dual-fund: add require_confirmed_inputs to RBF flows

We now require peers to reaffirm their preference for
`require_confirmed_inputs` when executing an RBF.

Requested-By: @t-bast
This commit is contained in:
niftynei
2023-12-13 16:59:50 -06:00
committed by Christian Decker
parent e72be90606
commit bc98cafe9e
8 changed files with 98 additions and 14 deletions

View File

@@ -3564,6 +3564,14 @@ static void rbf_local_start(struct state *state, u8 *msg)
*init_rbf_tlvs->funding_output_contribution
= (s64)tx_state->opener_funding.satoshis; /* Raw: wire conversion */
/* We repeat whatever we used on initial open for requiring confirmed
* inputs */
if (state->require_confirmed_inputs[LOCAL])
init_rbf_tlvs->require_confirmed_inputs =
tal(init_rbf_tlvs, struct tlv_tx_init_rbf_tlvs_require_confirmed_inputs);
msg = towire_tx_init_rbf(tmpctx, &state->channel_id,
tx_state->tx_locktime,
tx_state->feerate_per_kw_funding,
@@ -3601,6 +3609,14 @@ static void rbf_local_start(struct state *state, u8 *msg)
} else
tx_state->accepter_funding = state->tx_state->accepter_funding;
/* Set the require_confirmed_inputs to whatever they set here */
if (ack_rbf_tlvs)
state->require_confirmed_inputs[REMOTE] =
ack_rbf_tlvs->require_confirmed_inputs != NULL;
else
/* They have to re-affirm to keep it! */
state->require_confirmed_inputs[REMOTE] = false;
/* Check that total funding doesn't overflow */
if (!amount_sat_add(&total, tx_state->opener_funding,
tx_state->accepter_funding)) {
@@ -3672,6 +3688,11 @@ static void rbf_local_start(struct state *state, u8 *msg)
tal_free(state->tx_state);
state->tx_state = tal_steal(state, tx_state);
/* Notify lightningd about require_confirmed state */
msg = towire_dualopend_update_require_confirmed(NULL,
state->require_confirmed_inputs[REMOTE]);
wire_sync_write(REQ_FD, take(msg));
/* We merge with RBF's we've initiated now */
rbf_wrap_up(state, tx_state, total);
tal_free(rbf_ctx);
@@ -3735,6 +3756,14 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg)
/* Otherwise we use the last known funding amount */
tx_state->opener_funding = state->tx_state->opener_funding;
/* Set the require_confirmed_inputs to whatever they set here */
if (init_rbf_tlvs)
state->require_confirmed_inputs[REMOTE] =
init_rbf_tlvs->require_confirmed_inputs != NULL;
else
/* They have to re-affirm to keep it! */
state->require_confirmed_inputs[REMOTE] = false;
/* Copy over the channel config info -- everything except
* the reserve will be the same */
tx_state->localconf = state->tx_state->localconf;
@@ -3757,7 +3786,8 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg)
state->tx_state->accepter_funding,
tx_state->feerate_per_kw_funding,
tx_state->tx_locktime,
state->requested_lease);
state->requested_lease,
state->require_confirmed_inputs[REMOTE]);
wire_sync_write(REQ_FD, take(msg));
msg = wire_sync_read(tmpctx, REQ_FD);
@@ -3833,6 +3863,11 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg)
*ack_rbf_tlvs->funding_output_contribution
= (s64)tx_state->accepter_funding.satoshis; /* Raw: wire conversion */
/* We keep whatever we initially set at open for RBFs */
if (state->require_confirmed_inputs[LOCAL])
ack_rbf_tlvs->require_confirmed_inputs =
tal(ack_rbf_tlvs, struct tlv_tx_ack_rbf_tlvs_require_confirmed_inputs);
msg = towire_tx_ack_rbf(tmpctx, &state->channel_id, ack_rbf_tlvs);
peer_write(state->pps, msg);
peer_billboard(false, "channel rbf: ack sent, waiting for reply");
@@ -4177,6 +4212,7 @@ static u8 *handle_master_in(struct state *state)
case WIRE_DUALOPEND_DRY_RUN:
case WIRE_DUALOPEND_VALIDATE_LEASE:
case WIRE_DUALOPEND_VALIDATE_INPUTS:
case WIRE_DUALOPEND_UPDATE_REQUIRE_CONFIRMED:
break;
}
status_failed(STATUS_FAIL_MASTER_IO,

View File

@@ -118,12 +118,17 @@ msgdata,dualopend_got_rbf_offer,our_last_funding,amount_sat,
msgdata,dualopend_got_rbf_offer,funding_feerate_per_kw,u32,
msgdata,dualopend_got_rbf_offer,locktime,u32,
msgdata,dualopend_got_rbf_offer,requested_lease,?amount_sat,
msgdata,dualopend_got_rbf_offer,require_confirmed_inputs,bool,
# master->dualopend: reply back with our funding info/contribs
msgtype,dualopend_got_rbf_offer_reply,7505
msgdata,dualopend_got_rbf_offer_reply,our_funding,amount_sat,
msgdata,dualopend_got_rbf_offer_reply,psbt,wally_psbt,
# dualopend->master: update to require_confirmed_inputs preference
msgtype,dualopend_update_require_confirmed,7511
msgdata,dualopend_update_require_confirmed,require_confirmed_inputs,bool,
# dualopend->master: is this a valid RBF candidate transaction?
msgtype,dualopend_rbf_validate,7506
msgdata,dualopend_rbf_validate,proposed_funding_psbt,wally_psbt,
1 #include <bitcoin/chainparams.h>
118 msgdata msgtype
119 msgdata
120 # dualopend->master: is this a valid RBF candidate transaction? msgdata
121 # dualopend->master: update to require_confirmed_inputs preference
122 msgtype
123 msgdata
124 # master->dualopend: this is a valid RBF candidate transaction # dualopend->master: is this a valid RBF candidate transaction?
125 msgtype
126 # master->dualopend: attempt an RBF msgdata
127 msgtype # master->dualopend: this is a valid RBF candidate transaction
128 msgtype
129 # master->dualopend: attempt an RBF
130 msgtype
131 msgdata
132 msgdata
133 msgdata
134 msgdata # dualopend->master: about to send first commitment_signed