rbf: on close, drop every inflight transaction's commitment

If it's a unilateral close, we need to drop all the inflights also,
as we don't know which of them ended up being mined.
This commit is contained in:
niftynei 2021-05-19 19:09:56 -05:00 committed by Rusty Russell
parent 727d7e9493
commit 5f1ba02ece

View file

@ -180,19 +180,21 @@ u8 *p2wpkh_for_keyidx(const tal_t *ctx, struct lightningd *ld, u64 keyidx)
return scriptpubkey_p2wpkh(ctx, &shutdownkey); return scriptpubkey_p2wpkh(ctx, &shutdownkey);
} }
static void sign_last_tx(struct channel *channel) static void sign_last_tx(struct channel *channel,
struct bitcoin_tx *last_tx,
struct bitcoin_signature *last_sig)
{ {
struct lightningd *ld = channel->peer->ld; struct lightningd *ld = channel->peer->ld;
struct bitcoin_signature sig; struct bitcoin_signature sig;
u8 *msg, **witness; u8 *msg, **witness;
assert(!channel->last_tx->wtx->inputs[0].witness); assert(!last_tx->wtx->inputs[0].witness);
msg = towire_hsmd_sign_commitment_tx(tmpctx, msg = towire_hsmd_sign_commitment_tx(tmpctx,
&channel->peer->id, &channel->peer->id,
channel->dbid, channel->dbid,
channel->last_tx, last_tx,
&channel->channel_info &channel->channel_info
.remote_fundingkey); .remote_fundingkey);
if (!wire_sync_write(ld->hsm_fd, take(msg))) if (!wire_sync_write(ld->hsm_fd, take(msg)))
fatal("Could not write to HSM: %s", strerror(errno)); fatal("Could not write to HSM: %s", strerror(errno));
@ -203,11 +205,11 @@ static void sign_last_tx(struct channel *channel)
tal_hex(tmpctx, msg)); tal_hex(tmpctx, msg));
witness = witness =
bitcoin_witness_2of2(channel->last_tx, &channel->last_sig, bitcoin_witness_2of2(last_tx, last_sig,
&sig, &channel->channel_info.remote_fundingkey, &sig, &channel->channel_info.remote_fundingkey,
&channel->local_funding_pubkey); &channel->local_funding_pubkey);
bitcoin_tx_input_set_witness(channel->last_tx, 0, take(witness)); bitcoin_tx_input_set_witness(last_tx, 0, take(witness));
} }
static void remove_sig(struct bitcoin_tx *signed_tx) static void remove_sig(struct bitcoin_tx *signed_tx)
@ -337,10 +339,31 @@ static bool invalid_last_tx(const struct bitcoin_tx *tx)
#endif #endif
} }
static void sign_and_send_last(struct lightningd *ld,
struct channel *channel,
struct bitcoin_tx *last_tx,
struct bitcoin_signature *last_sig)
{
struct bitcoin_txid txid;
sign_last_tx(channel, last_tx, last_sig);
bitcoin_txid(last_tx, &txid);
wallet_transaction_add(ld->wallet, last_tx->wtx, 0, 0);
wallet_transaction_annotate(ld->wallet, &txid,
channel->last_tx_type,
channel->dbid);
/* Keep broadcasting until we say stop (can fail due to dup,
* if they beat us to the broadcast). */
broadcast_tx(ld->topology, channel, last_tx, NULL);
remove_sig(last_tx);
}
void drop_to_chain(struct lightningd *ld, struct channel *channel, void drop_to_chain(struct lightningd *ld, struct channel *channel,
bool cooperative) bool cooperative)
{ {
struct bitcoin_txid txid; struct channel_inflight *inflight;
/* BOLT #2: /* BOLT #2:
* *
* - if `next_revocation_number` is greater than expected * - if `next_revocation_number` is greater than expected
@ -357,16 +380,15 @@ void drop_to_chain(struct lightningd *ld, struct channel *channel,
"Cannot broadcast our commitment tx:" "Cannot broadcast our commitment tx:"
" it's invalid! (ancient channel?)"); " it's invalid! (ancient channel?)");
} else { } else {
sign_last_tx(channel); /* We need to drop *every* commitment transaction to chain */
bitcoin_txid(channel->last_tx, &txid); if (!cooperative && !list_empty(&channel->inflights)) {
wallet_transaction_add(ld->wallet, channel->last_tx->wtx, 0, 0); list_for_each(&channel->inflights, inflight, list)
wallet_transaction_annotate(ld->wallet, &txid, channel->last_tx_type, channel->dbid); sign_and_send_last(ld, channel,
inflight->last_tx,
/* Keep broadcasting until we say stop (can fail due to dup, &inflight->last_sig);
* if they beat us to the broadcast). */ } else
broadcast_tx(ld->topology, channel, channel->last_tx, NULL); sign_and_send_last(ld, channel, channel->last_tx,
&channel->last_sig);
remove_sig(channel->last_tx);
} }
resolve_close_command(ld, channel, cooperative); resolve_close_command(ld, channel, cooperative);
@ -2286,7 +2308,7 @@ static struct command_result *json_sign_last_tx(struct command *cmd,
log_debug(channel->log, "dev-sign-last-tx: signing tx with %zu outputs", log_debug(channel->log, "dev-sign-last-tx: signing tx with %zu outputs",
channel->last_tx->wtx->num_outputs); channel->last_tx->wtx->num_outputs);
sign_last_tx(channel); sign_last_tx(channel, channel->last_tx, &channel->last_sig);
json_add_tx(response, "tx", channel->last_tx); json_add_tx(response, "tx", channel->last_tx);
remove_sig(channel->last_tx); remove_sig(channel->last_tx);