close: Do not publish unilateral when witnessing a close onchain

Changelog-Changed: close: We no longer attempt to publish a unilateral close that'd fail anyway when we witness a close onchain.
This commit is contained in:
Christian Decker 2024-07-02 16:50:26 +02:00
parent 76ad48cd1b
commit 6c972cdb32
4 changed files with 35 additions and 9 deletions

View File

@ -902,13 +902,19 @@ void channel_fail_permanent(struct channel *channel,
struct lightningd *ld = channel->peer->ld;
va_list ap;
char *why;
/* Do we want to rebroadcast close transactions? If we're
* witnessing the close on-chain there is no point in doing
* this. */
bool rebroadcast;
va_start(ap, fmt);
why = tal_vfmt(tmpctx, fmt, ap);
va_end(ap);
log_unusual(channel->log, "Peer permanent failure in %s: %s",
channel_state_name(channel), why);
log_unusual(channel->log,
"Peer permanent failure in %s: %s (reason=%s)",
channel_state_name(channel), why,
channel_change_state_reason_str(reason));
/* We can have multiple errors, eg. onchaind failures. */
if (!channel->error)
@ -916,8 +922,15 @@ void channel_fail_permanent(struct channel *channel,
&channel->cid, "%s", why);
channel_set_owner(channel, NULL);
/* Drop non-cooperatively (unilateral) to chain. */
drop_to_chain(ld, channel, false);
/* Drop non-cooperatively (unilateral) to chain. If we detect
* the close from the blockchain (i.e., reason is
* REASON_ONCHAIN, or FUNDING_SPEND_SEEN) then we can observe
* passively, and not broadcast our own unilateral close, as
* it doesn't stand a chance anyway. */
rebroadcast = !(channel->state == ONCHAIN ||
channel->state == FUNDING_SPEND_SEEN);
drop_to_chain(ld, channel, false, rebroadcast);
if (channel_state_wants_onchain_fail(channel->state))
channel_set_state(channel,

View File

@ -303,7 +303,7 @@ static void peer_closing_complete(struct channel *channel, const u8 *msg)
return;
/* Channel gets dropped to chain cooperatively. */
drop_to_chain(channel->peer->ld, channel, true);
drop_to_chain(channel->peer->ld, channel, true, true /* rebroadcast */);
channel_set_state(channel,
CLOSINGD_SIGEXCHANGE,
CLOSINGD_COMPLETE,

View File

@ -348,7 +348,7 @@ static enum watch_result closed_inflight_depth_cb(struct lightningd *ld,
}
void drop_to_chain(struct lightningd *ld, struct channel *channel,
bool cooperative)
bool cooperative, bool rebroadcast)
{
struct channel_inflight *inflight;
const char *cmd_id;
@ -387,6 +387,10 @@ void drop_to_chain(struct lightningd *ld, struct channel *channel,
log_broken(channel->log,
"Cannot broadcast our commitment tx:"
" it's invalid! (ancient channel?)");
} else if (!rebroadcast && !cooperative) {
log_unusual(channel->log,
"Not dropping our unilateral close onchain since "
"we already saw theirs confirm.");
} else {
struct bitcoin_tx *tx COMPILER_WANTS_INIT("gcc 12.3.0");
@ -448,10 +452,10 @@ void resend_closing_transactions(struct lightningd *ld)
case CLOSED:
continue;
case CLOSINGD_COMPLETE:
drop_to_chain(ld, channel, true);
drop_to_chain(ld, channel, true, true);
continue;
case AWAITING_UNILATERAL:
drop_to_chain(ld, channel, false);
drop_to_chain(ld, channel, false, true);
continue;
}
abort();

View File

@ -109,7 +109,16 @@ void peer_set_dbid(struct peer *peer, u64 dbid);
/* At startup, re-send any transactions we want bitcoind to have */
void resend_closing_transactions(struct lightningd *ld);
void drop_to_chain(struct lightningd *ld, struct channel *channel, bool cooperative);
/**
* Initiate the close of a channel.
*
* @param rebroadcast: Whether we should be broadcasting our
* commitment transaction in order to close the channel, or not.
*/
void drop_to_chain(struct lightningd *ld,
struct channel *channel,
bool cooperative,
bool rebroadcast);
void update_channel_from_inflight(struct lightningd *ld,
struct channel *channel,