diff --git a/gossipd/gossmap_manage.c b/gossipd/gossmap_manage.c index a25c5dd88d75..7c3a40003a7d 100644 --- a/gossipd/gossmap_manage.c +++ b/gossipd/gossmap_manage.c @@ -824,9 +824,11 @@ static const char *process_channel_update(const tal_t *ctx, u32 prev_timestamp = gossip_store_get_timestamp(gm->gs, chan->cupdate_off[dir]); if (prev_timestamp >= timestamp) { - status_trace("Too-old update for %s", - fmt_short_channel_id(tmpctx, scid)); - /* Too old, ignore */ + /* Don't spam the logs for duplicates! */ + if (timestamp < prev_timestamp) + status_trace("Too-old update for %s", + fmt_short_channel_id(tmpctx, scid)); + /* Too old / redundant, ignore */ return NULL; } } else { diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 41b9e0e68a8c..3630623d8fc3 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -824,7 +824,7 @@ static void updates_complete(struct chain_topology *topo) { if (!bitcoin_blkid_eq(&topo->tip->blkid, &topo->prev_tip)) { /* Tell lightningd about new block. */ - notify_new_block(topo->bitcoind->ld, topo->tip->height); + notify_new_block(topo->bitcoind->ld); /* Tell watch code to re-evaluate all txs. */ watch_topology_changed(topo); @@ -840,7 +840,7 @@ static void updates_complete(struct chain_topology *topo) /* Send out an account balance snapshot */ if (!first_update_complete) { - send_account_balance_snapshot(topo->ld, topo->tip->height); + send_account_balance_snapshot(topo->ld); first_update_complete = true; } } diff --git a/lightningd/channel.h b/lightningd/channel.h index 51b6353c3fa7..87706d0d19e6 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -601,6 +601,29 @@ static inline bool channel_state_failing_onchain(enum channel_state state) abort(); } +static inline bool channel_state_funding_spent_onchain(enum channel_state state) +{ + switch (state) { + case CHANNELD_AWAITING_LOCKIN: + case CHANNELD_NORMAL: + case CHANNELD_AWAITING_SPLICE: + case CLOSINGD_SIGEXCHANGE: + case CHANNELD_SHUTTING_DOWN: + case CLOSINGD_COMPLETE: + case DUALOPEND_OPEN_INIT: + case DUALOPEND_OPEN_COMMIT_READY: + case DUALOPEND_OPEN_COMMITTED: + case DUALOPEND_AWAITING_LOCKIN: + case AWAITING_UNILATERAL: + return false; + case CLOSED: + case FUNDING_SPEND_SEEN: + case ONCHAIN: + return true; + } + abort(); +} + static inline bool channel_state_pre_open(enum channel_state state) { switch (state) { diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index d344c2f3585b..8e22b0702a41 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -114,9 +114,9 @@ static void try_update_feerates(struct lightningd *ld, struct channel *channel) } static void try_update_blockheight(struct lightningd *ld, - struct channel *channel, - u32 blockheight) + struct channel *channel) { + u32 blockheight = get_block_height(ld->topology); u8 *msg; /* We don't update the blockheight for non-leased chans */ @@ -1005,7 +1005,7 @@ void lockin_has_completed(struct channel *channel, bool record_push) * so update now. */ try_update_feerates(ld, channel); - try_update_blockheight(ld, channel, get_block_height(ld->topology)); + try_update_blockheight(ld, channel); /* Emit an event for the channel open (or channel proposal if blockheight * is zero) */ @@ -1878,8 +1878,7 @@ bool peer_start_channeld(struct channel *channel, * might not be what we expect: adjust now. */ if (channel->opener == LOCAL) { try_update_feerates(ld, channel); - try_update_blockheight(ld, channel, - get_block_height(ld->topology)); + try_update_blockheight(ld, channel); } /* "Reestablished" if we've just opened. */ @@ -1925,9 +1924,10 @@ void channeld_tell_depth(struct channel *channel, * If so, we should forget the channel. */ static bool is_fundee_should_forget(struct lightningd *ld, - struct channel *channel, - u32 block_height) + struct channel *channel) { + u32 block_height = get_block_height(ld->topology); + /* BOLT #2: * * A non-funding node (fundee): @@ -1967,9 +1967,9 @@ is_fundee_should_forget(struct lightningd *ld, } /* Notify all channels of new blocks. */ -void channel_notify_new_block(struct lightningd *ld, - u32 block_height) +void channel_notify_new_block(struct lightningd *ld) { + u32 block_height = get_block_height(ld->topology); struct peer *peer; struct channel *channel; struct channel **to_forget = tal_arr(NULL, struct channel *, 0); @@ -1983,13 +1983,12 @@ void channel_notify_new_block(struct lightningd *ld, list_for_each(&peer->channels, channel, list) { if (channel_state_uncommitted(channel->state)) continue; - if (is_fundee_should_forget(ld, channel, block_height)) { + if (is_fundee_should_forget(ld, channel)) { tal_arr_expand(&to_forget, channel); } else /* Let channels know about new blocks, * required for lease updates */ - try_update_blockheight(ld, channel, - block_height); + try_update_blockheight(ld, channel); } } diff --git a/lightningd/channel_control.h b/lightningd/channel_control.h index 199657abe1e0..9107fbd3aa8b 100644 --- a/lightningd/channel_control.h +++ b/lightningd/channel_control.h @@ -23,8 +23,7 @@ void channeld_tell_depth(struct channel *channel, u32 depth); /* Notify channels of new blocks. */ -void channel_notify_new_block(struct lightningd *ld, - u32 block_height); +void channel_notify_new_block(struct lightningd *ld); /* Cancel the channel after `fundchannel_complete` succeeds * but before funding broadcasts. */ diff --git a/lightningd/channel_gossip.c b/lightningd/channel_gossip.c index 76a503c9875d..5c56ae2e0885 100644 --- a/lightningd/channel_gossip.c +++ b/lightningd/channel_gossip.c @@ -1,4 +1,5 @@ #include "config.h" +#include #include #include #include @@ -16,14 +17,28 @@ #include enum channel_gossip_state { - /* Not a public channel */ + /* It's dead, so don't talk about it. */ + CGOSSIP_CHANNEL_DEAD, + /* It's dying, but we can still broadcast the "disabled" update. */ + CGOSSIP_CHANNEL_ANNOUNCED_DYING, + /* It's dead: send the "disabled" update only as error reply. */ + CGOSSIP_CHANNEL_ANNOUNCED_DEAD, + + /* Unannounced channels: without alias or scid */ + CGOSSIP_PRIVATE_WAITING_FOR_USABLE, + /* With alias/scid */ CGOSSIP_PRIVATE, - /* We can't yet send (non-forwardable) channel_update. */ - CGOSSIP_NOT_USABLE, - /* Not yet in at announcable depth. */ - CGOSSIP_NOT_DEEP_ENOUGH, - /* We want the peer's announcement_signatures. */ - CGOSSIP_NEED_PEER_SIGS, + + /* Public channels: */ + /* Not usable. */ + CGOSSIP_WAITING_FOR_USABLE, + /* No scid (zeroconf can be in CHANNELD_NORMAL without scid) */ + CGOSSIP_WAITING_FOR_SCID, + /* Sent ours, we want the peer's announcement_signatures (or + * we have it, but different scids) */ + CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS, + /* Not yet in at announceable depth (6). */ + CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH, /* We have received sigs, and announced. */ CGOSSIP_ANNOUNCED, }; @@ -31,20 +46,110 @@ enum channel_gossip_state { static const char *channel_gossip_state_str(enum channel_gossip_state s) { switch (s) { + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: + return "CGOSSIP_PRIVATE_WAITING_FOR_USABLE"; case CGOSSIP_PRIVATE: return "CGOSSIP_PRIVATE"; - case CGOSSIP_NOT_USABLE: - return "CGOSSIP_NOT_USABLE"; - case CGOSSIP_NOT_DEEP_ENOUGH: - return "CGOSSIP_NOT_DEEP_ENOUGH"; - case CGOSSIP_NEED_PEER_SIGS: - return "CGOSSIP_NEED_PEER_SIGS"; + case CGOSSIP_WAITING_FOR_USABLE: + return "CGOSSIP_WAITING_FOR_USABLE"; + case CGOSSIP_WAITING_FOR_SCID: + return "CGOSSIP_WAITING_FOR_SCID"; + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: + return "CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS"; + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: + return "CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH"; case CGOSSIP_ANNOUNCED: return "CGOSSIP_ANNOUNCED"; + case CGOSSIP_CHANNEL_DEAD: + return "CGOSSIP_CHANNEL_DEAD"; + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + return "CGOSSIP_CHANNEL_ANNOUNCED_DYING"; + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + return "CGOSSIP_CHANNEL_ANNOUNCED_DEAD"; } return "***INVALID***"; } +struct state_transition { + enum channel_gossip_state from, to; + const char *description; +}; + +static struct state_transition allowed_transitions[] = { + /* Private channels */ + { CGOSSIP_PRIVATE_WAITING_FOR_USABLE, CGOSSIP_CHANNEL_DEAD, + "Unannounced channel closed before it had scid or alias" }, + { CGOSSIP_PRIVATE_WAITING_FOR_USABLE, CGOSSIP_PRIVATE, + "Unannounced channel live" }, + { CGOSSIP_PRIVATE, CGOSSIP_CHANNEL_DEAD, + "Unannounced channel closed" }, + + /* Public channels, startup */ + { CGOSSIP_WAITING_FOR_USABLE, CGOSSIP_CHANNEL_DEAD, + "Channel closed before it had scid or alias" }, + { CGOSSIP_WAITING_FOR_USABLE, CGOSSIP_WAITING_FOR_SCID, + "Channel usable (zeroconf) but no scid yet" }, + { CGOSSIP_WAITING_FOR_SCID, CGOSSIP_CHANNEL_DEAD, + "Zeroconf channel closed before funding tx mined" }, + { CGOSSIP_WAITING_FOR_USABLE, CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS, + "Channel mined, but we haven't got matching announcment sigs from peer" }, + { CGOSSIP_WAITING_FOR_USABLE, CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH, + "Channel mined, they had already sent announcement sigs when we noticed" }, + { CGOSSIP_WAITING_FOR_SCID, CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS, + "Channel mined (zeroconf), but we haven't got matching announcment sigs from peer" }, + { CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS, CGOSSIP_CHANNEL_DEAD, + "Channel closed while waiting for announcement sigs from peer" }, + { CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS, CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH, + "Channel now waiting for 6 confirms to publish announcement" }, + { CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH, CGOSSIP_CHANNEL_DEAD, + "Channel closed before 6 confirms" }, + { CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH, CGOSSIP_ANNOUNCED, + "Channel fully announced" }, + { CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS, CGOSSIP_ANNOUNCED, + "Got peer announcement signatures after already at 6 confirmations" }, + { CGOSSIP_WAITING_FOR_USABLE, CGOSSIP_ANNOUNCED, + "We got peer sigs first, then 6 confirms, then finally received CHANNEL_READY" }, + + /* Splice */ + { CGOSSIP_ANNOUNCED, CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS, + "Splicing"}, + { CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH, CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS, + "Splicing before 6 confirmations"}, + + /* Public channels, closing */ + { CGOSSIP_ANNOUNCED, CGOSSIP_CHANNEL_ANNOUNCED_DYING, + "Announced channel closing, but close tx not seen onchain yet." }, + { CGOSSIP_ANNOUNCED, CGOSSIP_CHANNEL_ANNOUNCED_DEAD, + "Announced channel closed by seeing onchain tx." }, + { CGOSSIP_CHANNEL_ANNOUNCED_DYING, CGOSSIP_CHANNEL_ANNOUNCED_DEAD, + "Announced channel closed onchain." }, + { CGOSSIP_CHANNEL_DEAD, CGOSSIP_CHANNEL_ANNOUNCED_DEAD, + "Channel closed before 6 confirms, but now has 6 confirms so could be announced." }, + { CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH, CGOSSIP_CHANNEL_ANNOUNCED_DYING, + "Channel hit announced depth, but closed" }, +}; + +static void check_state_transition(const struct channel *channel, + enum channel_gossip_state oldstate, + enum channel_gossip_state newstate) +{ + /* Check transition */ + for (size_t i = 0; i < ARRAY_SIZE(allowed_transitions); i++) { + if (allowed_transitions[i].from == oldstate + && allowed_transitions[i].to == newstate) { + log_debug(channel->log, "gossip state: %s->%s (%s)", + channel_gossip_state_str(oldstate), + channel_gossip_state_str(newstate), + allowed_transitions[i].description); + return; + } + } + + log_broken(channel->log, "Illegal gossip state transition: %s->%s", + channel_gossip_state_str(oldstate), + channel_gossip_state_str(newstate)); +} + struct remote_announce_sigs { struct short_channel_id scid; secp256k1_ecdsa_signature node_sig; @@ -66,71 +171,162 @@ struct channel_gossip { /* Details of latest channel_update sent by peer */ const struct peer_update *peer_update; + + /* To avoid a storm, we only respond to announcement_signatures with + * our own signatures once */ + bool sent_sigs; }; static bool starting_up = true, gossipd_init_done = false; -/* We send non-forwardable channel updates if we can. */ -static bool can_send_channel_update(const struct channel *channel) +static bool is_private(const struct channel *channel) +{ + return !(channel->channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL); +} + +static bool is_usable(const struct channel *channel) { + if (channel_state_pre_open(channel->state)) + return false; /* Can't send if we can't talk about it. */ - if (!channel->scid && !channel->alias[REMOTE]) + return channel->scid != NULL || channel->alias[REMOTE] != NULL; +} + +static bool has_scid(const struct channel *channel) +{ + if (!is_usable(channel)) return false; - if (channel_state_pre_open(channel->state)) + return channel->scid != NULL; +} + +static bool has_matching_peer_sigs(const struct channel *channel) +{ + const struct channel_gossip *cg = channel->channel_gossip; + + if (!has_scid(channel)) return false; - return true; + + if (!cg->remote_sigs) + return false; + + return short_channel_id_eq(cg->remote_sigs->scid, *channel->scid); } -/* We send start the channel announcement signatures if we can. - * Caller must check it's not CGOSSIP_PRIVATE, but this is used - * to set up state so we cannot assert here! - */ -static bool channel_announceable(const struct channel *channel, - u32 block_height) +static bool has_announce_depth(const struct channel *channel) { - if (!channel->scid) + u32 block_height = get_block_height(channel->peer->ld->topology); + + if (!has_matching_peer_sigs(channel)) return false; + return is_scid_depth_announceable(*channel->scid, block_height); } -static void check_channel_gossip(const struct channel *channel) +/* Truly dead once we've seen spend onchain */ +static bool is_dead(const struct channel *channel) +{ + return channel_state_funding_spent_onchain(channel->state); +} + +static bool is_announced_dying(const struct channel *channel) +{ + return has_announce_depth(channel) + && channel_state_closing(channel->state) + && !channel_state_funding_spent_onchain(channel->state); +} + +static bool is_announced_dead(const struct channel *channel) +{ + return has_announce_depth(channel) + && channel_state_funding_spent_onchain(channel->state); +} + +#define check_channel_gossip(channel) check_channel_gossip_((channel), __LINE__) +static void check_channel_gossip_(const struct channel *channel, int line) { struct channel_gossip *cg = channel->channel_gossip; + bool enabled; + log_debug(channel->log, "checking channel gossip (%u)...", line); /* Note: we can't assert is_scid_depth_announceable, for two reasons: - * 1. on restart and rescan, block numbers can go backwards.' + * 1. on restar_t and rescan, block numbers can go backwards.' * 2. We don't get notified via channel_gossip_notify_new_block until * there are no new blocks to add, not on every block. */ switch (cg->state) { + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: + assert(is_private(channel)); + assert(!is_dead(channel)); + assert(!is_usable(channel)); + assert(!cg->remote_sigs); + assert(!cg->refresh_timer); + return; case CGOSSIP_PRIVATE: - assert(!(channel->channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL)); + assert(is_private(channel)); + assert(!is_dead(channel)); + assert(is_usable(channel)); assert(!cg->remote_sigs); assert(!cg->refresh_timer); return; - - case CGOSSIP_NOT_USABLE: - assert(channel->channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL); - assert(!can_send_channel_update(channel)); + case CGOSSIP_WAITING_FOR_USABLE: + assert(!is_private(channel)); + assert(!is_dead(channel)); + assert(!is_usable(channel)); + assert(!cg->refresh_timer); + return; + case CGOSSIP_WAITING_FOR_SCID: + assert(!is_private(channel)); + assert(!is_dead(channel)); + assert(!has_scid(channel)); assert(!cg->refresh_timer); return; - case CGOSSIP_NOT_DEEP_ENOUGH: - assert(channel->channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL); - assert(can_send_channel_update(channel)); + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: + assert(!is_private(channel)); + assert(!is_dead(channel)); + assert(!has_matching_peer_sigs(channel)); assert(!cg->refresh_timer); return; - case CGOSSIP_NEED_PEER_SIGS: - assert(can_send_channel_update(channel)); - assert(channel->scid); - /* If we have sigs, they don't match */ - if (cg->remote_sigs) - assert(!channel->scid || !short_channel_id_eq(cg->remote_sigs->scid, *channel->scid)); + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: + assert(!is_private(channel)); + assert(!is_dead(channel)); + /* We can't actually know !has_announce_depth: current + * block height may not have been updated to match! */ assert(!cg->refresh_timer); return; case CGOSSIP_ANNOUNCED: - assert(can_send_channel_update(channel)); - assert(channel->scid); - assert(cg->remote_sigs); + assert(!is_private(channel)); + assert(!is_dead(channel)); + /* We can't actually know !has_announce_depth: current + * block height may not have been updated to match! */ + /* refresh_timer is not always set at init */ + return; + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + assert(!is_dead(channel)); + assert(has_announce_depth(channel)); + /* We may not have a cupdate in some odd cases, e.g. reorg */ + if (cg->cupdate) { + assert(channel_update_details(cg->cupdate, NULL, + &enabled)); + assert(!enabled); + } + assert(!cg->refresh_timer); + return; + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + assert(is_dead(channel)); + assert(is_announced_dead(channel)); + /* We may not have a cupdate in some odd cases, e.g. reorg */ + if (cg->cupdate) { + assert(channel_update_details(cg->cupdate, NULL, + &enabled)); + assert(!enabled); + } + assert(!cg->refresh_timer); + return; + case CGOSSIP_CHANNEL_DEAD: + assert(is_dead(channel)); + assert(!is_announced_dying(channel)); + assert(!cg->cupdate); + assert(!cg->refresh_timer); return; } fatal("Bad channel_gossip_state %u", cg->state); @@ -179,6 +375,10 @@ static void broadcast_new_gossip(struct lightningd *ld, if (taken(msg)) tal_steal(tmpctx, msg); + /* Don't crash if shutting down */ + if (!ld->gossip) + return; + /* Tell gossipd about it */ subd_req(ld->gossip, ld->gossip, take(towire_gossipd_addgossip(NULL, msg, known_channel)), @@ -199,67 +399,34 @@ static void broadcast_new_gossip(struct lightningd *ld, /* Recursion */ static void cupdate_timer_refresh(struct channel *channel); -static void set_public_cupdate(struct channel *channel, - const u8 *cupdate TAKES, - bool refresh_later) +static enum channel_gossip_state derive_channel_state(const struct channel *channel) { - struct lightningd *ld = channel->peer->ld; - struct channel_gossip *cg = channel->channel_gossip; - u32 timestamp; - bool enabled; - struct timeabs now, due; - - if (!channel_update_details(cupdate, ×tamp, &enabled)) { - log_broken(channel->log, "Invalid channel_update %s: ignoring", - tal_hex(tmpctx, cupdate)); - if (taken(cupdate)) - tal_free(cupdate); - return; - } - - tal_free(cg->cupdate); - cg->cupdate = tal_dup_talarr(cg, u8, cupdate); - - cg->refresh_timer = tal_free(cg->refresh_timer); + if (is_announced_dying(channel)) + return CGOSSIP_CHANNEL_ANNOUNCED_DYING; - /* If enabled, we refresh, based on old timestamp */ - if (!enabled || !refresh_later) - return; + if (is_announced_dead(channel)) + return CGOSSIP_CHANNEL_ANNOUNCED_DEAD; - due.ts.tv_sec = timestamp; - due.ts.tv_nsec = 0; - due = timeabs_add(due, - time_from_sec(GOSSIP_PRUNE_INTERVAL(ld->dev_fast_gossip_prune) - - GOSSIP_BEFORE_DEADLINE(ld->dev_fast_gossip_prune))); + if (is_dead(channel)) + return CGOSSIP_CHANNEL_DEAD; - /* In case it's passed, timer should be zero */ - now = time_now(); - if (time_after(now, due)) - due = now; - - cg->refresh_timer = new_reltimer(ld->timers, cg, - time_between(due, now), - cupdate_timer_refresh, - channel); -} + if (is_private(channel)) { + if (!is_usable(channel)) + return CGOSSIP_PRIVATE_WAITING_FOR_USABLE; + return CGOSSIP_PRIVATE; + } -static enum channel_gossip_state init_public_state(struct channel *channel, - const struct remote_announce_sigs *remote_sigs) -{ - struct lightningd *ld = channel->peer->ld; + if (!is_usable(channel)) + return CGOSSIP_WAITING_FOR_USABLE; - if (!can_send_channel_update(channel)) - return CGOSSIP_NOT_USABLE; + if (!has_scid(channel)) + return CGOSSIP_WAITING_FOR_SCID; - /* Note: depth when we startup is not actually reliable, since - * we step one block back. We'll fix this up when gossipd - * tells us it's announced, or, when we add the block. */ - if (!channel_announceable(channel, get_block_height(ld->topology))) - return CGOSSIP_NOT_DEEP_ENOUGH; + if (!has_matching_peer_sigs(channel)) + return CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS; - if (!remote_sigs) { - return CGOSSIP_NEED_PEER_SIGS; - } + if (!has_announce_depth(channel)) + return CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH; return CGOSSIP_ANNOUNCED; } @@ -287,10 +454,6 @@ static void send_private_cupdate(struct channel *channel, bool even_if_redundant const u8 *cupdate; struct short_channel_id scid; - /* Only useful channels: not if closing */ - if (!channel_state_can_add_htlc(channel->state)) - return; - /* BOLT #7: * * - MAY create a `channel_update` to communicate the channel @@ -328,53 +491,91 @@ static void send_private_cupdate(struct channel *channel, bool even_if_redundant msg_to_peer(channel->peer, cg->cupdate); } -/* Send gossipd a channel_update, if not redundant. */ -static void broadcast_public_cupdate(struct channel *channel, - bool ok_if_disconnected) +/* Sets channel->channel_gossip->cupdate. Returns true if it changed. */ +static bool update_channel_update(const struct channel *channel, + bool enable) { - struct lightningd *ld = channel->peer->ld; struct channel_gossip *cg = channel->channel_gossip; const u8 *cupdate; u32 old_timestamp; + bool have_old; + + /* If we have no previous channel_update, this fails */ + have_old = channel_update_details(cg->cupdate, &old_timestamp, NULL); + cupdate = unsigned_channel_update(tmpctx, channel, *channel->scid, + have_old ? &old_timestamp : NULL, + true, + enable); + + /* Suppress redundant ones */ + if (cg->cupdate && channel_update_same(cg->cupdate, cupdate)) + return false; + + tal_free(cg->cupdate); + cg->cupdate = sign_update(cg, channel->peer->ld, cupdate); + return true; +} + +/* Using default logic, should this channel be enabled? */ +static bool channel_should_enable(const struct channel *channel, + bool ok_if_disconnected) +{ bool enable, have_old; /* If we have no previous channel_update, this fails */ - have_old = channel_update_details(cg->cupdate, - &old_timestamp, &enable); + have_old = channel_update_details(channel->channel_gossip->cupdate, + NULL, &enable); if (!channel_state_can_add_htlc(channel->state)) { /* If it's (no longer) usable, it's a simply courtesy * to disable */ - enable = false; + return false; } else if (channel->owner) { /* If it's live, it's enabled */ - enable = true; + return true; } else if (starting_up) { /* If we are starting up, don't change it! */ if (!have_old) /* Assume the best if we don't have an updated */ enable = true; + return enable; } else { - enable = ok_if_disconnected; + return ok_if_disconnected; } +} - cupdate = unsigned_channel_update(tmpctx, channel, *channel->scid, - have_old ? &old_timestamp : NULL, - true, - enable); +/* Based on existing update, schedule next refresh */ +static void arm_refresh_timer(struct channel *channel) +{ + struct lightningd *ld = channel->peer->ld; + struct channel_gossip *cg = channel->channel_gossip; + struct timeabs now = time_now(), due; + u32 timestamp; - /* Suppress redundant ones */ - if (cg->cupdate && channel_update_same(cg->cupdate, cupdate)) + if (!channel_update_details(cg->cupdate, ×tamp, NULL)) { + log_broken(channel->log, "Missing channel_update for refresh?"); return; + } + due.ts.tv_sec = timestamp; + due.ts.tv_nsec = 0; - set_public_cupdate(channel, - take(sign_update(NULL, channel->peer->ld, cupdate)), - true); - broadcast_new_gossip(ld, cg->cupdate, NULL, "channel update"); + due = timeabs_add(due, + time_from_sec(GOSSIP_PRUNE_INTERVAL(ld->dev_fast_gossip_prune) + - GOSSIP_BEFORE_DEADLINE(ld->dev_fast_gossip_prune))); + + /* In case it's passed, timer should be zero */ + if (time_after(now, due)) + due = now; + + cg->refresh_timer = new_reltimer(ld->timers, cg, + time_between(due, now), + cupdate_timer_refresh, + channel); } static void cupdate_timer_refresh(struct channel *channel) { + struct lightningd *ld = channel->peer->ld; struct channel_gossip *cg = channel->channel_gossip; /* Don't try to free this again if set_public_cupdate called later */ @@ -385,7 +586,10 @@ static void cupdate_timer_refresh(struct channel *channel) /* Free old cupdate to force a new one to be generated */ cg->cupdate = tal_free(cg->cupdate); - broadcast_public_cupdate(channel, true); + update_channel_update(channel, channel_should_enable(channel, true)); + + broadcast_new_gossip(ld, cg->cupdate, NULL, "channel update"); + arm_refresh_timer(channel); } static void stash_remote_announce_sigs(struct channel *channel, @@ -419,27 +623,34 @@ static void stash_remote_announce_sigs(struct channel *channel, "channel_gossip: received announcement sigs for %s (we have %s)", fmt_short_channel_id(tmpctx, scid), channel->scid ? fmt_short_channel_id(tmpctx, *channel->scid) : "none"); -} - -static bool apply_remote_sigs(struct channel *channel) -{ - struct channel_gossip *cg = channel->channel_gossip; - if (!cg->remote_sigs) - return false; + /* Save to db if we like these signatures */ + if (!channel->scid) + return; if (!short_channel_id_eq(cg->remote_sigs->scid, *channel->scid)) { log_debug(channel->log, "We have remote sigs, but wrong scid!"); - return false; + return; } wallet_announcement_save(channel->peer->ld->wallet, channel->dbid, &cg->remote_sigs->node_sig, &cg->remote_sigs->bitcoin_sig); - return true; } +/* BOLT #7: + * A node: + * - If the `open_channel` message has the `announce_channel` bit set AND a + * `shutdown` message has not been sent: + * - After `channel_ready` has been sent and received AND the funding + * transaction has enough confirmations to ensure that it won't be + * reorganized: + * - MUST send `announcement_signatures` for the funding transaction. + * - Otherwise: + * - MUST NOT send the `announcement_signatures` message. + */ + static void send_channel_announce_sigs(struct channel *channel) { /* First 2 + 256 byte are the signatures and msg type, skip them */ @@ -447,18 +658,18 @@ static void send_channel_announce_sigs(struct channel *channel) struct lightningd *ld = channel->peer->ld; struct sha256_double hash; secp256k1_ecdsa_signature local_node_sig, local_bitcoin_sig; + struct channel_gossip *cg = channel->channel_gossip; const u8 *ca, *msg; - /* If it's already closing, don't bother. */ - if (!channel_state_can_add_htlc(channel->state)) - return; - /* Wait until we've exchanged reestablish messages */ if (!channel->reestablished) { log_debug(channel->log, "channel_gossip: not sending channel_announcement_sigs until reestablished"); return; } + if (cg->sent_sigs) + return; + ca = create_channel_announcement(tmpctx, channel, *channel->scid, NULL, NULL, NULL, NULL); @@ -488,8 +699,10 @@ static void send_channel_announce_sigs(struct channel *channel) &channel->cid, *channel->scid, &local_node_sig, &local_bitcoin_sig); msg_to_peer(channel->peer, take(msg)); + cg->sent_sigs = true; } +/* Sends channel_announcement */ static void send_channel_announcement(struct channel *channel) { secp256k1_ecdsa_signature local_node_sig, local_bitcoin_sig; @@ -511,10 +724,6 @@ static void send_channel_announcement(struct channel *channel) &local_bitcoin_sig)) fatal("Reading hsmd_sign_any_cannouncement_reply: %s", tal_hex(tmpctx, msg)); - /* Don't crash if shutting down */ - if (!ld->gossip) - return; - ca = create_channel_announcement(tmpctx, channel, *channel->scid, &local_node_sig, &local_bitcoin_sig, @@ -523,41 +732,145 @@ static void send_channel_announcement(struct channel *channel) /* Send everyone our new channel announcement */ broadcast_new_gossip(ld, ca, &channel->funding_sats, "channel announcement"); - /* We can also send our first public channel_update now */ - broadcast_public_cupdate(channel, true); - /* And maybe our first node_announcement */ - channel_gossip_node_announce(ld); } -static void set_gossip_state(struct channel *channel, - enum channel_gossip_state state) +#define set_gossip_state(channel, state) \ + set_gossip_state_((channel), (state), __LINE__) +static void set_gossip_state_(struct channel *channel, + enum channel_gossip_state state, int line) { struct channel_gossip *cg = channel->channel_gossip; - cg->state = state; + check_state_transition(channel, cg->state, state); + /* Steps as we leave old state */ switch (cg->state) { + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: + case CGOSSIP_WAITING_FOR_USABLE: case CGOSSIP_PRIVATE: + case CGOSSIP_WAITING_FOR_SCID: + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + break; + case CGOSSIP_ANNOUNCED: + /* Stop refreshing (if we were) */ + cg->refresh_timer = tal_free(cg->refresh_timer); + break; + + /* We should never leave these */ + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + case CGOSSIP_CHANNEL_DEAD: + break; + } + + cg->state = state; + + /* Now the state we're entering */ + switch (cg->state) { + /* These are initial states, never set */ + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: + case CGOSSIP_WAITING_FOR_USABLE: abort(); - case CGOSSIP_NOT_USABLE: + + /* We don't do anything when we first enter these states */ + case CGOSSIP_PRIVATE: + case CGOSSIP_WAITING_FOR_SCID: return; - case CGOSSIP_NOT_DEEP_ENOUGH: - /* But it exists, so try sending private channel_update */ - send_private_cupdate(channel, false); + + /* Always ready to send sigs (once) if we're waiting + * for theirs: particularly for splicing. */ + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: + cg->sent_sigs = false; + return; + + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: + wallet_announcement_save(channel->peer->ld->wallet, + channel->dbid, + &cg->remote_sigs->node_sig, + &cg->remote_sigs->bitcoin_sig); + return; + + case CGOSSIP_ANNOUNCED: + /* BOLT #7: + * A recipient node: + *... + * - If it has sent AND received a valid `announcement_signatures` + * message: + * - If the funding transaction has at least 6 confirmations: + * - SHOULD queue the `channel_announcement` message for + * its peers. + */ + send_channel_announcement(channel); + + /* Any private cupdate will be different from this, so will force a refresh. */ + update_channel_update(channel, channel_should_enable(channel, true)); + broadcast_new_gossip(channel->peer->ld, cg->cupdate, NULL, "channel update"); + + /* We need to refresh channel update every 13 days */ + arm_refresh_timer(channel); + + /* And maybe our first node_announcement */ + channel_gossip_node_announce(channel->peer->ld); + return; + + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + /* Make sure update tells them it's disabled */ + if (update_channel_update(channel, false)) { + /* We might have skipped over CGOSSIP_ANNOUNCED, so tell + * gossipd about us now, so it doesn't complain. */ + send_channel_announcement(channel); + /* And tell the world */ + broadcast_new_gossip(channel->peer->ld, cg->cupdate, NULL, + "channel update"); + } + return; + + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + /* It's disabled, but gossipd has forgotten it, so no + * broadcast */ + update_channel_update(channel, false); + return; + + case CGOSSIP_CHANNEL_DEAD: + return; + } + fatal("Bad channel_gossip_state %u", cg->state); +} + +static void update_gossip_state(struct channel *channel) +{ + enum channel_gossip_state newstate; + struct channel_gossip *cg = channel->channel_gossip; + + newstate = derive_channel_state(channel); + if (newstate != cg->state) + set_gossip_state(channel, newstate); + + switch (cg->state) { + case CGOSSIP_CHANNEL_DEAD: + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + case CGOSSIP_WAITING_FOR_USABLE: + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: return; - case CGOSSIP_NEED_PEER_SIGS: + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: send_channel_announce_sigs(channel); - /* We may already have remote signatures */ - if (!apply_remote_sigs(channel)) - return; - cg->state = CGOSSIP_ANNOUNCED; /* fall thru */ + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: + case CGOSSIP_WAITING_FOR_SCID: + case CGOSSIP_PRIVATE: + /* Always try to send private cupdate: ignored if redundant */ + send_private_cupdate(channel, false); + return; case CGOSSIP_ANNOUNCED: - /* Any previous update was private, so clear. */ - cg->cupdate = tal_free(cg->cupdate); - send_channel_announcement(channel); + /* If a channel parameter has changed, send new update */ + if (update_channel_update(channel, channel_should_enable(channel, true))) + broadcast_new_gossip(channel->peer->ld, cg->cupdate, NULL, + "channel update"); return; } + fatal("Bad channel_gossip_state %u", cg->state); } @@ -574,6 +887,7 @@ void channel_gossip_init(struct channel *channel, cg->refresh_timer = NULL; cg->peer_update = tal_dup_or_null(channel, struct peer_update, remote_update); cg->remote_sigs = NULL; + cg->sent_sigs = false; /* If we have an scid, we might have announcement signatures * saved in the db already. */ @@ -588,10 +902,9 @@ void channel_gossip_init(struct channel *channel, } } - if (public) - cg->state = init_public_state(channel, cg->remote_sigs); - else - cg->state = CGOSSIP_PRIVATE; + cg->state = derive_channel_state(channel); + log_debug(channel->log, "Initial channel state %s", + channel_gossip_state_str(cg->state)); check_channel_gossip(channel); } @@ -599,50 +912,13 @@ void channel_gossip_init(struct channel *channel, /* Something about channel changed: update if required */ void channel_gossip_update(struct channel *channel) { - struct lightningd *ld = channel->peer->ld; struct channel_gossip *cg = channel->channel_gossip; /* Ignore unsaved channels */ if (!cg) return; - switch (cg->state) { - case CGOSSIP_NOT_USABLE: - /* Change might make it usable */ - if (!can_send_channel_update(channel)) { - check_channel_gossip(channel); - return; - } - set_gossip_state(channel, CGOSSIP_NOT_DEEP_ENOUGH); - /* fall thru */ - case CGOSSIP_NOT_DEEP_ENOUGH: - /* Now we can send at non-forwardable update */ - send_private_cupdate(channel, false); - /* Might have gotten straight from not-usable to announceable - * if we have a flurry of blocks, or minconf >= 6. */ - if (!channel_announceable(channel, get_block_height(ld->topology))) { - check_channel_gossip(channel); - return; - } - set_gossip_state(channel, CGOSSIP_NEED_PEER_SIGS); - /* Could have actually already had sigs! */ - if (cg->state == CGOSSIP_ANNOUNCED) - goto announced; - /* fall thru */ - case CGOSSIP_PRIVATE: - case CGOSSIP_NEED_PEER_SIGS: - send_private_cupdate(channel, false); - check_channel_gossip(channel); - return; - case CGOSSIP_ANNOUNCED: - announced: - /* We don't penalize disconnected clients normally: we only - * do that if we actually try to send an htlc through */ - broadcast_public_cupdate(channel, true); - check_channel_gossip(channel); - return; - } - fatal("Bad channel_gossip_state %u", channel->channel_gossip->state); + update_gossip_state(channel); } void channel_gossip_got_announcement_sigs(struct channel *channel, @@ -656,7 +932,13 @@ void channel_gossip_got_announcement_sigs(struct channel *channel, return; } + /* Ignore the weird cases */ switch (channel->channel_gossip->state) { + case CGOSSIP_CHANNEL_DEAD: + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + return; + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: case CGOSSIP_PRIVATE: log_unusual(channel->log, "They sent an announcement_signatures message for a private channel? Ignoring."); u8 *warning = towire_warningfmt(NULL, @@ -664,35 +946,24 @@ void channel_gossip_got_announcement_sigs(struct channel *channel, "You sent announcement_signatures for private channel"); msg_to_peer(channel->peer, take(warning)); return; - case CGOSSIP_NOT_USABLE: - case CGOSSIP_NOT_DEEP_ENOUGH: - /* They're early? */ - stash_remote_announce_sigs(channel, - scid, node_sig, bitcoin_sig); - check_channel_gossip(channel); - return; - case CGOSSIP_NEED_PEER_SIGS: - stash_remote_announce_sigs(channel, - scid, node_sig, bitcoin_sig); - if (apply_remote_sigs(channel)) - set_gossip_state(channel, CGOSSIP_ANNOUNCED); - check_channel_gossip(channel); + case CGOSSIP_WAITING_FOR_SCID: + stash_remote_announce_sigs(channel, scid, node_sig, bitcoin_sig); return; case CGOSSIP_ANNOUNCED: - /* BOLT #7: - * - Upon reconnection (once the above timing requirements - * have been met): - *... - * - If it receives `announcement_signatures` for the - * funding transaction: - * - MUST respond with its own `announcement_signatures` - * message. - */ - send_channel_announce_sigs(channel); - check_channel_gossip(channel); - return; + /* We don't care what they said, but it does prompt our response */ + goto send_our_sigs; + case CGOSSIP_WAITING_FOR_USABLE: + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: + stash_remote_announce_sigs(channel, scid, node_sig, bitcoin_sig); + update_gossip_state(channel); + goto send_our_sigs; } fatal("Bad channel_gossip_state %u", channel->channel_gossip->state); + +send_our_sigs: + /* This only works once, so we won't spam them. */ + send_channel_announce_sigs(channel); } /* Short channel id changed (splice, or reorg). */ @@ -709,69 +980,41 @@ void channel_gossip_scid_changed(struct channel *channel) cg->cupdate = tal_free(cg->cupdate); /* Any announcement signatures we received for old scid are no longer - * valid. */ + * valid. We keep cg->remote_sigs though: it's common that they + * have already sent them for the new scid. */ wallet_remote_ann_sigs_clear(ld->wallet, channel); + /* Sanity check */ switch (cg->state) { - case CGOSSIP_PRIVATE: - /* Still private, just send new channel_update */ - send_private_cupdate(channel, false); - check_channel_gossip(channel); - return; - case CGOSSIP_NOT_USABLE: + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: + case CGOSSIP_WAITING_FOR_USABLE: + case CGOSSIP_WAITING_FOR_SCID: + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + case CGOSSIP_CHANNEL_DEAD: /* Shouldn't happen. */ + log_broken(channel->log, "Got scid change in state %s!", + channel_gossip_state_str(cg->state)); return; - case CGOSSIP_NOT_DEEP_ENOUGH: - case CGOSSIP_NEED_PEER_SIGS: + case CGOSSIP_PRIVATE: + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: case CGOSSIP_ANNOUNCED: - log_debug(channel->log, "channel_gossip: scid now %s", - fmt_short_channel_id(tmpctx, *channel->scid)); - /* Start again. */ - /* Maybe remote announcement signatures now apply? If not, - * free them */ - if (cg->remote_sigs - && !short_channel_id_eq(cg->remote_sigs->scid, - *channel->scid)) { - cg->remote_sigs = tal_free(cg->remote_sigs); - } - - /* Stop refresh timer, we're not announcing the old one. */ - cg->refresh_timer = tal_free(cg->refresh_timer); - - set_gossip_state(channel, - init_public_state(channel, cg->remote_sigs)); - send_channel_announce_sigs(channel); - check_channel_gossip(channel); - return; + break; } - fatal("Bad channel_gossip_state %u", cg->state); + + update_gossip_state(channel); } /* Block height changed */ static void new_blockheight(struct lightningd *ld, - struct channel *channel, - u32 block_height) + struct channel *channel) { - switch (channel->channel_gossip->state) { - case CGOSSIP_PRIVATE: - case CGOSSIP_NEED_PEER_SIGS: - case CGOSSIP_ANNOUNCED: - case CGOSSIP_NOT_USABLE: - return; - case CGOSSIP_NOT_DEEP_ENOUGH: - if (!channel_announceable(channel, block_height)) { - check_channel_gossip(channel); - return; - } - set_gossip_state(channel, CGOSSIP_NEED_PEER_SIGS); - check_channel_gossip(channel); - return; - } - fatal("Bad channel_gossip_state %u", channel->channel_gossip->state); + /* This can change state if we're CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH */ + update_gossip_state(channel); } -void channel_gossip_notify_new_block(struct lightningd *ld, - u32 block_height) +void channel_gossip_notify_new_block(struct lightningd *ld) { struct peer *peer; struct channel *channel; @@ -785,8 +1028,7 @@ void channel_gossip_notify_new_block(struct lightningd *ld, if (!channel->channel_gossip) continue; - new_blockheight(ld, channel, block_height); - check_channel_gossip(channel); + new_blockheight(ld, channel); } } } @@ -795,6 +1037,8 @@ void channel_gossip_notify_new_block(struct lightningd *ld, void channel_gossip_update_from_gossipd(struct channel *channel, const u8 *channel_update TAKES) { + struct channel_gossip *cg = channel->channel_gossip; + if (!channel->channel_gossip) { log_broken(channel->log, "gossipd gave channel_update for unsaved channel? update=%s", @@ -805,33 +1049,42 @@ void channel_gossip_update_from_gossipd(struct channel *channel, /* We might still want signatures from peer (we lost state?) */ switch (channel->channel_gossip->state) { case CGOSSIP_PRIVATE: - log_broken(channel->log, - "gossipd gave channel_update for private channel? update=%s", - tal_hex(tmpctx, channel_update)); - return; - /* This happens: we step back a block when restarting. We can - * fast-forward in this case. */ - case CGOSSIP_NOT_DEEP_ENOUGH: - set_gossip_state(channel, CGOSSIP_NEED_PEER_SIGS); - check_channel_gossip(channel); - break; - - case CGOSSIP_NOT_USABLE: - case CGOSSIP_NEED_PEER_SIGS: + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: + case CGOSSIP_WAITING_FOR_USABLE: + case CGOSSIP_CHANNEL_DEAD: + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + /* Shouldn't happen. */ if (taken(channel_update)) tal_free(channel_update); log_broken(channel->log, - "gossipd gave us channel_update for channel in gossip_state %s", - channel_gossip_state_str(channel->channel_gossip->state)); + "gossipd gave channel_update in %s? update=%s", + channel_gossip_state_str(channel->channel_gossip->state), + tal_hex(tmpctx, channel_update)); return; + + /* This happens: we step back a block when restarting. */ + case CGOSSIP_WAITING_FOR_SCID: + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: case CGOSSIP_ANNOUNCED: break; } + /* In case we generated one before gossipd told us? */ + if (cg->cupdate) { + tal_free(cg->cupdate); + cg->refresh_timer = tal_free(cg->refresh_timer); + } + /* We don't set refresh timer if we're not ANNOUNCED, we're just saving updates * for later! */ - set_public_cupdate(channel, channel_update, - channel->channel_gossip->state == CGOSSIP_ANNOUNCED); + cg->cupdate = tal_dup_talarr(cg, u8, channel_update); + if (cg->state == CGOSSIP_ANNOUNCED) { + broadcast_new_gossip(channel->peer->ld, + channel_update, NULL, "channel update"); + arm_refresh_timer(channel); + } check_channel_gossip(channel); } @@ -878,8 +1131,16 @@ void channel_gossip_init_done(struct lightningd *ld) "gossipd lost track of announced channel: re-announcing!"); check_channel_gossip(channel); send_channel_announcement(channel); + update_channel_update(channel, channel_should_enable(channel, true)); + broadcast_new_gossip(ld, channel->channel_gossip->cupdate, NULL, "channel update"); + + /* We need to refresh channel update every 13 days */ + arm_refresh_timer(channel); } } + + /* And maybe our first node_announcement */ + channel_gossip_node_announce(ld); } static void channel_reestablished_stable(struct channel *channel) @@ -905,27 +1166,34 @@ void channel_gossip_channel_reestablished(struct channel *channel) if (!channel->channel_gossip) return; + /* We can re-xmit sigs once per reconnect */ + channel->channel_gossip->sent_sigs = false; + + /* BOLT #7: + * - Upon reconnection (once the above timing requirements have + * been met): + * - If it has NOT previously received + * `announcement_signatures` for the funding transaction: + * - MUST send its own `announcement_signatures` message. + */ + /* We also always send a private channel_update, even if redundant + * (they might have lost it) */ switch (channel->channel_gossip->state) { - case CGOSSIP_NOT_USABLE: - return; - case CGOSSIP_PRIVATE: - case CGOSSIP_NOT_DEEP_ENOUGH: - send_private_cupdate(channel, true); + case CGOSSIP_CHANNEL_DEAD: + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + case CGOSSIP_ANNOUNCED: + case CGOSSIP_WAITING_FOR_USABLE: + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: check_channel_gossip(channel); return; - case CGOSSIP_NEED_PEER_SIGS: - /* BOLT #7: - * - Upon reconnection (once the above timing requirements have - * been met): - * - If it has NOT previously received - * `announcement_signatures` for the funding transaction: - * - MUST send its own `announcement_signatures` message. - */ - send_private_cupdate(channel, true); + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: send_channel_announce_sigs(channel); - check_channel_gossip(channel); - return; - case CGOSSIP_ANNOUNCED: + /* fall thru */ + case CGOSSIP_PRIVATE: + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: + case CGOSSIP_WAITING_FOR_SCID: + send_private_cupdate(channel, true); check_channel_gossip(channel); return; } @@ -947,13 +1215,24 @@ const u8 *channel_gossip_update_for_error(const tal_t *ctx, struct channel_gossip *cg = channel->channel_gossip; switch (cg->state) { + case CGOSSIP_CHANNEL_DEAD: + case CGOSSIP_PRIVATE_WAITING_FOR_USABLE: case CGOSSIP_PRIVATE: - case CGOSSIP_NOT_USABLE: - case CGOSSIP_NOT_DEEP_ENOUGH: - case CGOSSIP_NEED_PEER_SIGS: + case CGOSSIP_WAITING_FOR_USABLE: + case CGOSSIP_WAITING_FOR_SCID: + case CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS: + case CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH: return NULL; + case CGOSSIP_CHANNEL_ANNOUNCED_DYING: + case CGOSSIP_CHANNEL_ANNOUNCED_DEAD: + return cg->cupdate; case CGOSSIP_ANNOUNCED: - broadcast_public_cupdate(channel, false); + /* At this point we actually disable disconnected peers. */ + if (update_channel_update(channel, channel_should_enable(channel, false))) { + broadcast_new_gossip(channel->peer->ld, + cg->cupdate, NULL, + "channel update"); + } check_channel_gossip(channel); return cg->cupdate; } @@ -1024,7 +1303,7 @@ void channel_gossip_set_remote_update(struct lightningd *ld, /* For public channels, it could come from anywhere. Private * channels must come from gossipd itself (the old store * migration!) or the correct peer. */ - if (cg->state == CGOSSIP_PRIVATE + if (is_private(channel) && source && !node_id_eq(source, &channel->peer->id)) { log_unusual(ld->log, "Bad gossip order: %s sent us a channel update for a " diff --git a/lightningd/channel_gossip.h b/lightningd/channel_gossip.h index 0a81089dea14..6b8e4e203262 100644 --- a/lightningd/channel_gossip.h +++ b/lightningd/channel_gossip.h @@ -23,8 +23,7 @@ void channel_gossip_update(struct channel *channel); void channel_gossip_scid_changed(struct channel *channel); /* Block height changed */ -void channel_gossip_notify_new_block(struct lightningd *ld, - u32 block_height); +void channel_gossip_notify_new_block(struct lightningd *ld); /* Got announcement_signatures from peer */ void channel_gossip_got_announcement_sigs(struct channel *channel, diff --git a/lightningd/coin_mvts.c b/lightningd/coin_mvts.c index 74f940384fa5..df91cabb6a1b 100644 --- a/lightningd/coin_mvts.c +++ b/lightningd/coin_mvts.c @@ -103,7 +103,7 @@ static bool report_chan_balance(const struct channel *chan) abort(); } -void send_account_balance_snapshot(struct lightningd *ld, u32 blockheight) +void send_account_balance_snapshot(struct lightningd *ld) { struct balance_snapshot *snap = tal(NULL, struct balance_snapshot); struct account_balance *bal; @@ -112,7 +112,7 @@ void send_account_balance_snapshot(struct lightningd *ld, u32 blockheight) struct peer *p; struct peer_node_id_map_iter it; - snap->blockheight = blockheight; + snap->blockheight = get_block_height(ld->topology); snap->timestamp = time_now().ts.tv_sec; snap->node_id = &ld->our_nodeid; diff --git a/lightningd/coin_mvts.h b/lightningd/coin_mvts.h index 70ce9aa6c4d6..90db53178c74 100644 --- a/lightningd/coin_mvts.h +++ b/lightningd/coin_mvts.h @@ -36,5 +36,5 @@ struct channel_coin_mvt *new_channel_mvt_routed_hout(const tal_t *ctx, struct htlc_out *hout, struct channel *channel); -void send_account_balance_snapshot(struct lightningd *ld, u32 blockheight); +void send_account_balance_snapshot(struct lightningd *ld); #endif /* LIGHTNING_LIGHTNINGD_COIN_MVTS_H */ diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 49c3d844da4d..7c3de2ae8eed 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -4122,7 +4122,7 @@ bool peer_start_dualopend(struct peer *peer, * funding transaction. */ /* FIXME: We should override this to 0 in the openchannel2 hook of we want zeroconf*/ - channel->minimum_depth = peer->ld->config.anchor_confirms; + channel->minimum_depth = peer->ld->config.funding_confirms; msg = towire_dualopend_init(NULL, chainparams, peer->ld->our_features, diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index e22bd1083f1e..a4e8477a98ca 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -255,8 +255,10 @@ static void gossipd_new_blockheight_reply(struct subd *gossipd, gossipd->ld->gossip_blockheight); } -void gossip_notify_new_block(struct lightningd *ld, u32 blockheight) +void gossip_notify_new_block(struct lightningd *ld) { + u32 blockheight = get_block_height(ld->topology); + /* Only notify gossipd once we're synced. */ if (!topology_synced(ld->topology)) return; @@ -269,7 +271,7 @@ void gossip_notify_new_block(struct lightningd *ld, u32 blockheight) static void gossip_topology_synced(struct chain_topology *topo, void *unused) { /* Now we start telling gossipd about blocks. */ - gossip_notify_new_block(topo->ld, get_block_height(topo)); + gossip_notify_new_block(topo->ld); } /* We make sure gossipd is started before plugins (which may want gossip_map) */ diff --git a/lightningd/gossip_control.h b/lightningd/gossip_control.h index cc9827b056a2..06a248799dfd 100644 --- a/lightningd/gossip_control.h +++ b/lightningd/gossip_control.h @@ -14,6 +14,6 @@ void gossipd_notify_spends(struct lightningd *ld, u32 blockheight, const struct short_channel_id *scids); -void gossip_notify_new_block(struct lightningd *ld, u32 blockheight); +void gossip_notify_new_block(struct lightningd *ld); #endif /* LIGHTNING_LIGHTNINGD_GOSSIP_CONTROL_H */ diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index accd93ec6bdd..524de213cd05 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -768,14 +768,14 @@ static int io_poll_lightningd(struct pollfd *fds, nfds_t nfds, int timeout) * like this, and it's always better to have compile-time calls than runtime, * as it makes the code more explicit. But pasting in direct calls is also an * abstraction violation, so we use this middleman function. */ -void notify_new_block(struct lightningd *ld, u32 block_height) +void notify_new_block(struct lightningd *ld) { /* Inform our subcomponents individually. */ - htlcs_notify_new_block(ld, block_height); - channel_notify_new_block(ld, block_height); - channel_gossip_notify_new_block(ld, block_height); - gossip_notify_new_block(ld, block_height); - waitblockheight_notify_new_block(ld, block_height); + htlcs_notify_new_block(ld); + channel_notify_new_block(ld); + channel_gossip_notify_new_block(ld); + gossip_notify_new_block(ld); + waitblockheight_notify_new_block(ld); } static void on_sigint(int _ UNUSED) diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index 2f562f6c2f41..7fd07a274d42 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -21,8 +21,8 @@ struct config { /* How long do we let them lock up our funds? (blocks: 2016 by spec) */ u32 max_htlc_cltv; - /* How many confirms until we consider an anchor "settled". */ - u32 anchor_confirms; + /* How many confirms until we consider a funding tx "settled". */ + u32 funding_confirms; /* Minimum CLTV to subtract from incoming HTLCs to outgoing */ u32 cltv_expiry_delta; @@ -439,7 +439,7 @@ const char *subdaemon_path(const tal_t *ctx, const struct lightningd *ld, const void test_subdaemons(const struct lightningd *ld); /* Notify lightningd about new blocks. */ -void notify_new_block(struct lightningd *ld, u32 block_height); +void notify_new_block(struct lightningd *ld); /* Signal a clean exit from lightningd. * NOTE! This function **returns**. diff --git a/lightningd/opening_common.c b/lightningd/opening_common.c index 7576d6149b97..79f7867c5733 100644 --- a/lightningd/opening_common.c +++ b/lightningd/opening_common.c @@ -62,7 +62,7 @@ new_uncommitted_channel(struct peer *peer) * funding transaction. */ /* We override this in openchannel hook if we want zeroconf */ - uc->minimum_depth = ld->config.anchor_confirms; + uc->minimum_depth = ld->config.funding_confirms; /* Use default 1% reserve if not otherwise specified. If this * is not-NULL it will be used by openingd as absolute value diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 333410d9055b..36008a8f2cfd 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -1294,7 +1294,7 @@ static struct command_result *json_fundchannel_start(struct command *cmd, } if (!mindepth) - mindepth = tal_dup(cmd, u32, &cmd->ld->config.anchor_confirms); + mindepth = tal_dup(cmd, u32, &cmd->ld->config.funding_confirms); if (push_msat && amount_msat_greater_sat(*push_msat, *amount)) return command_fail(cmd, FUND_CANNOT_AFFORD, diff --git a/lightningd/options.c b/lightningd/options.c index 767d03a5d25b..781123dc6bd4 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -957,7 +957,7 @@ static const struct config testnet_config = { .max_htlc_cltv = 2016, /* We're fairly trusting, under normal circumstances. */ - .anchor_confirms = 1, + .funding_confirms = 1, /* Testnet blockspace is free. */ .max_concurrent_htlcs = 483, @@ -1025,7 +1025,7 @@ static const struct config mainnet_config = { .max_htlc_cltv = 2016, /* We're fairly trusting, under normal circumstances. */ - .anchor_confirms = 3, + .funding_confirms = 3, /* While up to 483 htlcs are possible we do 30 by default (as eclair does) to save blockspace */ .max_concurrent_htlcs = 30, @@ -1099,8 +1099,8 @@ static void check_config(struct lightningd *ld) if (ld->config.max_concurrent_htlcs < 1 || ld->config.max_concurrent_htlcs > 483) fatal("--max-concurrent-htlcs value must be between 1 and 483 it is: %u", ld->config.max_concurrent_htlcs); - if (ld->config.anchor_confirms == 0) - fatal("anchor-confirms must be greater than zero"); + if (ld->config.funding_confirms == 0) + fatal("funding-confirms must be greater than zero"); if (ld->always_use_proxy && !ld->proxyaddr) fatal("--always-use-proxy needs --proxy"); @@ -1497,7 +1497,7 @@ static void register_opts(struct lightningd *ld) opt_register_arg("--max-locktime-blocks", opt_set_max_htlc_cltv, NULL, ld, opt_hidden); clnopt_witharg("--funding-confirms", OPT_SHOWINT, opt_set_u32, opt_show_u32, - &ld->config.anchor_confirms, + &ld->config.funding_confirms, "Confirmations required for funding transaction"); clnopt_witharg("--require-confirmed-inputs", OPT_SHOWBOOL, opt_set_bool_arg, opt_show_bool, diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 75eac3fc7a7d..2190f0d71aa3 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2912,9 +2912,9 @@ timeout_waitblockheight_waiter(struct waitblockheight_waiter *w) "Timed out.")); } /* Called by lightningd at each new block. */ -void waitblockheight_notify_new_block(struct lightningd *ld, - u32 block_height) +void waitblockheight_notify_new_block(struct lightningd *ld) { + u32 block_height = get_block_height(ld->topology); struct waitblockheight_waiter *w, *n; char *to_delete = tal(NULL, char); @@ -2929,8 +2929,7 @@ void waitblockheight_notify_new_block(struct lightningd *ld, list_del(&w->list); w->removed = true; tal_steal(to_delete, w); - was_pending(waitblockheight_complete(w->cmd, - block_height)); + was_pending(waitblockheight_complete(w->cmd, block_height)); } tal_free(to_delete); } diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 88a5f8866759..88d769e4bb77 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -154,8 +154,7 @@ struct leak_detect; void peer_dev_memleak(struct lightningd *ld, struct leak_detect *leaks); /* Triggered at each new block. */ -void waitblockheight_notify_new_block(struct lightningd *ld, - u32 block_height); +void waitblockheight_notify_new_block(struct lightningd *ld); /* JSON parameter by channel_id or scid (caller must check state!) */ diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 8bfb9afa42f1..a91fce7fd9a1 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -2791,9 +2791,10 @@ static void consider_failing_incoming(struct lightningd *ld, local_fail_in_htlc(hout->in, take(towire_permanent_channel_failure(NULL))); } -void htlcs_notify_new_block(struct lightningd *ld, u32 height) +void htlcs_notify_new_block(struct lightningd *ld) { bool removed; + u32 height = get_block_height(ld->topology); /* BOLT #2: * diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index 9b9e67255b74..edd9e3cffe30 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -46,7 +46,7 @@ void onchain_failed_our_htlc(const struct channel *channel, void onchain_fulfilled_htlc(struct channel *channel, const struct preimage *preimage); -void htlcs_notify_new_block(struct lightningd *ld, u32 height); +void htlcs_notify_new_block(struct lightningd *ld); /* Only defined if COMPAT_V061 */ void fixup_htlcs_out(struct lightningd *ld); diff --git a/lightningd/test/run-find_my_abspath.c b/lightningd/test/run-find_my_abspath.c index 2e5c3332cd5a..b8eb2743281f 100644 --- a/lightningd/test/run-find_my_abspath.c +++ b/lightningd/test/run-find_my_abspath.c @@ -11,12 +11,10 @@ int unused_main(int argc, char *argv[]); void begin_topology(struct chain_topology *topo UNNEEDED) { fprintf(stderr, "begin_topology called!\n"); abort(); } /* Generated stub for channel_gossip_notify_new_block */ -void channel_gossip_notify_new_block(struct lightningd *ld UNNEEDED, - u32 block_height UNNEEDED) +void channel_gossip_notify_new_block(struct lightningd *ld UNNEEDED) { fprintf(stderr, "channel_gossip_notify_new_block called!\n"); abort(); } /* Generated stub for channel_notify_new_block */ -void channel_notify_new_block(struct lightningd *ld UNNEEDED, - u32 block_height UNNEEDED) +void channel_notify_new_block(struct lightningd *ld UNNEEDED) { fprintf(stderr, "channel_notify_new_block called!\n"); abort(); } /* Generated stub for connectd_activate */ void connectd_activate(struct lightningd *ld UNNEEDED) @@ -112,7 +110,7 @@ bool fromwire_status_version(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, void gossip_init(struct lightningd *ld UNNEEDED, int connectd_fd UNNEEDED) { fprintf(stderr, "gossip_init called!\n"); abort(); } /* Generated stub for gossip_notify_new_block */ -void gossip_notify_new_block(struct lightningd *ld UNNEEDED, u32 blockheight UNNEEDED) +void gossip_notify_new_block(struct lightningd *ld UNNEEDED) { fprintf(stderr, "gossip_notify_new_block called!\n"); abort(); } /* Generated stub for handle_early_opts */ void handle_early_opts(struct lightningd *ld UNNEEDED, int argc UNNEEDED, char *argv[]) @@ -127,7 +125,7 @@ size_t hash_htlc_key(const struct htlc_key *htlc_key UNNEEDED) struct ext_key *hsm_init(struct lightningd *ld UNNEEDED) { fprintf(stderr, "hsm_init called!\n"); abort(); } /* Generated stub for htlcs_notify_new_block */ -void htlcs_notify_new_block(struct lightningd *ld UNNEEDED, u32 height UNNEEDED) +void htlcs_notify_new_block(struct lightningd *ld UNNEEDED) { fprintf(stderr, "htlcs_notify_new_block called!\n"); abort(); } /* Generated stub for htlcs_resubmit */ void htlcs_resubmit(struct lightningd *ld UNNEEDED, @@ -283,8 +281,7 @@ struct txfilter *txfilter_new(const tal_t *ctx UNNEEDED) const char *version(void) { fprintf(stderr, "version called!\n"); abort(); } /* Generated stub for waitblockheight_notify_new_block */ -void waitblockheight_notify_new_block(struct lightningd *ld UNNEEDED, - u32 block_height UNNEEDED) +void waitblockheight_notify_new_block(struct lightningd *ld UNNEEDED) { fprintf(stderr, "waitblockheight_notify_new_block called!\n"); abort(); } /* Generated stub for wallet_new */ struct wallet *wallet_new(struct lightningd *ld UNNEEDED, struct timers *timers UNNEEDED) diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 195db8a2cfc7..5c1300c67d6a 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -907,10 +907,6 @@ bool peer_start_channeld(struct channel *channel UNNEEDED, bool reconnected UNNEEDED, bool reestablish_only UNNEEDED) { fprintf(stderr, "peer_start_channeld called!\n"); abort(); } -/* Generated stub for peer_start_closingd */ -void peer_start_closingd(struct channel *channel UNNEEDED, - struct peer_fd *peer_fd UNNEEDED) -{ fprintf(stderr, "peer_start_closingd called!\n"); abort(); } /* Generated stub for peer_start_dualopend */ bool peer_start_dualopend(struct peer *peer UNNEEDED, struct peer_fd *peer_fd UNNEEDED, struct channel *channel UNNEEDED) diff --git a/tests/test_gossip.py b/tests/test_gossip.py index cda6c4e98aae..43ef9f79362c 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -393,8 +393,9 @@ def test_connect_by_gossip(node_factory, bitcoind): def test_gossip_jsonrpc(node_factory): l1, l2 = node_factory.line_graph(2, fundchannel=True, wait_for_announce=False) - # Shouldn't send announce signatures until 6 deep. - assert not l1.daemon.is_in_log('peer_out WIRE_ANNOUNCEMENT_SIGNATURES') + # We will exchange announcement signatures immediately. + l1.daemon.wait_for_logs(['peer_out WIRE_ANNOUNCEMENT_SIGNATURES', + 'peer_in WIRE_ANNOUNCEMENT_SIGNATURES']) # Make sure we can route through the channel, will raise on failure l1.rpc.getroute(l2.info['id'], 100, 1) @@ -412,9 +413,6 @@ def test_gossip_jsonrpc(node_factory): # Now proceed to funding-depth and do a full gossip round l1.bitcoin.generate_block(5) - # Could happen in either order. - l1.daemon.wait_for_logs(['peer_out WIRE_ANNOUNCEMENT_SIGNATURES', - 'peer_in WIRE_ANNOUNCEMENT_SIGNATURES']) # Just wait for the update to kick off and then check the effect needle = "Received node_announcement for node" diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 82be3f8babe2..22844c62b947 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -363,9 +363,6 @@ bool fromwire_tlv(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *record UNNEEDED, struct tlv_field **fields UNNEEDED, const u64 *extra_types UNNEEDED, size_t *err_off UNNEEDED, u64 *err_type UNNEEDED) { fprintf(stderr, "fromwire_tlv 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_network_blockheight */ u32 get_network_blockheight(const struct chain_topology *topo UNNEEDED) { fprintf(stderr, "get_network_blockheight called!\n"); abort(); } @@ -929,10 +926,6 @@ bool peer_start_channeld(struct channel *channel UNNEEDED, bool reconnected UNNEEDED, bool reestablish_only UNNEEDED) { fprintf(stderr, "peer_start_channeld called!\n"); abort(); } -/* Generated stub for peer_start_closingd */ -void peer_start_closingd(struct channel *channel UNNEEDED, - struct peer_fd *peer_fd UNNEEDED) -{ fprintf(stderr, "peer_start_closingd called!\n"); abort(); } /* Generated stub for peer_start_dualopend */ bool peer_start_dualopend(struct peer *peer UNNEEDED, struct peer_fd *peer_fd UNNEEDED, struct channel *channel UNNEEDED) @@ -1304,6 +1297,12 @@ void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *scrip tal_free(script); } +/* Can actually be called by new_channel */ +u32 get_block_height(const struct chain_topology *topo UNNEEDED) +{ + return 0; +} + /** * mempat -- Set the memory to a pattern *