lightningd: funding_lockin_cb, handle reorgs that change short_channel_id

Keep watching and updating scid until ANNOUNCE_MIN_DEPTH, even when channel is private.
When scid changes, we fail channeld so it will restart and initialize with updated
scid and add it to rtable. Reorgs can change funding tx's height/index after lockin,
which could happen with small minimum_depth=1.
This commit is contained in:
Simon Vrouwe 2019-04-30 19:10:15 +03:00 committed by Christian Decker
parent 7726681aa6
commit 8c1bbf33e5
1 changed files with 26 additions and 21 deletions

View File

@ -843,21 +843,22 @@ static enum watch_result funding_depth_cb(struct lightningd *ld,
unsigned int depth) unsigned int depth)
{ {
const char *txidstr; const char *txidstr;
struct short_channel_id scid;
txidstr = type_to_string(tmpctx, struct bitcoin_txid, txid); txidstr = type_to_string(tmpctx, struct bitcoin_txid, txid);
log_debug(channel->log, "Funding tx %s depth %u of %u", log_debug(channel->log, "Funding tx %s depth %u of %u",
txidstr, depth, channel->minimum_depth); txidstr, depth, channel->minimum_depth);
tal_free(txidstr); tal_free(txidstr);
bool local_locked = depth >= channel->minimum_depth; bool min_depth_reached = depth >= channel->minimum_depth;
/* If we restart, we could already have peer->scid from database */ /* Reorg can change scid, so always update/save scid when possible (depth=0
if (local_locked && !channel->scid) { * means the stale block with our funding tx was removed) */
if ((min_depth_reached && !channel->scid) || (depth && channel->scid)) {
struct txlocator *loc; struct txlocator *loc;
loc = wallet_transaction_locate(tmpctx, ld->wallet, txid); loc = wallet_transaction_locate(tmpctx, ld->wallet, txid);
channel->scid = tal(channel, struct short_channel_id); if (!mk_short_channel_id(&scid,
if (!mk_short_channel_id(channel->scid,
loc->blkheight, loc->index, loc->blkheight, loc->index,
channel->funding_outnum)) { channel->funding_outnum)) {
channel_fail_permanent(channel, "Invalid funding scid %u:%u:%u", channel_fail_permanent(channel, "Invalid funding scid %u:%u:%u",
@ -866,30 +867,34 @@ static enum watch_result funding_depth_cb(struct lightningd *ld,
return DELETE_WATCH; return DELETE_WATCH;
} }
/* We've added scid, update */ /* If we restart, we could already have peer->scid from database */
wallet_channel_save(ld->wallet, channel); if (!channel->scid) {
channel->scid = tal(channel, struct short_channel_id);
*channel->scid = scid;
wallet_channel_save(ld->wallet, channel);
} else if (!short_channel_id_eq(channel->scid, &scid)) {
/* This normally restarts channeld, initialized with updated scid
* and also adds it (at least our halve_chan) to rtable. */
channel_fail_transient(channel,
"short_channel_id changed to %s (was %s)",
short_channel_id_to_str(tmpctx, &scid),
short_channel_id_to_str(tmpctx, channel->scid));
*channel->scid = scid;
wallet_channel_save(ld->wallet, channel);
return KEEP_WATCHING;
}
} }
/* Try to tell subdaemon */ /* Try to tell subdaemon */
if (!channel_tell_depth(ld, channel, txid, depth)) if (!channel_tell_depth(ld, channel, txid, depth))
return KEEP_WATCHING; return KEEP_WATCHING;
if (!local_locked) if (!min_depth_reached)
return KEEP_WATCHING; return KEEP_WATCHING;
/* BOLT #7:
*
* A node:
* - if the `open_channel` message has the `announce_channel` bit set AND a `shutdown` message has not been sent:
* - MUST send the `announcement_signatures` message.
* - MUST NOT send `announcement_signatures` messages until `funding_locked`
* has been sent and received AND the funding transaction has at least six confirmations.
* - otherwise:
* - MUST NOT send the `announcement_signatures` message.
*/
if (!(channel->channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL))
return DELETE_WATCH;
/* We keep telling it depth until we get to announce depth. */ /* We keep telling it depth/scid until we get to announce depth. */
if (depth < ANNOUNCE_MIN_DEPTH) if (depth < ANNOUNCE_MIN_DEPTH)
return KEEP_WATCHING; return KEEP_WATCHING;