diff --git a/CHANGELOG.md b/CHANGELOG.md index 23d857406..5c1e50da3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - JSON API: `newaddr` outputs `bech32` or `p2sh-segwit`, or both with new `all` parameter (#2390) +- JSON API: `listpeers` status now shows how many confirmations until channel is open (#2405) ### Changed diff --git a/channeld/channel_wire.csv b/channeld/channel_wire.csv index 82c55d187..47421f190 100644 --- a/channeld/channel_wire.csv +++ b/channeld/channel_wire.csv @@ -8,6 +8,7 @@ channel_init,,chain_hash,struct bitcoin_blkid channel_init,,funding_txid,struct bitcoin_txid channel_init,,funding_txout,u16 channel_init,,funding_satoshi,struct amount_sat +channel_init,,minimum_depth,u32 channel_init,,our_config,struct channel_config channel_init,,their_config,struct channel_config # FIXME: Fix generate-wire.py to allow NUM_SIDES*u32 here. @@ -62,10 +63,10 @@ channel_init,,last_remote_secret,struct secret channel_init,,lflen,u16 channel_init,,localfeatures,lflen*u8 -# master->channeld funding hit new depth >= lock depth -channel_funding_locked,1002 -channel_funding_locked,,short_channel_id,struct short_channel_id -channel_funding_locked,,depth,u32 +# master->channeld funding hit new depth(funding locked if >= lock depth) +channel_funding_depth,1002 +channel_funding_depth,,short_channel_id,?struct short_channel_id +channel_funding_depth,,depth,u32 # Tell channel to offer this htlc channel_offer_htlc,1004 diff --git a/channeld/channeld.c b/channeld/channeld.c index 51f13a5c4..5dbef920d 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -153,6 +153,9 @@ struct peer { /* Make sure peer is live. */ struct timeabs last_recv; + + /* Additional confirmations need for local lockin. */ + u32 depth_togo; }; static u8 *create_channel_announcement(const tal_t *ctx, struct peer *peer); @@ -165,8 +168,9 @@ static void billboard_update(const struct peer *peer) if (peer->funding_locked[LOCAL] && peer->funding_locked[REMOTE]) funding_status = "Funding transaction locked."; else if (!peer->funding_locked[LOCAL] && !peer->funding_locked[REMOTE]) - /* FIXME: Say how many blocks to go! */ - funding_status = "Funding needs more confirmations."; + funding_status = tal_fmt(tmpctx, + "Funding needs %d confirmations to reach lockin.", + peer->depth_togo); else if (peer->funding_locked[LOCAL] && !peer->funding_locked[REMOTE]) funding_status = "We've confirmed funding, they haven't yet."; else if (!peer->funding_locked[LOCAL] && peer->funding_locked[REMOTE]) @@ -2386,37 +2390,53 @@ static void peer_reconnect(struct peer *peer, } } -/* Funding has locked in, and reached depth. */ -static void handle_funding_locked(struct peer *peer, const u8 *msg) +/* ignores the funding_depth unless depth >= minimum_depth + * (except to update billboard, and set peer->depth_togo). */ +static void handle_funding_depth(struct peer *peer, const u8 *msg) { - unsigned int depth; + u32 depth; + struct short_channel_id *scid; - if (!fromwire_channel_funding_locked(msg, - &peer->short_channel_ids[LOCAL], - &depth)) - master_badmsg(WIRE_CHANNEL_FUNDING_LOCKED, msg); + if (!fromwire_channel_funding_depth(tmpctx, + msg, + &scid, + &depth)) + master_badmsg(WIRE_CHANNEL_FUNDING_DEPTH, msg); /* Too late, we're shutting down! */ if (peer->shutdown_sent[LOCAL]) return; - if (!peer->funding_locked[LOCAL]) { - status_trace("funding_locked: sending commit index %"PRIu64": %s", - peer->next_index[LOCAL], - type_to_string(tmpctx, struct pubkey, - &peer->next_local_per_commit)); - msg = towire_funding_locked(NULL, - &peer->channel_id, - &peer->next_local_per_commit); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); - peer->funding_locked[LOCAL] = true; + if (depth < peer->channel->minimum_depth) { + peer->depth_togo = peer->channel->minimum_depth - depth; + + } else { + peer->depth_togo = 0; + + assert(scid); + peer->short_channel_ids[LOCAL] = *scid; + + if (!peer->funding_locked[LOCAL]) { + + status_trace("funding_locked: sending commit index %"PRIu64": %s", + peer->next_index[LOCAL], + type_to_string(tmpctx, struct pubkey, + &peer->next_local_per_commit)); + + msg = towire_funding_locked(NULL, + &peer->channel_id, + &peer->next_local_per_commit); + sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + + peer->funding_locked[LOCAL] = true; + } + + peer->announce_depth_reached = (depth >= ANNOUNCE_MIN_DEPTH); + + /* Send temporary or final announcements */ + channel_announcement_negotiate(peer); } - peer->announce_depth_reached = (depth >= ANNOUNCE_MIN_DEPTH); - - /* Send temporary or final announcements */ - channel_announcement_negotiate(peer); - billboard_update(peer); } @@ -2654,8 +2674,8 @@ static void req_in(struct peer *peer, const u8 *msg) enum channel_wire_type t = fromwire_peektype(msg); switch (t) { - case WIRE_CHANNEL_FUNDING_LOCKED: - handle_funding_locked(peer, msg); + case WIRE_CHANNEL_FUNDING_DEPTH: + handle_funding_depth(peer, msg); return; case WIRE_CHANNEL_OFFER_HTLC: handle_offer_htlc(peer, msg); @@ -2744,6 +2764,7 @@ static void init_channel(struct peer *peer) u8 *funding_signed; const u8 *msg; u32 feerate_per_kw[NUM_SIDES]; + u32 minimum_depth; struct secret last_remote_per_commit_secret; assert(!(fcntl(MASTER_FD, F_GETFL) & O_NONBLOCK)); @@ -2755,6 +2776,7 @@ static void init_channel(struct peer *peer) &peer->chain_hash, &funding_txid, &funding_txout, &funding, + &minimum_depth, &conf[LOCAL], &conf[REMOTE], feerate_per_kw, &peer->feerate_min, &peer->feerate_max, @@ -2797,8 +2819,9 @@ static void init_channel(struct peer *peer) &funding_signed, &peer->announce_depth_reached, &last_remote_per_commit_secret, - &peer->localfeatures)) - master_badmsg(WIRE_CHANNEL_INIT, msg); + &peer->localfeatures)) { + master_badmsg(WIRE_CHANNEL_INIT, msg); + } status_trace("init %s: remote_per_commit = %s, old_remote_per_commit = %s" " next_idx_local = %"PRIu64 @@ -2828,7 +2851,9 @@ static void init_channel(struct peer *peer) peer->channel = new_full_channel(peer, &peer->chain_hash, - &funding_txid, funding_txout, + &funding_txid, + funding_txout, + minimum_depth, funding, local_msat, feerate_per_kw, @@ -2865,6 +2890,9 @@ static void init_channel(struct peer *peer) if (peer->channel->funder == LOCAL) peer->desired_feerate = feerate_per_kw[REMOTE]; + /* from now we need keep watch over WIRE_CHANNEL_FUNDING_DEPTH */ + peer->depth_togo = minimum_depth; + /* OK, now we can process peer messages. */ if (reconnected) peer_reconnect(peer, &last_remote_per_commit_secret); diff --git a/channeld/full_channel.c b/channeld/full_channel.c index da173c296..31f4352ce 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -26,6 +26,7 @@ struct channel *new_full_channel(const tal_t *ctx, const struct bitcoin_blkid *chain_hash, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, + u32 minimum_depth, struct amount_sat funding, struct amount_msat local_msat, const u32 feerate_per_kw[NUM_SIDES], @@ -41,6 +42,7 @@ struct channel *new_full_channel(const tal_t *ctx, chain_hash, funding_txid, funding_txout, + minimum_depth, funding, local_msat, feerate_per_kw[LOCAL], diff --git a/channeld/full_channel.h b/channeld/full_channel.h index 8a217d176..427487d1c 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -10,8 +10,10 @@ /** * new_full_channel: Given initial fees and funding, what is initial state? * @ctx: tal context to allocate return value from. + * @chain_hash: Which blockchain are we talking about? * @funding_txid: The commitment transaction id. * @funding_txout: The commitment transaction output number. + * @minimum_depth: The minimum confirmations needed for funding transaction. * @funding: The commitment transaction amount. * @local_msat: The amount for the local side (remainder goes to remote) * @feerate_per_kw: feerate per kiloweight (satoshis) for the commitment @@ -30,6 +32,7 @@ struct channel *new_full_channel(const tal_t *ctx, const struct bitcoin_blkid *chain_hash, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, + u32 minimum_depth, struct amount_sat funding, struct amount_msat local_msat, const u32 feerate_per_kw[NUM_SIDES], diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 406ca9154..bbc4b8826 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -453,7 +453,7 @@ int main(void) feerate_per_kw[LOCAL] = feerate_per_kw[REMOTE] = 15000; lchannel = new_full_channel(tmpctx, &chainparams->genesis_blockhash, - &funding_txid, funding_output_index, + &funding_txid, funding_output_index, 0, funding_amount, to_local, feerate_per_kw, local_config, @@ -464,7 +464,7 @@ int main(void) LOCAL); rchannel = new_full_channel(tmpctx, &chainparams->genesis_blockhash, - &funding_txid, funding_output_index, + &funding_txid, funding_output_index, 0, funding_amount, to_remote, feerate_per_kw, remote_config, diff --git a/common/initial_channel.c b/common/initial_channel.c index 06823f535..d5983fec9 100644 --- a/common/initial_channel.c +++ b/common/initial_channel.c @@ -12,6 +12,7 @@ struct channel *new_initial_channel(const tal_t *ctx, const struct bitcoin_blkid *chain_hash, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, + u32 minimum_depth, struct amount_sat funding, struct amount_msat local_msatoshi, u32 feerate_per_kw, @@ -29,6 +30,7 @@ struct channel *new_initial_channel(const tal_t *ctx, channel->funding_txid = *funding_txid; channel->funding_txout = funding_txout; channel->funding = funding; + channel->minimum_depth = minimum_depth; if (!amount_sat_sub_msat(&remote_msatoshi, channel->funding, local_msatoshi)) return tal_free(channel); diff --git a/common/initial_channel.h b/common/initial_channel.h index 0966d45b4..6d5aa445a 100644 --- a/common/initial_channel.h +++ b/common/initial_channel.h @@ -38,6 +38,9 @@ struct channel { /* satoshis in from commitment tx */ struct amount_sat funding; + /* confirmations needed for locking funding */ + u32 minimum_depth; + /* Who is paying fees. */ enum side funder; @@ -69,6 +72,7 @@ struct channel { * @chain_hash: Which blockchain are we talking about? * @funding_txid: The commitment transaction id. * @funding_txout: The commitment transaction output number. + * @minimum_depth: The minimum confirmations needed for funding transaction. * @funding_satoshis: The commitment transaction amount. * @local_msatoshi: The amount for the local side (remainder goes to remote) * @feerate_per_kw: feerate per kiloweight (satoshis) for the commitment @@ -87,6 +91,7 @@ struct channel *new_initial_channel(const tal_t *ctx, const struct bitcoin_blkid *chain_hash, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, + u32 minimum_depth, struct amount_sat funding, struct amount_msat local_msatoshi, u32 feerate_per_kw, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 1c1d7949f..de324aaf1 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -222,7 +222,7 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) /* And we never get these from channeld. */ case WIRE_CHANNEL_INIT: - case WIRE_CHANNEL_FUNDING_LOCKED: + case WIRE_CHANNEL_FUNDING_DEPTH: case WIRE_CHANNEL_OFFER_HTLC: case WIRE_CHANNEL_FULFILL_HTLC: case WIRE_CHANNEL_FAIL_HTLC: @@ -341,6 +341,7 @@ void peer_start_channeld(struct channel *channel, &channel->funding_txid, channel->funding_outnum, channel->funding, + channel->minimum_depth, &channel->our_config, &channel->channel_info.their_config, channel->channel_info.feerate_per_kw, @@ -393,32 +394,38 @@ void peer_start_channeld(struct channel *channel, try_update_feerates(ld, channel); } -bool channel_tell_funding_locked(struct lightningd *ld, +bool channel_tell_depth(struct lightningd *ld, struct channel *channel, const struct bitcoin_txid *txid, u32 depth) { + const char *txidstr; + + txidstr = type_to_string(tmpctx, struct bitcoin_txid, txid); + /* If not awaiting lockin/announce, it doesn't care any more */ if (channel->state != CHANNELD_AWAITING_LOCKIN && channel->state != CHANNELD_NORMAL) { log_debug(channel->log, - "Funding tx confirmed, but peer in state %s", - channel_state_name(channel)); + "Funding tx %s confirmed, but peer in state %s", + txidstr, channel_state_name(channel)); return true; } if (!channel->owner) { log_debug(channel->log, - "Funding tx confirmed, but peer disconnected"); + "Funding tx %s confirmed, but peer disconnected", + txidstr); return false; } subd_send_msg(channel->owner, - take(towire_channel_funding_locked(NULL, channel->scid, + take(towire_channel_funding_depth(NULL, channel->scid, depth))); if (channel->remote_funding_locked - && channel->state == CHANNELD_AWAITING_LOCKIN) + && channel->state == CHANNELD_AWAITING_LOCKIN + && depth >= channel->minimum_depth) lockin_complete(channel); return true; diff --git a/lightningd/channel_control.h b/lightningd/channel_control.h index 8d6d8f738..3e62150cf 100644 --- a/lightningd/channel_control.h +++ b/lightningd/channel_control.h @@ -15,7 +15,7 @@ void peer_start_channeld(struct channel *channel, bool reconnected); /* Returns true if subd told, otherwise false. */ -bool channel_tell_funding_locked(struct lightningd *ld, +bool channel_tell_depth(struct lightningd *ld, struct channel *channel, const struct bitcoin_txid *txid, u32 depth); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 909be0ca1..0309c62dd 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -856,23 +856,22 @@ void peer_connected(struct lightningd *ld, const u8 *msg, plugin_hook_call_peer_connected(ld, hook_payload, hook_payload); } -static enum watch_result funding_lockin_cb(struct lightningd *ld, +static enum watch_result funding_depth_cb(struct lightningd *ld, struct channel *channel, const struct bitcoin_txid *txid, unsigned int depth) { const char *txidstr; - txidstr = type_to_string(channel, struct bitcoin_txid, txid); + txidstr = type_to_string(tmpctx, struct bitcoin_txid, txid); log_debug(channel->log, "Funding tx %s depth %u of %u", txidstr, depth, channel->minimum_depth); tal_free(txidstr); - if (depth < channel->minimum_depth) - return KEEP_WATCHING; + bool local_locked = depth >= channel->minimum_depth; /* If we restart, we could already have peer->scid from database */ - if (!channel->scid) { + if (local_locked && !channel->scid) { struct txlocator *loc; loc = wallet_transaction_locate(tmpctx, ld->wallet, txid); @@ -891,9 +890,11 @@ static enum watch_result funding_lockin_cb(struct lightningd *ld, } /* Try to tell subdaemon */ - if (!channel_tell_funding_locked(ld, channel, txid, depth)) + if (!channel_tell_depth(ld, channel, txid, depth)) return KEEP_WATCHING; + if (!local_locked) + return KEEP_WATCHING; /* BOLT #7: * * A node: @@ -932,7 +933,7 @@ void channel_watch_funding(struct lightningd *ld, struct channel *channel) { /* FIXME: Remove arg from cb? */ watch_txid(channel, ld->topology, channel, - &channel->funding_txid, funding_lockin_cb); + &channel->funding_txid, funding_depth_cb); watch_txo(channel, ld->topology, channel, &channel->funding_txid, channel->funding_outnum, funding_spent); diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 36564de83..d4c1a462d 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -34,12 +34,12 @@ void broadcast_tx(struct chain_topology *topo UNNEEDED, int exitstatus UNNEEDED, const char *err)) { fprintf(stderr, "broadcast_tx called!\n"); abort(); } -/* Generated stub for channel_tell_funding_locked */ -bool channel_tell_funding_locked(struct lightningd *ld UNNEEDED, +/* Generated stub for channel_tell_depth */ +bool channel_tell_depth(struct lightningd *ld UNNEEDED, struct channel *channel UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 depth UNNEEDED) -{ fprintf(stderr, "channel_tell_funding_locked called!\n"); abort(); } +{ fprintf(stderr, "channel_tell_depth called!\n"); abort(); } /* Generated stub for command_fail */ struct command_result *command_fail(struct command *cmd UNNEEDED, int code UNNEEDED, const char *fmt UNNEEDED, ...) diff --git a/openingd/openingd.c b/openingd/openingd.c index 7ae5a8906..125bd06c9 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -632,12 +632,13 @@ static u8 *funder_channel(struct state *state, * * The routines to support `struct channel` are split into a common * part (common/initial_channel) which doesn't support HTLCs and is - * enough for us hgere, and the complete channel support required by + * enough for us here, and the complete channel support required by * `channeld` which lives in channeld/full_channel. */ state->channel = new_initial_channel(state, &state->chainparams->genesis_blockhash, &state->funding_txid, state->funding_txout, + minimum_depth, state->funding, local_msat, state->feerate_per_kw, @@ -1041,6 +1042,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &chain_hash, &state->funding_txid, state->funding_txout, + state->minimum_depth, state->funding, state->push_msat, state->feerate_per_kw, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 250a6b071..fb4411c2a 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -45,12 +45,12 @@ void broadcast_tx(struct chain_topology *topo UNNEEDED, int exitstatus UNNEEDED, const char *err)) { fprintf(stderr, "broadcast_tx called!\n"); abort(); } -/* Generated stub for channel_tell_funding_locked */ -bool channel_tell_funding_locked(struct lightningd *ld UNNEEDED, +/* Generated stub for channel_tell_depth */ +bool channel_tell_depth(struct lightningd *ld UNNEEDED, struct channel *channel UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 depth UNNEEDED) -{ fprintf(stderr, "channel_tell_funding_locked called!\n"); abort(); } +{ fprintf(stderr, "channel_tell_depth called!\n"); abort(); } /* Generated stub for command_fail */ struct command_result *command_fail(struct command *cmd UNNEEDED, int code UNNEEDED, const char *fmt UNNEEDED, ...)