mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
df: revert channel state in dualopend
Now that RBF's are possible, we revert the channel's state after a failure to the previous channel info.
This commit is contained in:
parent
cf170c3909
commit
fe688ab718
@ -1467,6 +1467,48 @@ static bool run_tx_interactive(struct state *state,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there's a failure, we reset the state to the last
|
||||||
|
* valid channel */
|
||||||
|
static void revert_channel_state(struct state *state)
|
||||||
|
{
|
||||||
|
struct tx_state *tx_state = state->tx_state;
|
||||||
|
struct amount_sat total;
|
||||||
|
struct amount_msat our_msats;
|
||||||
|
enum side opener = state->our_role == TX_INITIATOR ? LOCAL : REMOTE;
|
||||||
|
|
||||||
|
/* We've already checked this */
|
||||||
|
if (!amount_sat_add(&total, tx_state->opener_funding,
|
||||||
|
tx_state->accepter_funding))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
/* We've already checked this */
|
||||||
|
if (!amount_sat_to_msat(&our_msats,
|
||||||
|
state->our_role == TX_INITIATOR ?
|
||||||
|
tx_state->opener_funding :
|
||||||
|
tx_state->accepter_funding))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
tal_free(state->channel);
|
||||||
|
state->channel = new_initial_channel(state,
|
||||||
|
&state->channel_id,
|
||||||
|
&tx_state->funding_txid,
|
||||||
|
tx_state->funding_txout,
|
||||||
|
state->minimum_depth,
|
||||||
|
total,
|
||||||
|
our_msats,
|
||||||
|
take(new_fee_states(
|
||||||
|
NULL, opener,
|
||||||
|
&state->feerate_per_kw_commitment)),
|
||||||
|
&tx_state->localconf,
|
||||||
|
&tx_state->remoteconf,
|
||||||
|
&state->our_points,
|
||||||
|
&state->their_points,
|
||||||
|
&state->our_funding_pubkey,
|
||||||
|
&state->their_funding_pubkey,
|
||||||
|
true, true,
|
||||||
|
opener);
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns NULL on negotation failure; reason given as *err_reason
|
/* Returns NULL on negotation failure; reason given as *err_reason
|
||||||
* In case that negotiation_aborted called, *err_reason set NULL */
|
* In case that negotiation_aborted called, *err_reason set NULL */
|
||||||
static u8 *accepter_commits(struct state *state,
|
static u8 *accepter_commits(struct state *state,
|
||||||
@ -1544,6 +1586,9 @@ static u8 *accepter_commits(struct state *state,
|
|||||||
"Overflow converting accepter_funding "
|
"Overflow converting accepter_funding "
|
||||||
"to msats");
|
"to msats");
|
||||||
|
|
||||||
|
if (state->channel)
|
||||||
|
state->channel = tal_free(state->channel);
|
||||||
|
|
||||||
state->channel = new_initial_channel(state,
|
state->channel = new_initial_channel(state,
|
||||||
&state->channel_id,
|
&state->channel_id,
|
||||||
&tx_state->funding_txid,
|
&tx_state->funding_txid,
|
||||||
@ -1571,6 +1616,7 @@ static u8 *accepter_commits(struct state *state,
|
|||||||
if (!local_commit) {
|
if (!local_commit) {
|
||||||
*err_reason = tal_fmt(tmpctx, "Could not meet our fees"
|
*err_reason = tal_fmt(tmpctx, "Could not meet our fees"
|
||||||
" and reserve: %s", error);
|
" and reserve: %s", error);
|
||||||
|
revert_channel_state(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1596,21 +1642,27 @@ static u8 *accepter_commits(struct state *state,
|
|||||||
* a courtesy to other implementaters whose brains may be so
|
* a courtesy to other implementaters whose brains may be so
|
||||||
* twisted by coding in Go, Scala and Rust that they can no
|
* twisted by coding in Go, Scala and Rust that they can no
|
||||||
* longer read C code. */
|
* longer read C code. */
|
||||||
peer_failed_err(state->pps, &state->channel_id,
|
*err_reason = tal_fmt(tmpctx,
|
||||||
"Bad signature %s on tx %s using key %s"
|
"Bad signature %s on tx %s using key %s"
|
||||||
" (funding txid %s, psbt %s)",
|
" (funding txid %s, psbt %s)",
|
||||||
type_to_string(tmpctx, struct bitcoin_signature,
|
type_to_string(tmpctx,
|
||||||
&remote_sig),
|
struct bitcoin_signature,
|
||||||
type_to_string(tmpctx, struct bitcoin_tx,
|
&remote_sig),
|
||||||
local_commit),
|
type_to_string(tmpctx,
|
||||||
type_to_string(tmpctx, struct pubkey,
|
struct bitcoin_tx,
|
||||||
&state->their_funding_pubkey),
|
local_commit),
|
||||||
/* This is the first place we'd discover
|
type_to_string(tmpctx, struct pubkey,
|
||||||
* * the funding tx doesn't match up */
|
&state->their_funding_pubkey),
|
||||||
type_to_string(tmpctx, struct bitcoin_txid,
|
/* This is the first place we'd discover
|
||||||
&tx_state->funding_txid),
|
* the funding tx doesn't match up */
|
||||||
type_to_string(tmpctx, struct wally_psbt,
|
type_to_string(tmpctx,
|
||||||
tx_state->psbt));
|
struct bitcoin_txid,
|
||||||
|
&tx_state->funding_txid),
|
||||||
|
type_to_string(tmpctx,
|
||||||
|
struct wally_psbt,
|
||||||
|
tx_state->psbt));
|
||||||
|
revert_channel_state(state);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create commitment tx signatures for remote */
|
/* Create commitment tx signatures for remote */
|
||||||
@ -1621,6 +1673,7 @@ static u8 *accepter_commits(struct state *state,
|
|||||||
if (!remote_commit) {
|
if (!remote_commit) {
|
||||||
*err_reason = tal_fmt(tmpctx, "Could not meet their fees"
|
*err_reason = tal_fmt(tmpctx, "Could not meet their fees"
|
||||||
" and reserve: %s", error);
|
" and reserve: %s", error);
|
||||||
|
revert_channel_state(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2021,6 +2074,7 @@ static u8 *opener_commits(struct state *state,
|
|||||||
if (!remote_commit) {
|
if (!remote_commit) {
|
||||||
*err_reason = tal_fmt(tmpctx, "Could not meet their fees"
|
*err_reason = tal_fmt(tmpctx, "Could not meet their fees"
|
||||||
" and reserve: %s", error);
|
" and reserve: %s", error);
|
||||||
|
revert_channel_state(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2060,6 +2114,7 @@ static u8 *opener_commits(struct state *state,
|
|||||||
msg = opening_negotiate_msg(tmpctx, state);
|
msg = opening_negotiate_msg(tmpctx, state);
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
*err_reason = NULL;
|
*err_reason = NULL;
|
||||||
|
revert_channel_state(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2071,11 +2126,12 @@ static u8 *opener_commits(struct state *state,
|
|||||||
"Parsing commitment signed %s",
|
"Parsing commitment signed %s",
|
||||||
tal_hex(tmpctx, msg));
|
tal_hex(tmpctx, msg));
|
||||||
|
|
||||||
if (htlc_sigs != NULL)
|
if (htlc_sigs != NULL) {
|
||||||
peer_failed_warn(state->pps, &state->channel_id,
|
*err_reason = tal_fmt(tmpctx, "Must not send HTLCs with first"
|
||||||
"Must not send HTLCs with first"
|
" commitment. %s", tal_hex(tmpctx, msg));
|
||||||
" commitment. %s",
|
revert_channel_state(state);
|
||||||
tal_hex(tmpctx, msg));
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
local_commit = initial_channel_tx(state, &wscript, state->channel,
|
local_commit = initial_channel_tx(state, &wscript, state->channel,
|
||||||
&state->first_per_commitment_point[LOCAL],
|
&state->first_per_commitment_point[LOCAL],
|
||||||
@ -2086,6 +2142,7 @@ static u8 *opener_commits(struct state *state,
|
|||||||
if (!local_commit) {
|
if (!local_commit) {
|
||||||
*err_reason = tal_fmt(tmpctx, "Could not meet our fees"
|
*err_reason = tal_fmt(tmpctx, "Could not meet our fees"
|
||||||
" and reserve: %s", error);
|
" and reserve: %s", error);
|
||||||
|
revert_channel_state(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2112,21 +2169,27 @@ static u8 *opener_commits(struct state *state,
|
|||||||
* a courtesy to other implementaters whose brains may be so
|
* a courtesy to other implementaters whose brains may be so
|
||||||
* twisted by coding in Go, Scala and Rust that they can no
|
* twisted by coding in Go, Scala and Rust that they can no
|
||||||
* longer read C code. */
|
* longer read C code. */
|
||||||
peer_failed_err(state->pps, &state->channel_id,
|
*err_reason = tal_fmt(tmpctx,
|
||||||
"Bad signature %s on tx %s using key %s "
|
"Bad signature %s on tx %s using key %s "
|
||||||
"(funding txid %s, psbt %s)",
|
"(funding txid %s, psbt %s)",
|
||||||
type_to_string(tmpctx, struct bitcoin_signature,
|
type_to_string(tmpctx,
|
||||||
&remote_sig),
|
struct bitcoin_signature,
|
||||||
type_to_string(tmpctx, struct bitcoin_tx,
|
&remote_sig),
|
||||||
local_commit),
|
type_to_string(tmpctx,
|
||||||
type_to_string(tmpctx, struct pubkey,
|
struct bitcoin_tx,
|
||||||
&state->their_funding_pubkey),
|
local_commit),
|
||||||
/* This is the first place we'd discover the
|
type_to_string(tmpctx, struct pubkey,
|
||||||
* * funding tx doesn't match up */
|
&state->their_funding_pubkey),
|
||||||
type_to_string(tmpctx, struct bitcoin_txid,
|
/* This is the first place we'd discover the
|
||||||
&tx_state->funding_txid),
|
* funding tx doesn't match up */
|
||||||
type_to_string(tmpctx, struct wally_psbt,
|
type_to_string(tmpctx,
|
||||||
tx_state->psbt));
|
struct bitcoin_txid,
|
||||||
|
&tx_state->funding_txid),
|
||||||
|
type_to_string(tmpctx,
|
||||||
|
struct wally_psbt,
|
||||||
|
tx_state->psbt));
|
||||||
|
revert_channel_state(state);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direct_outputs[LOCAL])
|
if (direct_outputs[LOCAL])
|
||||||
|
Loading…
Reference in New Issue
Block a user