From 4da0d6230e5c81ea3c7d450397a9c9f7b7a4fed7 Mon Sep 17 00:00:00 2001 From: niftynei Date: Thu, 14 Jul 2022 12:52:47 -0500 Subject: [PATCH] dual-fund: update to latest, add in updates to rbf amounts You can now pick a different amount during the RBF phase --- common/features.c | 4 +- openingd/dualopend.c | 109 +++++++++++++++------ wire/extracted_peer_03_openchannelv2.patch | 10 +- wire/peer_wire.csv | 2 + 4 files changed, 89 insertions(+), 36 deletions(-) diff --git a/common/features.c b/common/features.c index 2a090f1e8..203c0d2f3 100644 --- a/common/features.c +++ b/common/features.c @@ -171,9 +171,9 @@ static const struct dependency feature_deps[] = { /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #9: * Name | Description | Context | Dependencies | * ... - * `option_dual_fund` | ... | ... | `option_anchor_outputs` + * `option_dual_fund` | ... | ... | `option_static_remotekey` */ - { OPT_DUAL_FUND, OPT_ANCHOR_OUTPUTS }, + { OPT_DUAL_FUND, OPT_STATIC_REMOTEKEY }, /* BOLT-route-blinding #9: * Name | Description | Context | Dependencies | * ... diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 8004e35a6..18e0eb620 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -3105,6 +3105,9 @@ static void rbf_local_start(struct state *state, u8 *msg) struct channel_id cid; struct amount_sat total; char *err_reason; + struct tlv_tx_init_rbf_tlvs *init_rbf_tlvs; + struct tlv_tx_ack_rbf_tlvs *ack_rbf_tlvs; + /* tmpctx gets cleaned midway, so we have a context for this fn */ char *rbf_ctx = notleak_with_children(tal(state, char)); @@ -3114,6 +3117,7 @@ static void rbf_local_start(struct state *state, u8 *msg) * the reserve will be the same */ tx_state->localconf = state->tx_state->localconf; tx_state->remoteconf = state->tx_state->remoteconf; + init_rbf_tlvs = tlv_tx_init_rbf_tlvs_new(tmpctx); if (!fromwire_dualopend_rbf_init(tx_state, msg, &tx_state->opener_funding, @@ -3141,9 +3145,17 @@ static void rbf_local_start(struct state *state, u8 *msg) } tx_state->tx_locktime = tx_state->psbt->tx->locktime; + + /* For now, we always just echo/send the funding amount */ + init_rbf_tlvs->funding_output_contribution + = tal(init_rbf_tlvs, u64); + *init_rbf_tlvs->funding_output_contribution + = tx_state->opener_funding.satoshis; /* Raw: wire conversion */ + msg = towire_tx_init_rbf(tmpctx, &state->channel_id, - tx_state->tx_locktime, - tx_state->feerate_per_kw_funding); + tx_state->tx_locktime, + tx_state->feerate_per_kw_funding, + init_rbf_tlvs); peer_write(state->pps, take(msg)); @@ -3154,13 +3166,27 @@ static void rbf_local_start(struct state *state, u8 *msg) goto free_rbf_ctx; } - if (!fromwire_tx_ack_rbf(msg, &cid)) + if (!fromwire_tx_ack_rbf(tmpctx, msg, &cid, &ack_rbf_tlvs)) open_err_fatal(state, "Parsing tx_ack_rbf %s", tal_hex(tmpctx, msg)); peer_billboard(false, "channel rbf: ack received"); check_channel_id(state, &cid, &state->channel_id); + if (ack_rbf_tlvs && ack_rbf_tlvs->funding_output_contribution) { + tx_state->accepter_funding = + amount_sat(*ack_rbf_tlvs->funding_output_contribution); + + if (!amount_sat_eq(state->tx_state->accepter_funding, + tx_state->accepter_funding)) + status_debug("RBF: accepter amt changed %s->%s", + type_to_string(tmpctx, struct amount_sat, + &state->tx_state->accepter_funding), + type_to_string(tmpctx, struct amount_sat, + &tx_state->accepter_funding)); + } else + tx_state->accepter_funding = state->tx_state->accepter_funding; + /* Check that total funding doesn't overflow */ if (!amount_sat_add(&total, tx_state->opener_funding, tx_state->accepter_funding)) { @@ -3237,16 +3263,21 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg) char *err_reason; struct amount_sat total; enum dualopend_wire msg_type; + struct tlv_tx_init_rbf_tlvs *init_rbf_tlvs; + struct tlv_tx_ack_rbf_tlvs *ack_rbf_tlvs; + u8 *msg; /* tmpctx gets cleaned midway, so we have a context for this fn */ char *rbf_ctx = notleak_with_children(tal(state, char)); /* We need a new tx_state! */ tx_state = new_tx_state(rbf_ctx); + ack_rbf_tlvs = tlv_tx_ack_rbf_tlvs_new(tmpctx); - if (!fromwire_tx_init_rbf(rbf_msg, &cid, + if (!fromwire_tx_init_rbf(tmpctx, rbf_msg, &cid, &tx_state->tx_locktime, - &tx_state->feerate_per_kw_funding)) + &tx_state->feerate_per_kw_funding, + &init_rbf_tlvs)) open_err_fatal(state, "Parsing tx_init_rbf %s", tal_hex(tmpctx, rbf_msg)); @@ -3265,6 +3296,22 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg) "Last funding attempt not complete:" " missing your funding tx_sigs"); + /* Maybe they want a different funding amount! */ + if (init_rbf_tlvs && init_rbf_tlvs->funding_output_contribution) { + tx_state->opener_funding = + amount_sat(*init_rbf_tlvs->funding_output_contribution); + + if (!amount_sat_eq(tx_state->opener_funding, + state->tx_state->opener_funding)) + status_debug("RBF: opener amt changed %s->%s", + type_to_string(tmpctx, struct amount_sat, + &state->tx_state->opener_funding), + type_to_string(tmpctx, struct amount_sat, + &tx_state->opener_funding)); + } else + /* Otherwise we use the last known funding amount */ + tx_state->opener_funding = state->tx_state->opener_funding; + /* Copy over the channel config info -- everything except * the reserve will be the same */ tx_state->localconf = state->tx_state->localconf; @@ -3300,9 +3347,7 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg) } if (!fromwire_dualopend_got_rbf_offer_reply(state, msg, - state->our_role == TX_INITIATOR ? - &tx_state->opener_funding : - &tx_state->accepter_funding, + &tx_state->accepter_funding, &tx_state->psbt)) master_badmsg(WIRE_DUALOPEND_GOT_RBF_OFFER_REPLY, msg); @@ -3312,13 +3357,26 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg) /* Check that total funding doesn't overflow */ if (!amount_sat_add(&total, tx_state->opener_funding, - tx_state->accepter_funding)) { - open_err_warn(state, "Amount overflow. Local sats %s. " - "Remote sats %s", - type_to_string(tmpctx, struct amount_sat, - &tx_state->accepter_funding), - type_to_string(tmpctx, struct amount_sat, - &tx_state->opener_funding)); + tx_state->accepter_funding)) + open_err_fatal(state, + "Amount overflow. Local sats %s. Remote sats %s", + type_to_string(tmpctx, struct amount_sat, + &tx_state->accepter_funding), + type_to_string(tmpctx, struct amount_sat, + &tx_state->opener_funding)); + + /* Now that we know the total of the channel, we can set the reserve */ + set_reserve(tx_state, total, state->our_role); + + if (!check_config_bounds(tmpctx, total, + state->feerate_per_kw_commitment, + state->max_to_self_delay, + state->min_effective_htlc_capacity, + &tx_state->remoteconf, + &tx_state->localconf, + true, /* v2 means we use anchor outputs */ + &err_reason)) { + negotiation_failed(state, "%s", err_reason); goto free_rbf_ctx; } @@ -3340,22 +3398,13 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg) goto free_rbf_ctx; } - /* Now that we know the total of the channel, we can set the reserve */ - set_reserve(tx_state, total, state->our_role); + /* We always send the funding amount */ + ack_rbf_tlvs->funding_output_contribution + = tal(ack_rbf_tlvs, u64); + *ack_rbf_tlvs->funding_output_contribution + = tx_state->accepter_funding.satoshis; /* Raw: wire conversion */ - if (!check_config_bounds(tmpctx, total, - state->feerate_per_kw_commitment, - state->max_to_self_delay, - state->min_effective_htlc_capacity, - &tx_state->remoteconf, - &tx_state->localconf, - true, /* v2 means we use anchor outputs */ - &err_reason)) { - open_err_warn(state, "%s", err_reason); - goto free_rbf_ctx; - } - - msg = towire_tx_ack_rbf(tmpctx, &state->channel_id); + 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"); diff --git a/wire/extracted_peer_03_openchannelv2.patch b/wire/extracted_peer_03_openchannelv2.patch index 9f3e93f44..cb978278e 100644 --- a/wire/extracted_peer_03_openchannelv2.patch +++ b/wire/extracted_peer_03_openchannelv2.patch @@ -1,6 +1,6 @@ ---- wire/peer_wire.csv 2022-05-16 13:44:14.131975828 -0500 -+++ - 2022-05-16 13:44:55.193718105 -0500 -@@ -37,6 +31,52 @@ +--- wire/peer_wire.csv 2022-05-19 14:25:25.346839996 -0500 ++++ - 2022-05-19 14:26:13.327293456 -0500 +@@ -37,6 +31,54 @@ tlvdata,n2,tlv1,amount_msat,tu64, tlvtype,n2,tlv2,11 tlvdata,n2,tlv2,cltv_expiry,tu32, @@ -40,10 +40,12 @@ +msgdata,tx_init_rbf,channel_id,channel_id, +msgdata,tx_init_rbf,locktime,u32, +msgdata,tx_init_rbf,feerate,u32, ++msgdata,tx_init_rbf,tlvs,tx_init_rbf_tlvs, +tlvtype,tx_init_rbf_tlvs,funding_output_contribution,0 +tlvdata,tx_init_rbf_tlvs,funding_output_contribution,satoshis,tu64, +msgtype,tx_ack_rbf,73 +msgdata,tx_ack_rbf,channel_id,channel_id, ++msgdata,tx_ack_rbf,tlvs,tx_ack_rbf_tlvs, +tlvtype,tx_ack_rbf_tlvs,funding_output_contribution,0 +tlvdata,tx_ack_rbf_tlvs,funding_output_contribution,satoshis,tu64, +msgtype,tx_abort,74 @@ -53,7 +55,7 @@ msgtype,open_channel,32 msgdata,open_channel,chain_hash,chain_hash, msgdata,open_channel,temporary_channel_id,byte,32 -@@ -92,6 +116,56 @@ +@@ -92,6 +130,50 @@ msgdata,channel_ready,tlvs,channel_ready_tlvs, tlvtype,channel_ready_tlvs,short_channel_id,1 tlvdata,channel_ready_tlvs,short_channel_id,alias,short_channel_id, diff --git a/wire/peer_wire.csv b/wire/peer_wire.csv index f8f175853..512818ab7 100644 --- a/wire/peer_wire.csv +++ b/wire/peer_wire.csv @@ -73,10 +73,12 @@ msgtype,tx_init_rbf,72 msgdata,tx_init_rbf,channel_id,channel_id, msgdata,tx_init_rbf,locktime,u32, msgdata,tx_init_rbf,feerate,u32, +msgdata,tx_init_rbf,tlvs,tx_init_rbf_tlvs, tlvtype,tx_init_rbf_tlvs,funding_output_contribution,0 tlvdata,tx_init_rbf_tlvs,funding_output_contribution,satoshis,tu64, msgtype,tx_ack_rbf,73 msgdata,tx_ack_rbf,channel_id,channel_id, +msgdata,tx_ack_rbf,tlvs,tx_ack_rbf_tlvs, tlvtype,tx_ack_rbf_tlvs,funding_output_contribution,0 tlvdata,tx_ack_rbf_tlvs,funding_output_contribution,satoshis,tu64, msgtype,tx_abort,74