#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Channel we're still opening. */ struct uncommitted_channel { /* peer->uncommitted_channel == this */ struct peer *peer; /* openingd which is running now */ struct subd *openingd; /* Reserved dbid for if we become a real struct channel */ u64 dbid; /* For logging */ struct log *log; /* Openingd can tell us stuff. */ const char *transient_billboard; /* If we offered channel, this contains information, otherwise NULL */ struct funding_channel *fc; /* Secret seed (FIXME: Move to hsm!) */ struct privkey seed; /* Blockheight at creation, scans for funding confirmations * will start here */ u64 first_blocknum; /* These are *not* filled in by new_uncommitted_channel: */ /* Minimum funding depth (if funder == REMOTE). */ u32 minimum_depth; /* Our channel config. */ struct channel_config our_config; }; struct funding_channel { /* In lightningd->fundchannels while waiting for gossipd reply. */ struct list_node list; struct command *cmd; /* Which also owns us. */ struct wallet_tx wtx; u64 push_msat; u8 channel_flags; /* Peer we're trying to reach. */ struct pubkey peerid; /* Channel. */ struct uncommitted_channel *uc; }; static struct funding_channel *find_funding_channel(struct lightningd *ld, const struct pubkey *id) { struct funding_channel *i; list_for_each(&ld->fundchannels, i, list) { if (pubkey_eq(&i->peerid, id)) return i; } return NULL; } static void remove_funding_channel_from_list(struct funding_channel *fc) { list_del_from(&fc->cmd->ld->fundchannels, &fc->list); } /* Opening failed: hand back to gossipd (sending errpkt if not NULL) */ static void uncommitted_channel_to_gossipd(struct lightningd *ld, struct uncommitted_channel *uc, const struct crypto_state *cs, int peer_fd, int gossip_fd, const u8 *errorpkt, const char *fmt, ...) { va_list ap; char *errstr; u8 *msg; va_start(ap, fmt); errstr = tal_vfmt(uc, fmt, ap); va_end(ap); log_unusual(uc->log, "Opening channel: %s", errstr); if (uc->fc) command_fail(uc->fc->cmd, "%s", errstr); /* Hand back to gossipd, (maybe) with an error packet to send. */ msg = towire_gossipctl_hand_back_peer(errstr, &uc->peer->id, cs, errorpkt); subd_send_msg(ld->gossip, take(msg)); subd_send_fd(ld->gossip, peer_fd); subd_send_fd(ld->gossip, gossip_fd); } void kill_uncommitted_channel(struct uncommitted_channel *uc, const char *why) { log_info(uc->log, "Killing openingd: %s", why); /* Close openingd. */ subd_release_channel(uc->openingd, uc); uc->openingd = NULL; if (uc->fc) command_fail(uc->fc->cmd, "%s", why); tal_free(uc); } void json_add_uncommitted_channel(struct json_result *response, const struct uncommitted_channel *uc) { if (!uc) return; json_object_start(response, NULL); json_add_string(response, "state", "OPENINGD"); json_add_string(response, "owner", "lightning_openingd"); json_add_string(response, "funder", uc->fc ? "LOCAL" : "REMOTE"); if (uc->transient_billboard) { json_array_start(response, "status"); json_add_string(response, NULL, uc->transient_billboard); json_array_end(response); } if (uc->fc) { u64 msatoshi_total, our_msatoshi; msatoshi_total = uc->fc->wtx.amount * 1000; our_msatoshi = msatoshi_total - uc->fc->push_msat; json_add_u64(response, "msatoshi_to_us", our_msatoshi); json_add_u64(response, "msatoshi_total", msatoshi_total); } json_object_end(response); } /* Steals fields from uncommitted_channel: returns NULL if can't generate a * key for this channel (shouldn't happen!). */ static struct channel * wallet_commit_channel(struct lightningd *ld, struct uncommitted_channel *uc, struct bitcoin_tx *remote_commit, secp256k1_ecdsa_signature *remote_commit_sig, const struct bitcoin_txid *funding_txid, u16 funding_outnum, u64 funding_satoshi, u64 push_msat, u8 channel_flags, struct channel_info *channel_info, u32 feerate) { struct channel *channel; u64 our_msatoshi; s64 final_key_idx; /* Get a key to use for closing outputs from this tx */ final_key_idx = wallet_get_newindex(ld); if (final_key_idx == -1) { log_broken(uc->log, "Can't get final key index"); return NULL; } if (uc->fc) our_msatoshi = funding_satoshi * 1000 - push_msat; else our_msatoshi = push_msat; /* Feerates begin identical. */ channel_info->feerate_per_kw[LOCAL] = channel_info->feerate_per_kw[REMOTE] = feerate; /* old_remote_per_commit not valid yet, copy valid one. */ channel_info->old_remote_per_commit = channel_info->remote_per_commit; channel = new_channel(uc->peer, uc->dbid, NULL, /* No shachain yet */ CHANNELD_AWAITING_LOCKIN, uc->fc ? LOCAL : REMOTE, uc->log, take(uc->transient_billboard), channel_flags, &uc->our_config, uc->minimum_depth, 1, 1, 0, funding_txid, funding_outnum, funding_satoshi, push_msat, false, /* !remote_funding_locked */ NULL, /* no scid yet */ /* The three arguments below are msatoshi_to_us, * msatoshi_to_us_min, and msatoshi_to_us_max. * Because, this is a newly-funded channel, * all three are same value. */ our_msatoshi, our_msatoshi, /* msatoshi_to_us_min */ our_msatoshi, /* msatoshi_to_us_max */ remote_commit, remote_commit_sig, NULL, /* No HTLC sigs yet */ channel_info, NULL, /* No remote_shutdown_scriptpubkey yet */ final_key_idx, false, NULL, /* No commit sent yet */ uc->first_blocknum, feerate, feerate, /* We are connected */ true); /* Now we finally put it in the database. */ wallet_channel_insert(ld->wallet, channel); return channel; } static void funding_broadcast_failed(struct channel *channel, int exitstatus, const char *err) { channel_internal_error(channel, "Funding broadcast exited with %i: %s", exitstatus, err); } void tell_gossipd_peer_is_important(struct lightningd *ld, const struct channel *channel) { u8 *msg; /* Tell gossipd we need to keep connection to this peer */ msg = towire_gossipctl_peer_important(NULL, &channel->peer->id, true); subd_send_msg(ld->gossip, take(msg)); } static void opening_funder_finished(struct subd *openingd, const u8 *resp, const int *fds, struct funding_channel *fc) { u8 *msg, *linear; struct channel_info channel_info; struct bitcoin_tx *fundingtx; struct bitcoin_txid funding_txid, expected_txid; struct pubkey changekey; struct pubkey local_fundingkey; struct crypto_state cs; secp256k1_ecdsa_signature remote_commit_sig; struct bitcoin_tx *remote_commit; u16 funding_outnum; u32 feerate; u64 change_satoshi; struct channel *channel; struct json_result *response; struct lightningd *ld = openingd->ld; struct channel_id cid; assert(tal_count(fds) == 2); /* This is a new channel_info.their_config so set its ID to 0 */ channel_info.their_config.id = 0; if (!fromwire_opening_funder_reply(resp, resp, &channel_info.their_config, &remote_commit, &remote_commit_sig, &cs, &channel_info.theirbase.revocation, &channel_info.theirbase.payment, &channel_info.theirbase.htlc, &channel_info.theirbase.delayed_payment, &channel_info.remote_per_commit, &fc->uc->minimum_depth, &channel_info.remote_fundingkey, &expected_txid, &feerate)) { log_broken(fc->uc->log, "bad OPENING_FUNDER_REPLY %s", tal_hex(resp, resp)); command_fail(fc->cmd, "bad OPENING_FUNDER_REPLY %s", tal_hex(fc->cmd, resp)); goto failed; } log_debug(ld->log, "%s", type_to_string(tmpctx, struct pubkey, &channel_info.remote_per_commit)); /* Generate the funding tx. */ if (fc->wtx.change && !bip32_pubkey(ld->wallet->bip32_base, &changekey, fc->wtx.change_key_index)) fatal("Error deriving change key %u", fc->wtx.change_key_index); derive_basepoints(&fc->uc->seed, &local_fundingkey, NULL, NULL, NULL); fundingtx = funding_tx(tmpctx, &funding_outnum, fc->wtx.utxos, fc->wtx.amount, &local_fundingkey, &channel_info.remote_fundingkey, fc->wtx.change, &changekey, ld->wallet->bip32_base); log_debug(fc->uc->log, "Funding tx has %zi inputs, %zu outputs:", tal_count(fundingtx->input), tal_count(fundingtx->output)); for (size_t i = 0; i < tal_count(fundingtx->input); i++) { log_debug(fc->uc->log, "%zi: %"PRIu64" satoshi (%s) %s\n", i, fc->wtx.utxos[i]->amount, fc->wtx.utxos[i]->is_p2sh ? "P2SH" : "SEGWIT", type_to_string(tmpctx, struct bitcoin_txid, &fundingtx->input[i].txid)); } bitcoin_txid(fundingtx, &funding_txid); if (!structeq(&funding_txid, &expected_txid)) { log_broken(fc->uc->log, "Funding txid mismatch:" " satoshi %"PRIu64" change %"PRIu64 " changeidx %u" " localkey %s remotekey %s", fc->wtx.amount, fc->wtx.change, fc->wtx.change_key_index, type_to_string(fc, struct pubkey, &local_fundingkey), type_to_string(fc, struct pubkey, &channel_info.remote_fundingkey)); command_fail(fc->cmd, "Funding txid mismatch:" " satoshi %"PRIu64" change %"PRIu64 " changeidx %u" " localkey %s remotekey %s", fc->wtx.amount, fc->wtx.change, fc->wtx.change_key_index, type_to_string(fc, struct pubkey, &local_fundingkey), type_to_string(fc, struct pubkey, &channel_info.remote_fundingkey)); goto failed; } /* Steals fields from uc */ channel = wallet_commit_channel(ld, fc->uc, remote_commit, &remote_commit_sig, &funding_txid, funding_outnum, fc->wtx.amount, fc->push_msat, fc->channel_flags, &channel_info, feerate); if (!channel) { command_fail(fc->cmd, "Key generation failure"); goto failed; } /* Get HSM to sign the funding tx. */ log_debug(channel->log, "Getting HSM to sign funding tx"); msg = towire_hsm_sign_funding(tmpctx, channel->funding_satoshi, fc->wtx.change, fc->wtx.change_key_index, &local_fundingkey, &channel_info.remote_fundingkey, fc->wtx.utxos); if (!wire_sync_write(ld->hsm_fd, take(msg))) fatal("Could not write to HSM: %s", strerror(errno)); msg = hsm_sync_read(fc, ld); if (!fromwire_hsm_sign_funding_reply(tmpctx, msg, &fundingtx)) fatal("HSM gave bad sign_funding_reply %s", tal_hex(msg, resp)); /* Extract the change output and add it to the DB */ wallet_extract_owned_outputs(ld->wallet, fundingtx, NULL, &change_satoshi); /* Make sure we recognize our change output by its scriptpubkey in * future. This assumes that we have only two outputs, may not be true * if we add support for multifundchannel */ if (tal_count(fundingtx->output) == 2) txfilter_add_scriptpubkey(ld->owned_txfilter, fundingtx->output[!funding_outnum].script); /* Send it out and watch for confirms. */ broadcast_tx(ld->topology, channel, fundingtx, funding_broadcast_failed); channel_watch_funding(ld, channel); tell_gossipd_peer_is_important(ld, channel); /* Start normal channel daemon. */ peer_start_channeld(channel, &cs, fds[0], fds[1], NULL, false); wallet_confirm_utxos(ld->wallet, fc->wtx.utxos); response = new_json_result(fc->cmd); json_object_start(response, NULL); linear = linearize_tx(response, fundingtx); json_add_hex(response, "tx", linear, tal_len(linear)); json_add_txid(response, "txid", &channel->funding_txid); derive_channel_id(&cid, &channel->funding_txid, funding_outnum); json_add_string(response, "channel_id", type_to_string(tmpctx, struct channel_id, &cid)); json_object_end(response); command_success(fc->cmd, response); subd_release_channel(openingd, fc->uc); fc->uc->openingd = NULL; /* Frees fc too, and tmpctx */ tal_free(fc->uc); return; failed: close(fds[0]); close(fds[1]); subd_release_channel(openingd, fc->uc); fc->uc->openingd = NULL; /* Frees fc too, and tmpctx */ tal_free(fc->uc); } static void opening_fundee_finished(struct subd *openingd, const u8 *reply, const int *fds, struct uncommitted_channel *uc) { u8 *funding_signed; struct channel_info channel_info; struct crypto_state cs; secp256k1_ecdsa_signature remote_commit_sig; struct bitcoin_tx *remote_commit; struct lightningd *ld = openingd->ld; struct bitcoin_txid funding_txid; u16 funding_outnum; u64 funding_satoshi, push_msat; u32 feerate; u8 channel_flags; struct channel *channel; log_debug(uc->log, "Got opening_fundee_finish_response"); assert(tal_count(fds) == 2); /* This is a new channel_info.their_config, set its ID to 0 */ channel_info.their_config.id = 0; if (!fromwire_opening_fundee_reply(tmpctx, reply, &channel_info.their_config, &remote_commit, &remote_commit_sig, &cs, &channel_info.theirbase.revocation, &channel_info.theirbase.payment, &channel_info.theirbase.htlc, &channel_info.theirbase.delayed_payment, &channel_info.remote_per_commit, &channel_info.remote_fundingkey, &funding_txid, &funding_outnum, &funding_satoshi, &push_msat, &channel_flags, &feerate, &funding_signed)) { log_broken(uc->log, "bad OPENING_FUNDEE_REPLY %s", tal_hex(reply, reply)); tal_free(uc); return; } /* Consumes uc */ channel = wallet_commit_channel(ld, uc, remote_commit, &remote_commit_sig, &funding_txid, funding_outnum, funding_satoshi, push_msat, channel_flags, &channel_info, feerate); if (!channel) { tal_free(uc); return; } log_debug(channel->log, "Watching funding tx %s", type_to_string(reply, struct bitcoin_txid, &channel->funding_txid)); channel_watch_funding(ld, channel); tell_gossipd_peer_is_important(ld, channel); /* On to normal operation! */ peer_start_channeld(channel, &cs, fds[0], fds[1], funding_signed, false); subd_release_channel(openingd, uc); uc->openingd = NULL; tal_free(uc); } static void opening_channel_errmsg(struct uncommitted_channel *uc, int peer_fd, int gossip_fd, const struct crypto_state *cs, const struct channel_id *channel_id UNUSED, const char *desc, const u8 *err_for_them) { if (peer_fd == -1) { u8 *msg = towire_gossipctl_peer_disconnected(tmpctx, &uc->peer->id); log_info(uc->log, "%s", desc); subd_send_msg(uc->peer->ld->gossip, msg); if (uc->fc) command_fail(uc->fc->cmd, "%s", desc); } else { /* An error occurred (presumably negotiation fail). */ const char *errsrc = err_for_them ? "sent" : "received"; uncommitted_channel_to_gossipd(uc->peer->ld, uc, cs, peer_fd, gossip_fd, err_for_them, "%s ERROR %s", errsrc, desc); } tal_free(uc); } /* There's nothing permanent in an unconfirmed transaction */ static void opening_channel_set_billboard(struct uncommitted_channel *uc, bool perm UNUSED, const char *happenings TAKES) { uc->transient_billboard = tal_free(uc->transient_billboard); if (happenings) uc->transient_billboard = tal_strdup(uc, happenings); } static void destroy_uncommitted_channel(struct uncommitted_channel *uc) { if (uc->openingd) { struct subd *openingd = uc->openingd; uc->openingd = NULL; subd_release_channel(openingd, uc); } uc->peer->uncommitted_channel = NULL; /* Last one out frees */ if (list_empty(&uc->peer->channels)) delete_peer(uc->peer); } /* Returns NULL if there's already an opening or active channel for this peer */ static struct uncommitted_channel * new_uncommitted_channel(struct lightningd *ld, struct funding_channel *fc, const struct pubkey *peer_id, const struct wireaddr *addr) { struct uncommitted_channel *uc = tal(ld, struct uncommitted_channel); char *idname; /* We make a new peer if necessary. */ uc->peer = peer_by_id(ld, peer_id); if (!uc->peer) uc->peer = new_peer(ld, 0, peer_id, addr); if (uc->peer->uncommitted_channel) return tal_free(uc); if (peer_active_channel(uc->peer)) return tal_free(uc); uc->transient_billboard = NULL; uc->dbid = wallet_get_channel_dbid(ld->wallet); idname = type_to_string(uc, struct pubkey, &uc->peer->id); uc->log = new_log(uc, uc->peer->log_book, "%s chan #%"PRIu64":", idname, uc->dbid); tal_free(idname); uc->fc = fc; uc->first_blocknum = get_block_height(ld->topology); uc->our_config.id = 0; derive_channel_seed(ld, &uc->seed, &uc->peer->id, uc->dbid); uc->peer->uncommitted_channel = uc; tal_add_destructor(uc, destroy_uncommitted_channel); return uc; } static void channel_config(struct lightningd *ld, struct channel_config *ours, u32 *max_to_self_delay, u32 *max_minimum_depth, u64 *min_effective_htlc_capacity_msat) { /* FIXME: depend on feerate. */ *max_to_self_delay = ld->config.locktime_max; *max_minimum_depth = ld->config.anchor_confirms_max; /* This is 1c at $1000/BTC */ *min_effective_htlc_capacity_msat = 1000000; /* BOLT #2: * * The sender SHOULD set `dust_limit_satoshis` to a sufficient * value to allow commitment transactions to propagate through * the Bitcoin network. */ ours->dust_limit_satoshis = 546; ours->max_htlc_value_in_flight_msat = UINT64_MAX; /* Don't care */ ours->htlc_minimum_msat = 0; /* BOLT #2: * * The sender SHOULD set `to_self_delay` sufficient to ensure * the sender can irreversibly spend a commitment transaction * output in case of misbehavior by the receiver. */ ours->to_self_delay = ld->config.locktime_blocks; /* BOLT #2: * * It MUST fail the channel if `max_accepted_htlcs` is greater than * 483. */ ours->max_accepted_htlcs = 483; /* This is filled in by lightning_openingd, for consistency. */ ours->channel_reserve_satoshis = 0; }; /* Peer has spontaneously exited from gossip due to open msg. Return * NULL if we took over, otherwise hand back to gossipd with this * error. */ u8 *peer_accept_channel(const tal_t *ctx, struct lightningd *ld, const struct pubkey *peer_id, const struct wireaddr *addr, const struct crypto_state *cs, const u8 *gfeatures UNUSED, const u8 *lfeatures UNUSED, int peer_fd, int gossip_fd, const struct channel_id *channel_id, const u8 *open_msg) { u32 max_to_self_delay, max_minimum_depth; u64 min_effective_htlc_capacity_msat; u8 *msg; struct uncommitted_channel *uc; assert(fromwire_peektype(open_msg) == WIRE_OPEN_CHANNEL); /* Fails if there's already one */ uc = new_uncommitted_channel(ld, NULL, peer_id, addr); if (!uc) return towire_errorfmt(ctx, channel_id, "Multiple channels unsupported"); uc->openingd = new_channel_subd(ld, "lightning_openingd", uc, uc->log, true, opening_wire_type_name, NULL, opening_channel_errmsg, opening_channel_set_billboard, take(&peer_fd), take(&gossip_fd), NULL); if (!uc->openingd) { u8 *errpkt; char *errmsg; errmsg = tal_fmt(uc, "INTERNAL ERROR:" " Failed to subdaemon opening: %s", strerror(errno)); errpkt = towire_errorfmt(uc, channel_id, "%s", errmsg); uncommitted_channel_to_gossipd(ld, uc, cs, peer_fd, gossip_fd, errpkt, "%s", errmsg); tal_free(uc); return NULL; } /* BOLT #2: * * The sender SHOULD set `minimum_depth` to a number of blocks it * considers reasonable to avoid double-spending of the funding * transaction. */ uc->minimum_depth = ld->config.anchor_confirms; channel_config(ld, &uc->our_config, &max_to_self_delay, &max_minimum_depth, &min_effective_htlc_capacity_msat); msg = towire_opening_init(uc, get_chainparams(ld)->index, &uc->our_config, max_to_self_delay, min_effective_htlc_capacity_msat, cs, &uc->seed); subd_send_msg(uc->openingd, take(msg)); msg = towire_opening_fundee(uc, uc->minimum_depth, feerate_min(ld), feerate_max(ld), open_msg); subd_req(uc, uc->openingd, take(msg), -1, 2, opening_fundee_finished, uc); return NULL; } static void peer_offer_channel(struct lightningd *ld, struct funding_channel *fc, const struct wireaddr *addr, const struct crypto_state *cs, const u8 *gfeatures UNUSED, const u8 *lfeatures UNUSED, int peer_fd, int gossip_fd) { u8 *msg; u32 max_to_self_delay, max_minimum_depth; u64 min_effective_htlc_capacity_msat; /* Remove from list, it's not pending any more. */ list_del_from(&ld->fundchannels, &fc->list); tal_del_destructor(fc, remove_funding_channel_from_list); fc->uc = new_uncommitted_channel(ld, fc, &fc->peerid, addr); /* We asked to release this peer, but another raced in? Corner case, * close this is easiest. */ if (!fc->uc) { command_fail(fc->cmd, "Peer already active"); close(peer_fd); close(gossip_fd); return; } /* Channel now owns fc; if it dies, we free fc. */ tal_steal(fc->uc, fc); fc->uc->openingd = new_channel_subd(ld, "lightning_openingd", fc->uc, fc->uc->log, true, opening_wire_type_name, NULL, opening_channel_errmsg, opening_channel_set_billboard, take(&peer_fd), take(&gossip_fd), NULL); if (!fc->uc->openingd) { /* We don't send them an error packet: for them, nothing * happened! */ uncommitted_channel_to_gossipd(ld, fc->uc, NULL, peer_fd, gossip_fd, NULL, "Failed to launch openingd: %s", strerror(errno)); tal_free(fc->uc); return; } channel_config(ld, &fc->uc->our_config, &max_to_self_delay, &max_minimum_depth, &min_effective_htlc_capacity_msat); msg = towire_opening_init(fc, get_chainparams(ld)->index, &fc->uc->our_config, max_to_self_delay, min_effective_htlc_capacity_msat, cs, &fc->uc->seed); subd_send_msg(fc->uc->openingd, take(msg)); msg = towire_opening_funder(fc, fc->wtx.amount, fc->push_msat, get_feerate(ld->topology, FEERATE_NORMAL), max_minimum_depth, fc->wtx.change, fc->wtx.change_key_index, fc->channel_flags, fc->wtx.utxos, ld->wallet->bip32_base); subd_req(fc, fc->uc->openingd, take(msg), -1, 2, opening_funder_finished, fc); } /* Peer has been released from gossip. Start opening. */ static void gossip_peer_released(struct subd *gossip, const u8 *resp, const int *fds, struct funding_channel *fc) { struct lightningd *ld = gossip->ld; struct crypto_state cs; u8 *gfeatures, *lfeatures; struct wireaddr addr; struct channel *c; struct uncommitted_channel *uc; /* handle_opening_channel might have already taken care of this. */ if (fc->uc) return; c = active_channel_by_id(ld, &fc->peerid, &uc); if (!fromwire_gossipctl_release_peer_reply(fc, resp, &addr, &cs, &gfeatures, &lfeatures)) { if (!fromwire_gossipctl_release_peer_replyfail(resp)) { fatal("Gossip daemon gave invalid reply %s", tal_hex(gossip, resp)); } if (uc) command_fail(fc->cmd, "Peer already OPENING"); else if (c) command_fail(fc->cmd, "Peer already %s", channel_state_name(c)); else command_fail(fc->cmd, "Peer not connected"); return; } assert(tal_count(fds) == 2); /* Gossipd should guarantee peer is unique: we would have killed any * old connection when it was told us peer reconnected. */ assert(!c); assert(!uc); /* OK, offer peer a channel. */ peer_offer_channel(ld, fc, &addr, &cs, gfeatures, lfeatures, fds[0], fds[1]); } /* We can race: we're trying to get gossipd to release peer just as it * reconnects. If that's happened, treat it as if it were * released. */ bool handle_opening_channel(struct lightningd *ld, const struct pubkey *id, const struct wireaddr *addr, const struct crypto_state *cs, const u8 *gfeatures, const u8 *lfeatures, int peer_fd, int gossip_fd) { struct funding_channel *fc = find_funding_channel(ld, id); if (!fc) return false; peer_offer_channel(ld, fc, addr, cs, gfeatures, lfeatures, peer_fd, gossip_fd); return true; } /** * json_fund_channel - Entrypoint for funding a channel */ static void json_fund_channel(struct command *cmd, const char *buffer, const jsmntok_t *params) { jsmntok_t *desttok, *sattok; struct funding_channel * fc = tal(cmd, struct funding_channel); u32 feerate_per_kw = get_feerate(cmd->ld->topology, FEERATE_NORMAL); u8 *msg; fc->cmd = cmd; fc->uc = NULL; wtx_init(cmd, &fc->wtx); if (!json_get_params(fc->cmd, buffer, params, "id", &desttok, "satoshi", &sattok, NULL)) return; if (!json_tok_wtx(&fc->wtx, buffer, sattok)) return; if (!pubkey_from_hexstr(buffer + desttok->start, desttok->end - desttok->start, &fc->peerid)) { command_fail(cmd, "Could not parse id"); return; } /* FIXME: Support push_msat? */ fc->push_msat = 0; fc->channel_flags = OUR_CHANNEL_FLAGS; if (!wtx_select_utxos(&fc->wtx, feerate_per_kw, BITCOIN_SCRIPTPUBKEY_P2WSH_LEN)) return; if (fc->wtx.amount > MAX_FUNDING_SATOSHI) { command_fail(cmd, "Funding satoshi must be <= %d", MAX_FUNDING_SATOSHI); return; } list_add(&cmd->ld->fundchannels, &fc->list); tal_add_destructor(fc, remove_funding_channel_from_list); msg = towire_gossipctl_release_peer(cmd, &fc->peerid); subd_req(fc, cmd->ld->gossip, msg, -1, 2, gossip_peer_released, fc); command_still_pending(cmd); } static const struct json_command fund_channel_command = { "fundchannel", json_fund_channel, "Fund channel with {id} using {satoshi} (or 'all') satoshis" }; AUTODATA(json_command, &fund_channel_command);