mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 18:57:06 +01:00
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:
parent
727d7e9493
commit
5f1ba02ece
1 changed files with 43 additions and 21 deletions
|
@ -180,17 +180,19 @@ 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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue