lightningd/opening_control: routines to control openingd (move from peer_control.c)

We also fold opening_got_hsm_funding_sig() into the caller; it was
previously a callback before we decided to always use the HSM
synchronously.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-02-21 07:29:04 +10:30 committed by Christian Decker
parent d2265cd3d2
commit 4cf274b1c0
7 changed files with 909 additions and 922 deletions

View File

@ -61,6 +61,7 @@ LIGHTNINGD_SRC := \
lightningd/log.c \
lightningd/log_status.c \
lightningd/netaddress.c \
lightningd/opening_control.c \
lightningd/opt_time.c \
lightningd/options.c \
lightningd/pay.c \

View File

@ -0,0 +1,831 @@
#include <bitcoin/privkey.h>
#include <bitcoin/script.h>
#include <ccan/tal/str/str.h>
#include <common/channel_config.h>
#include <common/funding_tx.h>
#include <common/key_derive.h>
#include <common/wire_error.h>
#include <errno.h>
#include <gossipd/gen_gossip_wire.h>
#include <hsmd/gen_hsm_client_wire.h>
#include <lightningd/build_utxos.h>
#include <lightningd/chaintopology.h>
#include <lightningd/hsm_control.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/opening_control.h>
#include <lightningd/peer_control.h>
#include <lightningd/subd.h>
#include <openingd/gen_opening_wire.h>
#include <wire/wire_sync.h>
/* 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;
/* 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 {
struct command *cmd; /* Which also owns us. */
/* Peer we're trying to reach. */
struct pubkey peerid;
/* Details of how to make funding. */
const struct utxo **utxomap;
u64 change;
u32 change_keyindex;
u64 funding_satoshi, push_msat;
u8 channel_flags;
/* Channel. */
struct uncommitted_channel *uc;
};
/* 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,
u64 gossip_index,
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,
gossip_index,
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);
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->fc) {
u64 msatoshi_total, our_msatoshi;
msatoshi_total = uc->fc->funding_satoshi * 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 */
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;
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,
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 */
our_msatoshi,
remote_commit,
remote_commit_sig,
NULL, /* No HTLC sigs yet */
channel_info,
NULL, /* No remote_shutdown_scriptpubkey yet */
-1, false,
NULL, /* No commit sent yet */
uc->first_blocknum);
/* 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);
}
static void opening_funder_finished(struct subd *openingd, const u8 *resp,
const int *fds,
struct funding_channel *fc)
{
tal_t *tmpctx = tal_tmpctx(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;
u64 gossip_index;
u32 feerate;
u64 change_satoshi;
struct channel *channel;
struct json_result *response;
struct lightningd *ld = openingd->ld;
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, NULL,
&channel_info.their_config,
&remote_commit,
&remote_commit_sig,
&cs,
&gossip_index,
&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(ltmp, struct pubkey,
&channel_info.remote_per_commit));
/* Generate the funding tx. */
if (fc->change
&& !bip32_pubkey(ld->wallet->bip32_base,
&changekey, fc->change_keyindex))
fatal("Error deriving change key %u", fc->change_keyindex);
derive_basepoints(&fc->uc->seed, &local_fundingkey, NULL, NULL, NULL);
fundingtx = funding_tx(tmpctx, &funding_outnum,
fc->utxomap, fc->funding_satoshi,
&local_fundingkey,
&channel_info.remote_fundingkey,
fc->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->utxomap[i]->amount,
fc->utxomap[i]->is_p2sh ? "P2SH" : "SEGWIT",
type_to_string(ltmp, 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->funding_satoshi,
fc->change, fc->change_keyindex,
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->funding_satoshi,
fc->change, fc->change_keyindex,
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->funding_satoshi,
fc->push_msat,
fc->channel_flags,
&channel_info,
feerate);
/* 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->change, fc->change_keyindex,
&local_fundingkey,
&channel_info.remote_fundingkey,
fc->utxomap);
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, NULL, &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, &change_satoshi);
/* Send it out and watch for confirms. */
broadcast_tx(ld->topology, channel, fundingtx, funding_broadcast_failed);
channel_watch_funding(ld, channel);
/* Start normal channel daemon. */
peer_start_channeld(channel, &cs, gossip_index,
fds[0], fds[1], NULL, false);
wallet_confirm_utxos(ld->wallet, fc->utxomap);
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);
json_object_end(response);
command_success(fc->cmd, response);
subd_release_channel(openingd, fc->uc);
/* Frees fc too, and tmpctx */
tal_free(fc->uc);
return;
failed:
close(fds[0]);
close(fds[1]);
subd_release_channel(openingd, fc->uc);
/* 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;
u64 gossip_index;
secp256k1_ecdsa_signature remote_commit_sig;
struct bitcoin_tx *remote_commit;
const tal_t *tmpctx = tal_tmpctx(uc);
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, NULL,
&channel_info.their_config,
&remote_commit,
&remote_commit_sig,
&cs,
&gossip_index,
&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);
log_debug(channel->log, "Watching funding tx %s",
type_to_string(reply, struct bitcoin_txid,
&channel->funding_txid));
channel_watch_funding(ld, channel);
/* On to normal operation! */
peer_start_channeld(channel, &cs, gossip_index,
fds[0], fds[1], funding_signed, false);
subd_release_channel(openingd, uc);
tal_free(uc);
}
static void opening_channel_errmsg(struct uncommitted_channel *uc,
int peer_fd, int gossip_fd,
const struct crypto_state *cs,
u64 gossip_index,
const struct channel_id *channel_id,
const char *desc,
const u8 *err_for_them)
{
if (peer_fd == -1) {
log_info(uc->log, "%s", desc);
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, gossip_index,
peer_fd, gossip_fd,
err_for_them,
"%s ERROR %s", errsrc, desc);
}
tal_free(uc);
}
static void destroy_uncommitted_channel(struct uncommitted_channel *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->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(struct lightningd *ld,
const struct pubkey *peer_id,
const struct wireaddr *addr,
const struct crypto_state *cs,
u64 gossip_index,
const u8 *gfeatures, const u8 *lfeatures,
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(open_msg, channel_id,
"Multiple channels unsupported");
uc->openingd = new_channel_subd(ld, "lightning_openingd", uc, uc->log,
opening_wire_type_name, NULL,
opening_channel_errmsg,
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, gossip_index,
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, gossip_index, &uc->seed);
subd_send_msg(uc->openingd, take(msg));
/* BOLT #2:
*
* Given the variance in fees, and the fact that the transaction may
* be spent in the future, it's a good idea for the fee payer to keep
* a good margin, say 5x the expected fee requirement */
msg = towire_opening_fundee(uc, uc->minimum_depth,
get_feerate(ld->topology, FEERATE_SLOW),
get_feerate(ld->topology, FEERATE_IMMEDIATE)
* 5,
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,
u64 gossip_index,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd)
{
u8 *msg;
u32 max_to_self_delay, max_minimum_depth;
u64 min_effective_htlc_capacity_msat;
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,
opening_wire_type_name, NULL,
opening_channel_errmsg,
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,
gossip_index,
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, gossip_index, &fc->uc->seed);
subd_send_msg(fc->uc->openingd, take(msg));
msg = towire_opening_funder(fc, fc->funding_satoshi,
fc->push_msat,
get_feerate(ld->topology, FEERATE_NORMAL),
max_minimum_depth,
fc->change, fc->change_keyindex,
fc->channel_flags,
fc->utxomap,
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;
u64 gossip_index;
u8 *gfeatures, *lfeatures;
struct wireaddr addr;
struct channel *c;
struct uncommitted_channel *uc;
c = active_channel_by_id(ld, &fc->peerid, &uc);
if (!fromwire_gossipctl_release_peer_reply(fc, resp, NULL, &addr, &cs,
&gossip_index,
&gfeatures, &lfeatures)) {
if (!fromwire_gossipctl_release_peer_replyfail(resp, NULL)) {
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, gossip_index,
gfeatures, lfeatures,
fds[0], fds[1]);
}
static void json_fund_channel(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *peertok, *satoshitok;
struct funding_channel *fc = tal(cmd, struct funding_channel);
u8 *msg;
if (!json_get_params(cmd, buffer, params,
"id", &peertok,
"satoshi", &satoshitok,
NULL)) {
return;
}
fc->cmd = cmd;
if (!pubkey_from_hexstr(buffer + peertok->start,
peertok->end - peertok->start, &fc->peerid)) {
command_fail(cmd, "Could not parse id");
return;
}
if (!json_tok_u64(buffer, satoshitok, &fc->funding_satoshi)) {
command_fail(cmd, "Invalid satoshis");
return;
}
if (fc->funding_satoshi > MAX_FUNDING_SATOSHI) {
command_fail(cmd, "Funding satoshi must be <= %d",
MAX_FUNDING_SATOSHI);
return;
}
/* FIXME: Support push_msat? */
fc->push_msat = 0;
fc->channel_flags = OUR_CHANNEL_FLAGS;
/* Try to do this now, so we know if insufficient funds. */
/* FIXME: dustlimit */
fc->utxomap = build_utxos(fc, cmd->ld, fc->funding_satoshi,
get_feerate(cmd->ld->topology, FEERATE_NORMAL),
600, BITCOIN_SCRIPTPUBKEY_P2WSH_LEN,
&fc->change, &fc->change_keyindex);
if (!fc->utxomap) {
command_fail(cmd, "Cannot afford funding transaction");
return;
}
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} satoshis"
};
AUTODATA(json_command, &fund_channel_command);

View File

@ -0,0 +1,34 @@
#ifndef LIGHTNING_LIGHTNINGD_OPENING_CONTROL_H
#define LIGHTNING_LIGHTNINGD_OPENING_CONTROL_H
#include "config.h"
#include <ccan/short_types/short_types.h>
struct channel_id;
struct crypto_state;
struct json_result;
struct lightningd;
struct pubkey;
struct uncommitted_channel;
struct wireaddr;
void json_add_uncommitted_channel(struct json_result *response,
const struct uncommitted_channel *uc);
/* 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(struct lightningd *ld,
const struct pubkey *peer_id,
const struct wireaddr *addr,
const struct crypto_state *cs,
u64 gossip_index,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd,
const struct channel_id *channel_id,
const u8 *open_msg);
void kill_uncommitted_channel(struct uncommitted_channel *uc,
const char *why);
#endif /* LIGHTNING_LIGHTNINGD_OPENING_CONTROL_H */

View File

@ -15,7 +15,6 @@
#include <common/close_tx.h>
#include <common/dev_disconnect.h>
#include <common/features.h>
#include <common/funding_tx.h>
#include <common/initial_commit_tx.h>
#include <common/key_derive.h>
#include <common/status.h>
@ -35,11 +34,11 @@
#include <lightningd/jsonrpc.h>
#include <lightningd/log.h>
#include <lightningd/netaddress.h>
#include <lightningd/opening_control.h>
#include <lightningd/options.h>
#include <lightningd/peer_htlcs.h>
#include <onchaind/gen_onchain_wire.h>
#include <onchaind/onchain_wire.h>
#include <openingd/gen_opening_wire.h>
#include <unistd.h>
#include <wally_bip32.h>
#include <wire/gen_onion_wire.h>
@ -52,56 +51,6 @@ struct connect {
struct command *cmd;
};
/* 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;
/* 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 {
struct command *cmd; /* Which also owns us. */
/* Peer we're trying to reach. */
struct pubkey peerid;
/* Details of how to make funding. */
const struct utxo **utxomap;
u64 change;
u32 change_keyindex;
u64 funding_satoshi, push_msat;
u8 channel_flags;
/* Channel. */
struct uncommitted_channel *uc;
};
/* FIXME: Reorder */
static void copy_to_parent_log(const char *prefix,
enum log_level level,
@ -110,33 +59,11 @@ static void copy_to_parent_log(const char *prefix,
const char *str,
const u8 *io,
struct log *parent_log);
static void peer_offer_channel(struct lightningd *ld,
struct funding_channel *fc,
const struct wireaddr *addr,
const struct crypto_state *cs,
u64 gossip_index,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd);
static bool peer_start_channeld(struct channel *channel,
const struct crypto_state *cs,
u64 gossip_index,
int peer_fd, int gossip_fd,
const u8 *funding_signed,
bool reconnected);
static void peer_start_closingd(struct channel *channel,
struct crypto_state *cs,
u64 gossip_index,
int peer_fd, int gossip_fd,
bool reconnected);
static u8 *peer_accept_channel(struct lightningd *ld,
const struct pubkey *peer_id,
const struct wireaddr *addr,
const struct crypto_state *cs,
u64 gossip_index,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd,
const struct channel_id *channel_id,
const u8 *open_msg);
static void destroy_peer(struct peer *peer)
{
@ -288,80 +215,6 @@ static void connect_failed(struct lightningd *ld, const struct pubkey *id,
}
}
/* 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,
u64 gossip_index,
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,
gossip_index,
errorpkt);
subd_send_msg(ld->gossip, take(msg));
subd_send_fd(ld->gossip, peer_fd);
subd_send_fd(ld->gossip, gossip_fd);
}
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;
};
static void channel_errmsg(struct channel *channel,
int peer_fd, int gossip_fd,
const struct crypto_state *cs,
@ -466,11 +319,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg,
/* Opening now? Kill it */
if (uc) {
log_info(uc->log, "Peer reconnected, killing openingd");
/* Close openingd. */
subd_release_channel(uc->openingd, uc);
tal_free(uc);
kill_uncommitted_channel(uc, "Peer reconnected");
goto return_to_gossipd;
}
@ -854,26 +703,7 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg,
}
json_array_start(response, "channels");
if (p->uncommitted_channel) {
const struct uncommitted_channel *uc
= p->uncommitted_channel;
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->fc) {
u64 msatoshi_total, our_msatoshi;
msatoshi_total = uc->fc->funding_satoshi * 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);
}
json_add_uncommitted_channel(response, p->uncommitted_channel);
list_for_each(&p->channels, channel, list) {
json_object_start(response, NULL);
@ -1003,14 +833,6 @@ struct peer *peer_from_json(struct lightningd *ld,
return peer_by_id(ld, &peerid);
}
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);
}
static enum watch_result funding_announce_cb(struct channel *channel,
const struct bitcoin_tx *tx,
unsigned int depth,
@ -1606,48 +1428,14 @@ static enum watch_result funding_lockin_cb(struct channel *channel,
return DELETE_WATCH;
}
static void opening_got_hsm_funding_sig(struct channel *channel,
struct command *cmd,
const struct utxo **utxomap,
int peer_fd, int gossip_fd,
const u8 *resp,
const struct crypto_state *cs,
u64 gossip_index)
void channel_watch_funding(struct lightningd *ld, struct channel *channel)
{
struct bitcoin_tx *tx;
u8 *linear;
u64 change_satoshi;
struct json_result *response = new_json_result(cmd);
struct lightningd *ld = channel->peer->ld;
if (!fromwire_hsm_sign_funding_reply(cmd, resp, NULL, &tx))
fatal("HSM gave bad sign_funding_reply %s",
tal_hex(cmd, resp));
/* Send it out and watch for confirms. */
broadcast_tx(ld->topology, channel, tx, funding_broadcast_failed);
watch_tx(channel, ld->topology, channel, tx, funding_lockin_cb, NULL);
/* Extract the change output and add it to the DB */
wallet_extract_owned_outputs(ld->wallet, tx, &change_satoshi);
/* FIXME: Remove arg from cb? */
watch_txid(channel, ld->topology, channel,
&channel->funding_txid, funding_lockin_cb, NULL);
watch_txo(channel, ld->topology, channel,
&channel->funding_txid, channel->funding_outnum,
funding_spent, NULL);
json_object_start(response, NULL);
linear = linearize_tx(response, tx);
json_add_hex(response, "tx", linear, tal_len(linear));
json_add_txid(response, "txid", &channel->funding_txid);
json_object_end(response);
command_success(cmd, response);
/* Start normal channel daemon. */
peer_start_channeld(channel, cs, gossip_index,
peer_fd, gossip_fd, NULL, false);
wallet_confirm_utxos(ld->wallet, utxomap);
}
/* We were informed by channeld that it announced the channel and sent
@ -2084,12 +1872,12 @@ u32 feerate_max(struct lightningd *ld)
return get_feerate(ld->topology, FEERATE_IMMEDIATE) * 5;
}
static bool peer_start_channeld(struct channel *channel,
const struct crypto_state *cs,
u64 gossip_index,
int peer_fd, int gossip_fd,
const u8 *funding_signed,
bool reconnected)
bool peer_start_channeld(struct channel *channel,
const struct crypto_state *cs,
u64 gossip_index,
int peer_fd, int gossip_fd,
const u8 *funding_signed,
bool reconnected)
{
const tal_t *tmpctx = tal_tmpctx(channel);
u8 *msg, *initmsg;
@ -2213,630 +2001,6 @@ static bool peer_start_channeld(struct channel *channel,
return true;
}
/* Steals fields from uncommitted_channel */
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;
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,
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 */
our_msatoshi,
remote_commit,
remote_commit_sig,
NULL, /* No HTLC sigs yet */
channel_info,
NULL, /* No remote_shutdown_scriptpubkey yet */
-1, false,
NULL, /* No commit sent yet */
uc->first_blocknum);
/* Now we finally put it in the database. */
wallet_channel_insert(ld->wallet, channel);
return channel;
}
static void opening_funder_finished(struct subd *openingd, const u8 *resp,
const int *fds,
struct funding_channel *fc)
{
tal_t *tmpctx = tal_tmpctx(fc);
u8 *msg;
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;
u64 gossip_index;
u32 feerate;
struct channel *channel;
struct lightningd *ld = openingd->ld;
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, NULL,
&channel_info.their_config,
&remote_commit,
&remote_commit_sig,
&cs,
&gossip_index,
&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(ltmp, struct pubkey,
&channel_info.remote_per_commit));
/* Generate the funding tx. */
if (fc->change
&& !bip32_pubkey(ld->wallet->bip32_base,
&changekey, fc->change_keyindex))
fatal("Error deriving change key %u", fc->change_keyindex);
derive_basepoints(&fc->uc->seed, &local_fundingkey, NULL, NULL, NULL);
fundingtx = funding_tx(tmpctx, &funding_outnum,
fc->utxomap, fc->funding_satoshi,
&local_fundingkey,
&channel_info.remote_fundingkey,
fc->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->utxomap[i]->amount,
fc->utxomap[i]->is_p2sh ? "P2SH" : "SEGWIT",
type_to_string(ltmp, 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->funding_satoshi,
fc->change, fc->change_keyindex,
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->funding_satoshi,
fc->change, fc->change_keyindex,
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->funding_satoshi,
fc->push_msat,
fc->channel_flags,
&channel_info,
feerate);
/* 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->change, fc->change_keyindex,
&local_fundingkey,
&channel_info.remote_fundingkey,
fc->utxomap);
if (!wire_sync_write(ld->hsm_fd, take(msg)))
fatal("Could not write to HSM: %s", strerror(errno));
tal_free(tmpctx);
msg = hsm_sync_read(fc, ld);
opening_got_hsm_funding_sig(channel, fc->cmd, fc->utxomap,
fds[0], fds[1], msg, &cs, gossip_index);
subd_release_channel(openingd, fc->uc);
/* Frees fc too */
tal_free(fc->uc);
return;
failed:
close(fds[0]);
close(fds[1]);
subd_release_channel(openingd, fc->uc);
/* Frees fc too */
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;
u64 gossip_index;
secp256k1_ecdsa_signature remote_commit_sig;
struct bitcoin_tx *remote_commit;
const tal_t *tmpctx = tal_tmpctx(uc);
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, NULL,
&channel_info.their_config,
&remote_commit,
&remote_commit_sig,
&cs,
&gossip_index,
&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);
log_debug(channel->log, "Watching funding tx %s",
type_to_string(reply, struct bitcoin_txid,
&channel->funding_txid));
watch_txid(channel, ld->topology, channel, &channel->funding_txid,
funding_lockin_cb, NULL);
/* FIXME: Remove arg from cb? */
watch_txo(channel, ld->topology, channel, &channel->funding_txid,
channel->funding_outnum, funding_spent, NULL);
/* On to normal operation! */
peer_start_channeld(channel, &cs, gossip_index,
fds[0], fds[1], funding_signed, false);
subd_release_channel(openingd, uc);
tal_free(uc);
}
static void opening_channel_errmsg(struct uncommitted_channel *uc,
int peer_fd, int gossip_fd,
const struct crypto_state *cs,
u64 gossip_index,
const struct channel_id *channel_id,
const char *desc,
const u8 *err_for_them)
{
if (peer_fd == -1) {
log_info(uc->log, "%s", desc);
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, gossip_index,
peer_fd, gossip_fd,
err_for_them,
"%s ERROR %s", errsrc, desc);
}
tal_free(uc);
}
static void destroy_uncommitted_channel(struct uncommitted_channel *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->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;
}
/* Peer has spontaneously exited from gossip due to open msg. Return
* NULL if we took over, otherwise hand back to gossipd with this
* error.
*/
static u8 *peer_accept_channel(struct lightningd *ld,
const struct pubkey *peer_id,
const struct wireaddr *addr,
const struct crypto_state *cs,
u64 gossip_index,
const u8 *gfeatures, const u8 *lfeatures,
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(open_msg, channel_id,
"Multiple channels unsupported");
uc->openingd = new_channel_subd(ld, "lightning_openingd", uc, uc->log,
opening_wire_type_name, NULL,
opening_channel_errmsg,
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, gossip_index,
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, gossip_index, &uc->seed);
subd_send_msg(uc->openingd, take(msg));
/* BOLT #2:
*
* Given the variance in fees, and the fact that the transaction may
* be spent in the future, it's a good idea for the fee payer to keep
* a good margin, say 5x the expected fee requirement */
msg = towire_opening_fundee(uc, uc->minimum_depth,
get_feerate(ld->topology, FEERATE_SLOW),
get_feerate(ld->topology, FEERATE_IMMEDIATE)
* 5,
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,
u64 gossip_index,
const u8 *gfeatures, const u8 *lfeatures,
int peer_fd, int gossip_fd)
{
u8 *msg;
u32 max_to_self_delay, max_minimum_depth;
u64 min_effective_htlc_capacity_msat;
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,
opening_wire_type_name, NULL,
opening_channel_errmsg,
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,
gossip_index,
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, gossip_index, &fc->uc->seed);
subd_send_msg(fc->uc->openingd, take(msg));
msg = towire_opening_funder(fc, fc->funding_satoshi,
fc->push_msat,
get_feerate(ld->topology, FEERATE_NORMAL),
max_minimum_depth,
fc->change, fc->change_keyindex,
fc->channel_flags,
fc->utxomap,
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;
u64 gossip_index;
u8 *gfeatures, *lfeatures;
struct wireaddr addr;
struct channel *c;
struct uncommitted_channel *uc;
c = active_channel_by_id(ld, &fc->peerid, &uc);
if (!fromwire_gossipctl_release_peer_reply(fc, resp, NULL, &addr, &cs,
&gossip_index,
&gfeatures, &lfeatures)) {
if (!fromwire_gossipctl_release_peer_replyfail(resp, NULL)) {
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, gossip_index,
gfeatures, lfeatures,
fds[0], fds[1]);
}
static void json_fund_channel(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *peertok, *satoshitok;
struct funding_channel *fc = tal(cmd, struct funding_channel);
u8 *msg;
if (!json_get_params(cmd, buffer, params,
"id", &peertok,
"satoshi", &satoshitok,
NULL)) {
return;
}
fc->cmd = cmd;
if (!pubkey_from_hexstr(buffer + peertok->start,
peertok->end - peertok->start, &fc->peerid)) {
command_fail(cmd, "Could not parse id");
return;
}
if (!json_tok_u64(buffer, satoshitok, &fc->funding_satoshi)) {
command_fail(cmd, "Invalid satoshis");
return;
}
if (fc->funding_satoshi > MAX_FUNDING_SATOSHI) {
command_fail(cmd, "Funding satoshi must be <= %d",
MAX_FUNDING_SATOSHI);
return;
}
/* FIXME: Support push_msat? */
fc->push_msat = 0;
fc->channel_flags = OUR_CHANNEL_FLAGS;
/* Try to do this now, so we know if insufficient funds. */
/* FIXME: dustlimit */
fc->utxomap = build_utxos(fc, cmd->ld, fc->funding_satoshi,
get_feerate(cmd->ld->topology, FEERATE_NORMAL),
600, BITCOIN_SCRIPTPUBKEY_P2WSH_LEN,
&fc->change, &fc->change_keyindex);
if (!fc->utxomap) {
command_fail(cmd, "Cannot afford funding transaction");
return;
}
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} satoshis"
};
AUTODATA(json_command, &fund_channel_command);
static void json_close(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
@ -2861,14 +2025,8 @@ static void json_close(struct command *cmd,
struct uncommitted_channel *uc = peer->uncommitted_channel;
if (uc) {
/* Easy case: peer can simply be forgotten. */
log_info(uc->log, "close command called");
kill_uncommitted_channel(uc, "close command called");
/* Close openingd. */
subd_release_channel(uc->openingd, uc);
if (uc->fc)
command_fail(uc->fc->cmd,
"close command called");
tal_free(uc);
command_success(cmd, null_response(cmd));
return;
}
@ -2932,14 +2090,8 @@ static void activate_peer(struct peer *peer)
}
list_for_each(&peer->channels, channel, list) {
/* This may be unnecessary, but it's harmless. */
watch_txid(channel, ld->topology, channel,
&channel->funding_txid,
funding_lockin_cb, NULL);
watch_txo(channel, ld->topology, channel,
&channel->funding_txid, channel->funding_outnum,
funding_spent, NULL);
/* Watching lockin may be unnecessary, but it's harmless. */
channel_watch_funding(ld, channel);
}
}

View File

@ -106,4 +106,12 @@ void free_htlcs(struct lightningd *ld, const struct channel *channel);
u32 feerate_min(struct lightningd *ld);
u32 feerate_max(struct lightningd *ld);
bool peer_start_channeld(struct channel *channel,
const struct crypto_state *cs,
u64 gossip_index,
int peer_fd, int gossip_fd,
const u8 *funding_signed,
bool reconnected);
void channel_watch_funding(struct lightningd *ld, struct channel *channel);
#endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */

View File

@ -2448,7 +2448,7 @@ class LightningDTests(BaseLightningDTests):
l1.rpc.connect(l2.info['id'], 'localhost', l2.info['port'])
# We should get a message about reconnecting.
l2.daemon.wait_for_log('Peer reconnected, killing openingd')
l2.daemon.wait_for_log('Killing openingd: Peer reconnected')
# Should work fine.
l1.rpc.fundchannel(l2.info['id'], 20000)

View File

@ -47,13 +47,6 @@ void broadcast_tx(struct chain_topology *topo UNNEEDED,
int exitstatus UNNEEDED,
const char *err))
{ fprintf(stderr, "broadcast_tx called!\n"); abort(); }
/* Generated stub for build_utxos */
const struct utxo **build_utxos(const tal_t *ctx UNNEEDED,
struct lightningd *ld UNNEEDED, u64 satoshi_out UNNEEDED,
u32 feerate_per_kw UNNEEDED, u64 dust_limit UNNEEDED,
size_t outputscriptlen UNNEEDED,
u64 *change_satoshis UNNEEDED, u32 *change_keyindex UNNEEDED)
{ fprintf(stderr, "build_utxos called!\n"); abort(); }
/* Generated stub for channel_wire_type_name */
const char *channel_wire_type_name(int e UNNEEDED)
{ fprintf(stderr, "channel_wire_type_name called!\n"); abort(); }
@ -103,12 +96,6 @@ bool fromwire_closing_complete(const void *p UNNEEDED, size_t *plen UNNEEDED, u6
/* Generated stub for fromwire_closing_received_signature */
bool fromwire_closing_received_signature(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
{ fprintf(stderr, "fromwire_closing_received_signature called!\n"); abort(); }
/* Generated stub for fromwire_gossipctl_release_peer_reply */
bool fromwire_gossipctl_release_peer_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct wireaddr *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u64 *gossip_index UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED)
{ fprintf(stderr, "fromwire_gossipctl_release_peer_reply called!\n"); abort(); }
/* Generated stub for fromwire_gossipctl_release_peer_replyfail */
bool fromwire_gossipctl_release_peer_replyfail(const void *p UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "fromwire_gossipctl_release_peer_replyfail called!\n"); abort(); }
/* Generated stub for fromwire_gossip_getpeers_reply */
bool fromwire_gossip_getpeers_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct pubkey **id UNNEEDED, struct wireaddr **addr UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_getpeers_reply called!\n"); abort(); }
@ -124,9 +111,6 @@ bool fromwire_gossip_peer_connection_failed(const void *p UNNEEDED, size_t *plen
/* Generated stub for fromwire_hsm_client_hsmfd_reply */
bool fromwire_hsm_client_hsmfd_reply(const void *p UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "fromwire_hsm_client_hsmfd_reply called!\n"); abort(); }
/* Generated stub for fromwire_hsm_sign_funding_reply */
bool fromwire_hsm_sign_funding_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
{ fprintf(stderr, "fromwire_hsm_sign_funding_reply called!\n"); abort(); }
/* Generated stub for fromwire_onchain_add_utxo */
bool fromwire_onchain_add_utxo(const void *p UNNEEDED, size_t *plen UNNEEDED, struct bitcoin_txid *prev_out_tx UNNEEDED, u32 *prev_out_index UNNEEDED, struct pubkey *per_commit_point UNNEEDED, u64 *value UNNEEDED)
{ fprintf(stderr, "fromwire_onchain_add_utxo called!\n"); abort(); }
@ -148,26 +132,6 @@ bool fromwire_onchain_missing_htlc_output(const void *p UNNEEDED, size_t *plen U
/* Generated stub for fromwire_onchain_unwatch_tx */
bool fromwire_onchain_unwatch_tx(const void *p UNNEEDED, size_t *plen UNNEEDED, struct bitcoin_txid *txid UNNEEDED)
{ fprintf(stderr, "fromwire_onchain_unwatch_tx called!\n"); abort(); }
/* Generated stub for fromwire_opening_fundee_reply */
bool fromwire_opening_fundee_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct channel_config *their_config UNNEEDED, struct bitcoin_tx **first_commit UNNEEDED, secp256k1_ecdsa_signature *first_commit_sig UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u64 *gossip_index UNNEEDED, struct pubkey *revocation_basepoint UNNEEDED, struct pubkey *payment_basepoint UNNEEDED, struct pubkey *htlc_basepoint UNNEEDED, struct pubkey *delayed_payment_basepoint UNNEEDED, struct pubkey *their_per_commit_point UNNEEDED, struct pubkey *remote_fundingkey UNNEEDED, struct bitcoin_txid *funding_txid UNNEEDED, u16 *funding_txout UNNEEDED, u64 *funding_satoshis UNNEEDED, u64 *push_msat UNNEEDED, u8 *channel_flags UNNEEDED, u32 *feerate_per_kw UNNEEDED, u8 **funding_signed_msg UNNEEDED)
{ fprintf(stderr, "fromwire_opening_fundee_reply called!\n"); abort(); }
/* Generated stub for fromwire_opening_funder_reply */
bool fromwire_opening_funder_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct channel_config *their_config UNNEEDED, struct bitcoin_tx **first_commit UNNEEDED, secp256k1_ecdsa_signature *first_commit_sig UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u64 *gossip_index UNNEEDED, struct pubkey *revocation_basepoint UNNEEDED, struct pubkey *payment_basepoint UNNEEDED, struct pubkey *htlc_basepoint UNNEEDED, struct pubkey *delayed_payment_basepoint UNNEEDED, struct pubkey *their_per_commit_point UNNEEDED, u32 *minimum_depth UNNEEDED, struct pubkey *remote_fundingkey UNNEEDED, struct bitcoin_txid *funding_txid UNNEEDED, u32 *feerate_per_kw UNNEEDED)
{ fprintf(stderr, "fromwire_opening_funder_reply called!\n"); abort(); }
/* Generated stub for funding_tx */
struct bitcoin_tx *funding_tx(const tal_t *ctx UNNEEDED,
u16 *outnum UNNEEDED,
const struct utxo **utxomap UNNEEDED,
u64 funding_satoshis UNNEEDED,
const struct pubkey *local_fundingkey UNNEEDED,
const struct pubkey *remote_fundingkey UNNEEDED,
u64 change_satoshis UNNEEDED,
const struct pubkey *changekey UNNEEDED,
const struct ext_key *bip32_base UNNEEDED)
{ fprintf(stderr, "funding_tx called!\n"); abort(); }
/* Generated stub for get_block_height */
u32 get_block_height(const struct chain_topology *topo UNNEEDED)
{ fprintf(stderr, "get_block_height called!\n"); abort(); }
/* Generated stub for get_chainparams */
struct chainparams *get_chainparams(const struct lightningd *ld UNNEEDED)
{ fprintf(stderr, "get_chainparams called!\n"); abort(); }
@ -270,6 +234,10 @@ void json_add_txid(struct json_result *result UNNEEDED, const char *fieldname UN
void json_add_u64(struct json_result *result UNNEEDED, const char *fieldname UNNEEDED,
uint64_t value UNNEEDED)
{ fprintf(stderr, "json_add_u64 called!\n"); abort(); }
/* Generated stub for json_add_uncommitted_channel */
void json_add_uncommitted_channel(struct json_result *response UNNEEDED,
const struct uncommitted_channel *uc UNNEEDED)
{ fprintf(stderr, "json_add_uncommitted_channel called!\n"); abort(); }
/* Generated stub for json_array_end */
void json_array_end(struct json_result *ptr UNNEEDED)
{ fprintf(stderr, "json_array_end called!\n"); abort(); }
@ -305,10 +273,10 @@ bool json_tok_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
bool json_tok_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct short_channel_id *scid UNNEEDED)
{ fprintf(stderr, "json_tok_short_channel_id called!\n"); abort(); }
/* Generated stub for json_tok_u64 */
bool json_tok_u64(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
uint64_t *num UNNEEDED)
{ fprintf(stderr, "json_tok_u64 called!\n"); abort(); }
/* Generated stub for kill_uncommitted_channel */
void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED,
const char *why UNNEEDED)
{ fprintf(stderr, "kill_uncommitted_channel called!\n"); abort(); }
/* Generated stub for locate_tx */
struct txlocator *locate_tx(const void *ctx UNNEEDED, const struct chain_topology *topo UNNEEDED, const struct bitcoin_txid *txid UNNEEDED)
{ fprintf(stderr, "locate_tx called!\n"); abort(); }
@ -357,9 +325,17 @@ void onchain_fulfilled_htlc(struct channel *channel UNNEEDED,
/* Generated stub for onchain_wire_type_name */
const char *onchain_wire_type_name(int e UNNEEDED)
{ fprintf(stderr, "onchain_wire_type_name called!\n"); abort(); }
/* Generated stub for opening_wire_type_name */
const char *opening_wire_type_name(int e UNNEEDED)
{ fprintf(stderr, "opening_wire_type_name called!\n"); abort(); }
/* Generated stub for peer_accept_channel */
u8 *peer_accept_channel(struct lightningd *ld UNNEEDED,
const struct pubkey *peer_id UNNEEDED,
const struct wireaddr *addr UNNEEDED,
const struct crypto_state *cs UNNEEDED,
u64 gossip_index UNNEEDED,
const u8 *gfeatures UNNEEDED, const u8 *lfeatures UNNEEDED,
int peer_fd UNNEEDED, int gossip_fd UNNEEDED,
const struct channel_id *channel_id UNNEEDED,
const u8 *open_msg UNNEEDED)
{ fprintf(stderr, "peer_accept_channel called!\n"); abort(); }
/* Generated stub for peer_got_commitsig */
void peer_got_commitsig(struct channel *channel UNNEEDED, const u8 *msg UNNEEDED)
{ fprintf(stderr, "peer_got_commitsig called!\n"); abort(); }
@ -438,9 +414,6 @@ u8 *towire_gossipctl_peer_addrhint(const tal_t *ctx UNNEEDED, const struct pubke
/* Generated stub for towire_gossipctl_reach_peer */
u8 *towire_gossipctl_reach_peer(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED)
{ fprintf(stderr, "towire_gossipctl_reach_peer called!\n"); abort(); }
/* Generated stub for towire_gossipctl_release_peer */
u8 *towire_gossipctl_release_peer(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED)
{ fprintf(stderr, "towire_gossipctl_release_peer called!\n"); abort(); }
/* Generated stub for towire_gossip_disable_channel */
u8 *towire_gossip_disable_channel(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED, u8 direction UNNEEDED, bool active UNNEEDED)
{ fprintf(stderr, "towire_gossip_disable_channel called!\n"); abort(); }
@ -450,9 +423,6 @@ u8 *towire_gossip_getpeers_request(const tal_t *ctx UNNEEDED, const struct pubke
/* Generated stub for towire_hsm_client_hsmfd */
u8 *towire_hsm_client_hsmfd(const tal_t *ctx UNNEEDED, const struct pubkey *pubkey UNNEEDED, u64 capabilities UNNEEDED)
{ fprintf(stderr, "towire_hsm_client_hsmfd called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_funding */
u8 *towire_hsm_sign_funding(const tal_t *ctx UNNEEDED, u64 satoshi_out UNNEEDED, u64 change_out UNNEEDED, u32 change_keyindex UNNEEDED, const struct pubkey *our_pubkey UNNEEDED, const struct pubkey *their_pubkey UNNEEDED, const struct utxo **inputs UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_funding called!\n"); abort(); }
/* Generated stub for towire_onchain_depth */
u8 *towire_onchain_depth(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 depth UNNEEDED)
{ fprintf(stderr, "towire_onchain_depth called!\n"); abort(); }
@ -468,15 +438,6 @@ u8 *towire_onchain_known_preimage(const tal_t *ctx UNNEEDED, const struct preima
/* Generated stub for towire_onchain_spent */
u8 *towire_onchain_spent(const tal_t *ctx UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, u32 input_num UNNEEDED, u32 blockheight UNNEEDED)
{ fprintf(stderr, "towire_onchain_spent called!\n"); abort(); }
/* Generated stub for towire_opening_fundee */
u8 *towire_opening_fundee(const tal_t *ctx UNNEEDED, u32 minimum_depth UNNEEDED, u32 min_feerate UNNEEDED, u32 max_feerate UNNEEDED, const u8 *msg UNNEEDED)
{ fprintf(stderr, "towire_opening_fundee called!\n"); abort(); }
/* Generated stub for towire_opening_funder */
u8 *towire_opening_funder(const tal_t *ctx UNNEEDED, u64 funding_satoshis UNNEEDED, u64 push_msat UNNEEDED, u32 feerate_per_kw UNNEEDED, u32 max_minimum_depth UNNEEDED, u64 change_satoshis UNNEEDED, u32 change_keyindex UNNEEDED, u8 channel_flags UNNEEDED, const struct utxo **inputs UNNEEDED, const struct ext_key *bip32 UNNEEDED)
{ fprintf(stderr, "towire_opening_funder called!\n"); abort(); }
/* Generated stub for towire_opening_init */
u8 *towire_opening_init(const tal_t *ctx UNNEEDED, u32 network_index UNNEEDED, const struct channel_config *our_config UNNEEDED, u32 max_to_self_delay UNNEEDED, u64 min_effective_htlc_capacity_msat UNNEEDED, const struct crypto_state *crypto_state UNNEEDED, u64 gossip_index UNNEEDED, const struct privkey *seed UNNEEDED)
{ fprintf(stderr, "towire_opening_init called!\n"); abort(); }
/* Generated stub for txfilter_add_scriptpubkey */
void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, u8 *script UNNEEDED)
{ fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); }