From 2d3a5c7644ab90d2e51ee1c914705b0f7a1ae629 Mon Sep 17 00:00:00 2001 From: niftynei Date: Tue, 23 Feb 2021 12:37:44 -0600 Subject: [PATCH 1/7] dual-fund: remove all references to PODLEs We're punting on PODLE's for v1 of dual-funded channels --- channeld/channeld.c | 1 - gossipd/gossipd.c | 1 - lightningd/dual_open_control.c | 2 -- openingd/dualopend.c | 19 ++-------------- wire/extracted_peer_exp_dual_fund.patch | 23 ++------------------ wire/extracted_peer_exp_dual_fund_more.patch | 4 ++-- wire/extracted_peer_exp_tmp_chan_id.patch | 2 +- wire/peer_wire.c | 2 -- 8 files changed, 7 insertions(+), 47 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index 7b7849ec7b10..e6065f93b086 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -1875,7 +1875,6 @@ static void peer_in(struct peer *peer, const u8 *msg) return; case WIRE_INIT_RBF: case WIRE_ACK_RBF: - case WIRE_BLACKLIST_PODLE: #endif break; diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 982d55a2f9e1..8b21f167375c 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -768,7 +768,6 @@ static struct io_plan *peer_msg_in(struct io_conn *conn, case WIRE_ACCEPT_CHANNEL2: case WIRE_INIT_RBF: case WIRE_ACK_RBF: - case WIRE_BLACKLIST_PODLE: #endif status_broken("peer %s: relayed unexpected msg of type %s", type_to_string(tmpctx, struct node_id, &peer->id), diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 385720365c2d..6035f6e7c0de 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -243,7 +243,6 @@ struct openchannel2_payload { u8 channel_flags; u32 locktime; u8 *shutdown_scriptpubkey; - /* FIXME: include the podle? */ struct amount_sat accepter_funding; u32 funding_feerate_per_kw; @@ -286,7 +285,6 @@ openchannel2_hook_serialize(struct openchannel2_payload *payload, if (tal_bytelen(payload->shutdown_scriptpubkey) != 0) json_add_hex_talarr(stream, "shutdown_scriptpubkey", payload->shutdown_scriptpubkey); - /* FIXME: include the podle? */ json_object_end(stream); } diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 18ea4598e8d2..605a662712dc 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -153,7 +153,6 @@ struct state { struct channel_id channel_id; u8 channel_flags; - struct sha256 opening_podle_h2; enum tx_role our_role; u32 feerate_per_kw_funding; @@ -220,8 +219,7 @@ static u8 *psbt_changeset_get_next(const tal_t *ctx, msg = towire_tx_add_input(ctx, cid, serial_id, prevtx, in->tx_input.index, in->tx_input.sequence, - script, - NULL); + script); tal_arr_remove(&set->added_ins, 0); return msg; @@ -1202,7 +1200,6 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state) case WIRE_TX_REMOVE_OUTPUT: case WIRE_TX_COMPLETE: case WIRE_ACK_RBF: - case WIRE_BLACKLIST_PODLE: case WIRE_CHANNEL_ANNOUNCEMENT: case WIRE_CHANNEL_UPDATE: case WIRE_NODE_ANNOUNCEMENT: @@ -1252,8 +1249,6 @@ static bool run_tx_interactive(struct state *state, struct bitcoin_tx *tx; struct bitcoin_txid txid; struct amount_sat amt; - struct tlv_tx_add_input_tlvs *add_tlvs = - tlv_tx_add_input_tlvs_new(tmpctx); if (!fromwire_tx_add_input(tmpctx, msg, &cid, &serial_id, @@ -1261,8 +1256,7 @@ static bool run_tx_interactive(struct state *state, &tx_bytes), &outnum, &sequence, cast_const2(u8 **, - &redeemscript), - add_tlvs)) + &redeemscript))) open_err_fatal(state, "Parsing tx_add_input %s", tal_hex(tmpctx, msg)); @@ -1386,7 +1380,6 @@ static bool run_tx_interactive(struct state *state, psbt_input_set_serial_id(psbt, in, serial_id); - /* FIXME: what's in the tlv? */ break; } case WIRE_TX_REMOVE_INPUT: { @@ -1548,7 +1541,6 @@ static bool run_tx_interactive(struct state *state, case WIRE_ACCEPT_CHANNEL2: case WIRE_INIT_RBF: case WIRE_ACK_RBF: - case WIRE_BLACKLIST_PODLE: case WIRE_CHANNEL_ANNOUNCEMENT: case WIRE_CHANNEL_UPDATE: case WIRE_NODE_ANNOUNCEMENT: @@ -1855,7 +1847,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) if (!fromwire_open_channel2(oc2_msg, &chain_hash, &state->channel_id, - &state->opening_podle_h2, &feerate_max, &feerate_min, &feerate_best, @@ -1921,7 +1912,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) &state->our_points.revocation, &state->their_points.revocation); - /* FIXME: pass the podle back also */ msg = towire_dualopend_got_offer(NULL, &cid, tx_state->opener_funding, @@ -2333,7 +2323,6 @@ static void opener_start(struct state *state, u8 *msg) struct channel_id cid; char *err_reason; struct amount_sat total; - struct sha256 podle; u32 feerate_min, feerate_max, feerate_best; struct tx_state *tx_state = state->tx_state; @@ -2392,12 +2381,9 @@ static void opener_start(struct state *state, u8 *msg) state->upfront_shutdown_script[LOCAL]; } - /* FIXME: actually set the podle */ - memset(&podle, 0, sizeof(podle)); msg = towire_open_channel2(NULL, &chainparams->genesis_blockhash, &state->channel_id, - &podle, /* FIXME: podle H2! */ feerate_max, feerate_min, feerate_best, @@ -3357,7 +3343,6 @@ static u8 *handle_peer_in(struct state *state) case WIRE_TX_REMOVE_OUTPUT: case WIRE_TX_COMPLETE: case WIRE_ACK_RBF: - case WIRE_BLACKLIST_PODLE: case WIRE_CHANNEL_ANNOUNCEMENT: case WIRE_CHANNEL_UPDATE: case WIRE_NODE_ANNOUNCEMENT: diff --git a/wire/extracted_peer_exp_dual_fund.patch b/wire/extracted_peer_exp_dual_fund.patch index 12c7aa1b52d5..599f7a7d8d7f 100644 --- a/wire/extracted_peer_exp_dual_fund.patch +++ b/wire/extracted_peer_exp_dual_fund.patch @@ -1,6 +1,6 @@ --- wire/extracted_peer_wire_csv 2020-07-28 12:36:12.063168014 -0500 +++ - 2020-08-31 21:00:40.856646471 -0500 -@@ -31,6 +31,46 @@ +@@ -31,6 +31,40 @@ tlvdata,n2,tlv1,amount_msat,tu64, tlvtype,n2,tlv2,11 tlvdata,n2,tlv2,cltv_expiry,tu32, @@ -13,12 +13,6 @@ +msgdata,tx_add_input,sequence,u32, +msgdata,tx_add_input,redeemscript_len,u16, +msgdata,tx_add_input,script,byte,redeemscript_len -+msgdata,tx_add_input,tlvs,tx_add_input_tlvs, -+tlvtype,tx_add_input_tlvs,podle_proof,2 -+tlvdata,tx_add_input_tlvs,podle_proof,p,point, -+tlvdata,tx_add_input_tlvs,podle_proof,p2,point, -+tlvdata,tx_add_input_tlvs,podle_proof,e,sha256, -+tlvdata,tx_add_input_tlvs,podle_proof,sig,byte,32 +msgtype,tx_add_output,67 +msgdata,tx_add_output,channel_id,channel_id, +msgdata,tx_add_output,serial_id,u16, @@ -47,13 +41,12 @@ msgtype,open_channel,32 msgdata,open_channel,chain_hash,chain_hash, msgdata,open_channel,temporary_channel_id,byte,32 -@@ -82,6 +122,54 @@ +@@ -82,6 +122,53 @@ msgtype,funding_locked,36 msgdata,funding_locked,channel_id,channel_id, msgdata,funding_locked,next_per_commitment_point,point, +msgtype,open_channel2,64 +msgdata,open_channel2,chain_hash,chain_hash, -+msgdata,open_channel2,podle_h2,sha256, +msgdata,open_channel2,feerate_per_kw_funding,u32, +msgdata,open_channel2,funding_satoshis,u64, +msgdata,open_channel2,dust_limit_satoshis,u64, @@ -102,15 +95,3 @@ msgtype,shutdown,38 msgdata,shutdown,channel_id,channel_id, msgdata,shutdown,len,u16, -@@ -169,6 +257,11 @@ - msgdata,channel_update,fee_base_msat,u32, - msgdata,channel_update,fee_proportional_millionths,u32, - msgdata,channel_update,htlc_maximum_msat,u64,,option_channel_htlc_max -+msgtype,blacklist_podle,260 -+msgdata,blacklist_podle,signature,signature, -+msgdata,blacklist_podle,node_id,point, -+msgdata,blacklist_podle,podle_h2,byte,32 -+msgdata,blacklist_podle,timestamp,u32, - msgtype,query_short_channel_ids,261,gossip_queries - msgdata,query_short_channel_ids,chain_hash,chain_hash, - msgdata,query_short_channel_ids,len,u16, diff --git a/wire/extracted_peer_exp_dual_fund_more.patch b/wire/extracted_peer_exp_dual_fund_more.patch index ba5b454c58e0..95c4c8c14a48 100644 --- a/wire/extracted_peer_exp_dual_fund_more.patch +++ b/wire/extracted_peer_exp_dual_fund_more.patch @@ -10,7 +10,7 @@ msgdata,tx_add_input,prevtx,byte,prevtx_len msgdata,tx_add_input,prevtx_vout,u32, @@ -48,16 +48,16 @@ - tlvdata,tx_add_input_tlvs,podle_proof,sig,byte,32 + msgdata,tx_add_input,script,byte,redeemscript_len msgtype,tx_add_output,67 msgdata,tx_add_output,channel_id,channel_id, -msgdata,tx_add_output,serial_id,u16, @@ -30,9 +30,9 @@ msgdata,tx_complete,channel_id,channel_id, msgtype,tx_signatures,71 @@ -125,7 +125,9 @@ + msgdata,funding_locked,next_per_commitment_point,point, msgtype,open_channel2,64 msgdata,open_channel2,chain_hash,chain_hash, - msgdata,open_channel2,podle_h2,sha256, -msgdata,open_channel2,feerate_per_kw_funding,u32, +msgdata,open_channel2,feerate_funding_max,u32, +msgdata,open_channel2,feerate_funding_min,u32, diff --git a/wire/extracted_peer_exp_tmp_chan_id.patch b/wire/extracted_peer_exp_tmp_chan_id.patch index f691cddbc534..44536a3b6577 100644 --- a/wire/extracted_peer_exp_tmp_chan_id.patch +++ b/wire/extracted_peer_exp_tmp_chan_id.patch @@ -5,6 +5,6 @@ msgtype,open_channel2,64 msgdata,open_channel2,chain_hash,chain_hash, +msgdata,open_channel2,temporary_channel_id,byte,32 - msgdata,open_channel2,podle_h2,sha256, msgdata,open_channel2,feerate_funding_max,u32, msgdata,open_channel2,feerate_funding_min,u32, + msgdata,open_channel2,feerate_funding_best,u32, diff --git a/wire/peer_wire.c b/wire/peer_wire.c index b8a9d6d68199..c2161021ccb5 100644 --- a/wire/peer_wire.c +++ b/wire/peer_wire.c @@ -45,7 +45,6 @@ static bool unknown_type(enum peer_wire t) case WIRE_ACCEPT_CHANNEL2: case WIRE_INIT_RBF: case WIRE_ACK_RBF: - case WIRE_BLACKLIST_PODLE: #endif return false; } @@ -97,7 +96,6 @@ bool is_msg_for_gossipd(const u8 *cursor) case WIRE_ACCEPT_CHANNEL2: case WIRE_INIT_RBF: case WIRE_ACK_RBF: - case WIRE_BLACKLIST_PODLE: #endif break; } From 9d0e5e4eb7362011754815a78cfa0fa5da0a1d01 Mon Sep 17 00:00:00 2001 From: niftynei Date: Tue, 2 Mar 2021 15:02:24 -0600 Subject: [PATCH 2/7] df-spec: consolidate dual-funding patches, update feerate protocol We consolidate to the latest/singular RFC patch for dual-funding, so there's just a single patchfile for the change. Plus we move back to the opener setting the desired feerate, the accepter merely declines to participate if they disagree with the set rate. --- common/channel_id.c | 2 +- common/psbt_internal.c | 4 +- lightningd/dual_open_control.c | 105 +---- openingd/dualopend.c | 391 ++++++++---------- openingd/dualopend_wire.csv | 11 +- openingd/dualopend_wiregen.c | 40 +- openingd/dualopend_wiregen.h | 18 +- plugins/spender/multifundchannel.c | 2 +- tests/plugins/df_accepter.py | 33 +- wire/extracted_peer_exp_dual_fund_more.patch | 50 --- ...=> extracted_peer_exp_openchannelv2.patch} | 33 +- wire/extracted_peer_exp_tmp_chan_id.patch | 10 - ...eer_experimental_dual_fund_more_more.patch | 14 - 13 files changed, 256 insertions(+), 457 deletions(-) delete mode 100644 wire/extracted_peer_exp_dual_fund_more.patch rename wire/{extracted_peer_exp_dual_fund.patch => extracted_peer_exp_openchannelv2.patch} (83%) delete mode 100644 wire/extracted_peer_exp_tmp_chan_id.patch delete mode 100644 wire/extracted_peer_experimental_dual_fund_more_more.patch diff --git a/common/channel_id.c b/common/channel_id.c index 74e55b291243..7b1bae721bbb 100644 --- a/common/channel_id.c +++ b/common/channel_id.c @@ -18,7 +18,7 @@ void derive_channel_id_v2(struct channel_id *channel_id, const struct pubkey *basepoint_1, const struct pubkey *basepoint_2) { - /* BOLT-df8bb5994d99e4c78053f7cb57694795f8393dc5 #2: + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * `channel_id`, v2 * For channels established using the v2 protocol, the * `channel_id` is the diff --git a/common/psbt_internal.c b/common/psbt_internal.c index 9fcd4aed5580..1686775f8c3f 100644 --- a/common/psbt_internal.c +++ b/common/psbt_internal.c @@ -67,8 +67,8 @@ psbt_to_witness_stacks(const tal_t *ctx, /* FIXME: throw an error ? */ return NULL; - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: - * - if is the `initiator`: + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * - if is the *initiator*: * - MUST send even `serial_id`s */ if (serial_id % 2 == side_to_stack) { diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 6035f6e7c0de..3afeff0701fa 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -232,9 +232,7 @@ struct openchannel2_payload { struct amount_sat dust_limit_satoshis; struct amount_msat max_htlc_value_in_flight_msat; struct amount_msat htlc_minimum_msat; - u32 funding_feerate_max; - u32 funding_feerate_min; - u32 funding_feerate_best; + u32 funding_feerate_per_kw; u32 feerate_our_max; u32 feerate_our_min; u32 commitment_feerate_per_kw; @@ -245,7 +243,6 @@ struct openchannel2_payload { u8 *shutdown_scriptpubkey; struct amount_sat accepter_funding; - u32 funding_feerate_per_kw; struct wally_psbt *psbt; const u8 *our_shutdown_scriptpubkey; char *err_msg; @@ -266,18 +263,14 @@ openchannel2_hook_serialize(struct openchannel2_payload *payload, payload->max_htlc_value_in_flight_msat); json_add_amount_msat_only(stream, "htlc_minimum_msat", payload->htlc_minimum_msat); - json_add_num(stream, "funding_feerate_max", - payload->funding_feerate_max); - json_add_num(stream, "funding_feerate_min", - payload->funding_feerate_min); - json_add_num(stream, "funding_feerate_best", - payload->funding_feerate_best); + json_add_num(stream, "funding_feerate_per_kw", + payload->funding_feerate_per_kw); + json_add_num(stream, "commitment_feerate_per_kw", + payload->commitment_feerate_per_kw); json_add_num(stream, "feerate_our_max", payload->feerate_our_max); json_add_num(stream, "feerate_our_min", payload->feerate_our_min); - json_add_num(stream, "commitment_feerate_per_kw", - payload->commitment_feerate_per_kw); json_add_num(stream, "to_self_delay", payload->to_self_delay); json_add_num(stream, "max_accepted_htlcs", payload->max_accepted_htlcs); json_add_num(stream, "channel_flags", payload->channel_flags); @@ -689,38 +682,11 @@ openchannel2_hook_cb(struct openchannel2_payload *payload STEALS) return subd_send_msg(dualopend, take(msg)); } - /* If there's no plugin, the funding_feerate_per_kw will be zero. - * In this case, we set the funding_feerate_per_kw to the default, - * the 'best' */ - if (payload->funding_feerate_per_kw == 0) { - u32 best_feerate - = payload->funding_feerate_per_kw - = payload->funding_feerate_best; - - /* We use the old checks here now, against the base feerate */ - if (best_feerate < payload->feerate_our_min) { - msg = towire_dualopend_fail(NULL, tal_fmt(tmpctx, - "feerate_per_kw %u below" - " minimum %u", - best_feerate, - payload->feerate_our_min)); - return subd_send_msg(dualopend, take(msg)); - } - if (best_feerate > payload->feerate_our_max) { - msg = towire_dualopend_fail(NULL, tal_fmt(tmpctx, - "feerate_per_kw %u above" - " maximum %u", - best_feerate, - payload->feerate_our_max)); - return subd_send_msg(dualopend, take(msg)); - } - } - channel->cid = payload->channel_id; channel->opener = REMOTE; channel->open_attempt = new_channel_open_attempt(channel); - msg = towire_dualopend_got_offer_reply(NULL, payload->accepter_funding, - payload->funding_feerate_per_kw, + msg = towire_dualopend_got_offer_reply(NULL, + payload->accepter_funding, payload->psbt, payload->our_shutdown_scriptpubkey); @@ -807,26 +773,6 @@ openchannel2_hook_deserialize(struct openchannel2_payload *payload, &payload->accepter_funding)) fatal("Plugin failed to supply accepter_funding_msat field"); - const jsmntok_t *t = json_get_member(buffer, toks, "funding_feerate"); - /* If they don't return a feerate, we use the best */ - if (!t) - payload->funding_feerate_per_kw = payload->funding_feerate_best; - else { - if (!json_to_number(buffer, t, - &payload->funding_feerate_per_kw)) - fatal("Unable to parse 'funding-feerate'"); - if (payload->funding_feerate_per_kw - < payload->funding_feerate_min - || payload->funding_feerate_per_kw - > payload->funding_feerate_max) - /* FIXME: return an error instead of failing? */ - fatal("Plugin supplied invalid funding feerate %d." - " Outside valid range %d - %d", - payload->funding_feerate_per_kw, - payload->funding_feerate_min, - payload->funding_feerate_max); - } - if (!payload->psbt && !amount_sat_eq(payload->accepter_funding, AMOUNT_SAT(0))) { /* Gotta give a PSBT if you set the accepter_funding amount */ @@ -1042,7 +988,7 @@ static struct amount_sat calculate_reserve(struct channel_config *their_config, { struct amount_sat reserve, dust_limit; - /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2 * * The channel reserve is fixed at 1% of the total channel balance * rounded down (sum of `funding_satoshis` from `open_channel2` @@ -1677,9 +1623,7 @@ static void accepter_got_offer(struct subd *dualopend, &payload->dust_limit_satoshis, &payload->max_htlc_value_in_flight_msat, &payload->htlc_minimum_msat, - &payload->funding_feerate_max, - &payload->funding_feerate_min, - &payload->funding_feerate_best, + &payload->funding_feerate_per_kw, &payload->commitment_feerate_per_kw, &payload->to_self_delay, &payload->max_accepted_htlcs, @@ -1695,13 +1639,10 @@ static void accepter_got_offer(struct subd *dualopend, * min + max feerates. Ideally, the plugin will fail to * contribute funds if the peer's feerate range is outside of * this acceptable range, but we delegate that decision to - * the plugin's logic */ + * the plugin */ payload->feerate_our_min = feerate_min(dualopend->ld, NULL); payload->feerate_our_max = feerate_max(dualopend->ld, NULL); - /* Set the inital to feerate to zero, in case there is no plugin */ - payload->funding_feerate_per_kw = 0; - tal_add_destructor2(dualopend, openchannel2_remove_dualopend, payload); plugin_hook_call_openchannel2(dualopend->ld, payload); } @@ -1802,9 +1743,12 @@ static void handle_validate_rbf(struct subd *dualopend, inputs_present = tal_arr(tmpctx, bool, candidate_psbt->num_inputs); memset(inputs_present, true, tal_bytelen(inputs_present)); - /* Iterate through all previous inflights, confirm - * that at least one input is in all proposed RBFs, including - * this one. */ + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the transaction does not share a common input with + * all previous funding transactions + */ list_for_each(&channel->inflights, inflight, list) { /* Remove every non-matching input from set */ for (size_t i = 0; i < candidate_psbt->num_inputs; i++) { @@ -1849,13 +1793,12 @@ static void handle_validate_rbf(struct subd *dualopend, assert(inflight); last_fee = psbt_compute_fee(inflight->funding_psbt); - /* BOLT-8edf819f1de3b110653f0b21594a04cfd03d5240 #2: - * - * The receiving node: - * - if this is an RBF attempt: - * - MUST fail the RBF attempt if: - * - the completed transaction's total fees paid - * is less than the last successful funding transaction's fees. + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - if is an RBF attempt: + * - MUST fail the negotiation if: + * - the transaction's total fees is less than the last + * successfully negotiated transaction's fees */ if (!amount_sat_greater(candidate_fee, last_fee)) { char *errmsg = tal_fmt(tmpctx, "Proposed funding tx fee (%s)" @@ -2721,8 +2664,6 @@ static void start_fresh_dualopend(struct peer *peer, pps, &channel->local_basepoints, &channel->local_funding_pubkey, channel->minimum_depth, - feerate_min(peer->ld, NULL), - feerate_max(peer->ld, NULL), send_msg); subd_send_msg(channel->owner, take(msg)); @@ -2794,8 +2735,6 @@ void peer_restart_dualopend(struct peer *peer, &channel->local_funding_pubkey, &channel->channel_info.remote_fundingkey, channel->minimum_depth, - feerate_min(peer->ld, NULL), - feerate_max(peer->ld, NULL), &inflight->funding->txid, inflight->funding->outnum, first_inflight->funding->feerate, diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 605a662712dc..fe937f7a47fa 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -73,8 +73,13 @@ enum tx_msgs { }; /* - * BOLT-544bda7144d91b3f51856189b8932610649f9e93 #2: - - MUST NOT send more than 2^12 ... messages + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: + * ... + * - MUST fail the negotiation if: ... + * - if has received 4096 `tx_add_input` messages during this negotiation + * ... + * - it has received 4096 `tx_add_output` messages during this negotiation */ #define MAX_TX_MSG_RCVD (1 << 12) @@ -131,7 +136,6 @@ struct state { /* Constraints on a channel they open. */ u32 minimum_depth; - u32 min_feerate, max_feerate; struct amount_msat min_effective_htlc_capacity; /* Limits on what remote config we accept. */ @@ -436,12 +440,13 @@ static void set_reserve(struct tx_state *tx_state, { struct amount_sat reserve, dust_limit; - /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * - * The channel reserve is fixed at 1% of the total channel balance - * rounded down (sum of `funding_satoshis` from `open_channel2` - * and `accept_channel2`) or the `dust_limit_satoshis` from - * `open_channel2`, whichever is greater. + * Instead, the channel reserve is fixed at 1% of the total + * channel balance (`open_channel2`.`funding_satoshis` + + * `accept_channel2`.`funding_satoshis`) rounded down to the + * nearest whole satoshi or the `dust_limit_satoshis`, whichever is + * greater. */ reserve = amount_sat_div(funding_total, 100); dust_limit = our_role == TX_INITIATOR ? @@ -459,14 +464,12 @@ static void set_reserve(struct tx_state *tx_state, static bool is_openers(const struct wally_map *unknowns) { - /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 - * The sending node: - * ... - * - if is the `initiator`: - * - MUST send even `serial_id`s - * - if is the `contributor`: - * ... - * - MUST send odd `serial_id`s + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The sending node: ... + * - if is the *initiator*: + * - MUST send even `serial_id`s + * - if is the *non-initiator*: + * - MUST send odd `serial_id`s */ u64 serial_id; if (!psbt_get_serial_id(unknowns, &serial_id)) @@ -487,7 +490,8 @@ static size_t psbt_input_weight(struct wally_psbt *psbt, (psbt->inputs[in].redeem_script_len + (varint_t) varint_size(psbt->inputs[in].redeem_script_len)) * 4; - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2 + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #3: + * * The minimum witness weight for an input is 110. */ weight += 110; @@ -530,10 +534,10 @@ static char *check_balances(const tal_t *ctx, size_t accepter_weight = 0; - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: - * The initiator is responsible for paying the fees - * for the following fields, to be referred to as - * the `common fields`. + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * + * The *initiator* is responsible for paying the fees for the + * following fields, to be referred to as the `common fields`. * - version * - segwit marker + flag * - input count @@ -562,12 +566,15 @@ static char *check_balances(const tal_t *ctx, return "overflow adding desired funding"; } - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: - * The receiving node: - * ... - * - MUST fail the channel if: - * ... - * - the value of the funding output is incorrect + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * + * Upon receipt of consecutive `tx_complete`s, the receiving + * node: + * - if is the *accepter*: + * - MUST fail the negotiation if: ... + * - the value of the funding output is not equal to the + * sum of `open_channel2`.`funding_satoshis` + * and `accept_channel2`. `funding_satoshis` */ if (!amount_sat_eq(total_funding, output_val)) { return tal_fmt(tmpctx, "total desired funding %s != " @@ -580,13 +587,14 @@ static char *check_balances(const tal_t *ctx, &output_val)); } - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: - * The receiving node: - * ... - * - MUST fail the channel if: - * ... - * - if the `funding_output` of the resulting - * transaction is less than the `dust_limit` + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * + * Upon receipt of consecutive `tx_complete`s, the receiving + * node: + * - if is the *accepter*: + * - MUST fail the negotiation if: ... + * - the value of the funding output is + * less than the `dust_limit` */ if (!amount_sat_greater(output_val, tx_state->remoteconf.dust_limit) || @@ -595,12 +603,13 @@ static char *check_balances(const tal_t *ctx, return "funding output is dust"; } } else { - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: - * The receiving node: - * ... - * - MUST fail the channel if: - * - no funding output is received, identified by - * the `script` + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * + * Upon receipt of consecutive `tx_complete`s, the receiving + * node: + * - if is the *accepter*: + * - MUST fail the negotiation if: + * - no funding output was received */ return "funding output not present"; } @@ -650,10 +659,13 @@ static char *check_balances(const tal_t *ctx, return "overflow adding output total"; } - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: - * The sending node: - * - MUST specify a `sats` value greater - * than the dust limit + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: + * ... + * - MUST fail the negotiation if: + * ... + * - the `sats` amount is less than or equal to + * the `dust_limit` */ if (!amount_sat_greater(amt, tx_state->remoteconf.dust_limit) || @@ -685,25 +697,25 @@ static char *check_balances(const tal_t *ctx, } } - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: - * The receiving node: ... - * - MUST fail the channel if: + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: + * ... + * - MUST fail the negotiation if: * ... - * - the total satoshis of the inputs is less than - * the outputs + * - the peer's total input satoshis is less than their outputs */ if (!amount_sat_greater_eq(tot_input_amt, tot_output_amt)) { return "inputs less than total outputs"; } - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * The receiving node: ... - * - MUST fail the channel if: + * - MUST fail the negotiation if: * ... - * - the peer's paid feerate does not meet or exceed - * the agreed `feerate`, (based on the miminum fee). - * - the `initiator`'s fees do not cover the `common` - * fields + * - the peer's paid feerate does not meet or exceed the + * agreed `feerate`, (based on the `minimum fee`). + * - if is the *non-initiator*: + * - the *initiator*'s fees do not cover the `common` fields */ if (!amount_sat_sub(&accepter_diff, accepter_inputs, accepter_outs)) { @@ -715,10 +727,13 @@ static char *check_balances(const tal_t *ctx, return "initiator inputs less than outputs"; } - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: - * Each party to the transaction is responsible for - * paying the fees for their input, output, - * and witness at the agreed `feerate`. */ + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: + * ... + * - the peer's paid feerate does not meet or exceed the + * agreed `feerate`, (based on the `minimum fee`). + */ accepter_fee = amount_tx_fee(feerate_per_kw_funding, accepter_weight); initiator_fee = amount_tx_fee(feerate_per_kw_funding, @@ -1264,32 +1279,31 @@ static bool run_tx_interactive(struct state *state, check_channel_id(state, &cid, &state->channel_id); /* - * BOLT-544bda7144d91b3f51856189b8932610649f9e93 #2: - * The receiving node: - * - MUST fail the transaction collaboration if: - * - it receives more than 2^12 `tx_add_input` - * messages */ + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - if has received 4096 `tx_add_input` + * messages during this negotiation + */ if (++tx_state->tx_msg_count[TX_ADD_INPUT] > MAX_TX_MSG_RCVD) open_err_warn(state, "Too many `tx_add_input`s" " received %d", MAX_TX_MSG_RCVD); /* - * BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2: - * - if is the `initiator`: - * - MUST send even `serial_id`s - * - MUST fail the transaction collaboration if: - * ... - * - it receives a `serial_id` from the peer - * with the incorrect parity + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the `serial_id` has the wrong parity */ if (serial_id % 2 == our_role) open_err_warn(state, "Invalid serial_id rcvd. %"PRIu64, serial_id); /* - * BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2: - * - MUST fail the transaction collaboration if: - * ... - * - it recieves a duplicate `serial_id` + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the `serial_id` is already included in + * the transaction */ if (psbt_find_serial_input(psbt, serial_id) != -1) open_err_warn(state, "Duplicate serial_id rcvd." @@ -1306,11 +1320,11 @@ static bool run_tx_interactive(struct state *state, "Invalid tx outnum sent. %u", outnum); /* - * BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2: - * - MUST fail the transaction collaboration if: - * ... - * - it receives an input that would create a - * malleable transaction id (e.g. pre-Segwit) + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the `prevtx_out` input of `prevtx` is + * not an `OP_0` to `OP_16` followed by a single push */ if (!is_segwit_output(&tx->wtx->outputs[outnum], redeemscript)) @@ -1321,14 +1335,12 @@ static bool run_tx_interactive(struct state *state, tx)); /* - * BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2: - * - MUST NOT re-transmit inputs it has already - * received from the peer - * ... - * - MUST fail the transaction collaboration if: - * ... - * - it receives a duplicate input to one it - * sent previously + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: + * - the `prevtx` and `prevtx_vout` are + * identical to a previously added (and not + * removed) input's */ bitcoin_txid(tx, &txid); if (psbt_has_input(psbt, &txid, outnum)) @@ -1341,10 +1353,9 @@ static bool run_tx_interactive(struct state *state, outnum); /* - * BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2: + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * The receiving node: - * - MUST add all received inputs to the funding - * transaction + * - MUST add all received inputs to the transaction */ struct wally_psbt_input *in = psbt_append_input(psbt, &txid, outnum, @@ -1392,27 +1403,23 @@ static bool run_tx_interactive(struct state *state, check_channel_id(state, &cid, &state->channel_id); - /* - * BOLT-544bda7144d91b3f51856189b8932610649f9e93 #2: - * The receiving node: - * - MUST fail the transaction collaboration if: - * - it receives more than 2^12 `tx_rm_input` - * messages */ - if (++tx_state->tx_msg_count[TX_RM_INPUT] > MAX_TX_MSG_RCVD) - open_err_warn(state, - "Too many `tx_rm_input`s" - " received (%d)", - MAX_TX_MSG_RCVD); - - /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 - * The sending node: - * - MUST NOT send a `tx_remove_input` for an - * input which is not theirs */ + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the input or output identified by the + * `serial_id` was not added by the sender + */ if (serial_id % 2 == our_role) open_err_warn(state, "Invalid serial_id rcvd. %"PRIu64, serial_id); + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the `serial_id` does not correspond + * to a currently added input (or output) + */ input_index = psbt_find_serial_input(psbt, serial_id); if (input_index == -1) open_err_warn(state, @@ -1436,34 +1443,46 @@ static bool run_tx_interactive(struct state *state, check_channel_id(state, &cid, &state->channel_id); /* - * BOLT-544bda7144d91b3f51856189b8932610649f9e93 #2: - * The receiving node: - * - MUST fail the transaction collaboration if: - * - it receives more than 2^12 `tx_add_output` - * messages */ + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - it has received 4096 `tx_add_output` + * messages during this negotiation + */ if (++tx_state->tx_msg_count[TX_ADD_OUTPUT] > MAX_TX_MSG_RCVD) open_err_warn(state, "Too many `tx_add_output`s" " received (%d)", MAX_TX_MSG_RCVD); - /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 - * The receiving node: - * ... - * - MUST fail the transaction collaboration if: - * ... - * - it receives a `serial_id` from the peer with the - * incorrect parity */ + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the `serial_id` has the wrong parity + */ if (serial_id % 2 == our_role) open_err_warn(state, "Invalid serial_id rcvd. %"PRIu64, serial_id); + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the `serial_id` is already included + * in the transaction */ if (psbt_find_serial_output(psbt, serial_id) != -1) open_err_warn(state, "Duplicate serial_id rcvd." " %"PRIu64, serial_id); amt = amount_sat(value); + + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MAY fail the negotiation if `script` + * is non-standard */ + if (!is_known_scripttype(scriptpubkey)) + open_err_warn(state, "Script is not standard"); + out = psbt_append_output(psbt, scriptpubkey, amt); psbt_output_set_serial_id(psbt, out, serial_id); break; @@ -1478,27 +1497,23 @@ static bool run_tx_interactive(struct state *state, check_channel_id(state, &cid, &state->channel_id); - /* - * BOLT-544bda7144d91b3f51856189b8932610649f9e93 #2: - * The receiving node: - * - MUST fail the transaction collaboration if: - * - it receives more than 2^12 `tx_rm_output` - * messages */ - if (++tx_state->tx_msg_count[TX_RM_OUTPUT] > MAX_TX_MSG_RCVD) - open_err_warn(state, - "Too many `tx_rm_output`s" - " received (%d)", - MAX_TX_MSG_RCVD); - - /* BOLT-fe0351ca2cea3105c4f2eb18c571afca9d21c85b #2 - * The sending node: - * - MUST NOT send a `tx_remove_ouput` for an - * input which is not theirs */ + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the input or output identified by the + * `serial_id` was not added by the sender + */ if (serial_id % 2 == our_role) open_err_warn(state, "Invalid serial_id rcvd." " %"PRIu64, serial_id); + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - the `serial_id` does not correspond to a + * currently added input (or output) + */ output_index = psbt_find_serial_output(psbt, serial_id); if (output_index == -1) open_err_warn(state, false, @@ -1839,7 +1854,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) u8 *msg; struct amount_sat total; enum dualopend_wire msg_type; - u32 feerate_min, feerate_max, feerate_best; struct tx_state *tx_state = state->tx_state; state->our_role = TX_ACCEPTER; @@ -1847,14 +1861,12 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) if (!fromwire_open_channel2(oc2_msg, &chain_hash, &state->channel_id, - &feerate_max, - &feerate_min, - &feerate_best, + &state->feerate_per_kw_funding, + &state->feerate_per_kw_commitment, &tx_state->opener_funding, &tx_state->remoteconf.dust_limit, &tx_state->remoteconf.max_htlc_value_in_flight, &tx_state->remoteconf.htlc_minimum, - &state->feerate_per_kw_commitment, &tx_state->remoteconf.to_self_delay, &tx_state->remoteconf.max_accepted_htlcs, &tx_state->tx_locktime, @@ -1875,6 +1887,9 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) } else state->upfront_shutdown_script[REMOTE] = NULL; + /* Save feerate on the tx_state as well */ + tx_state->feerate_per_kw_funding = state->feerate_per_kw_funding; + /* BOLT #2: * * The receiving node MUST fail the channel if: @@ -1918,9 +1933,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) tx_state->remoteconf.dust_limit, tx_state->remoteconf.max_htlc_value_in_flight, tx_state->remoteconf.htlc_minimum, - feerate_max, - feerate_min, - feerate_best, + state->feerate_per_kw_funding, state->feerate_per_kw_commitment, tx_state->remoteconf.to_self_delay, tx_state->remoteconf.max_accepted_htlcs, @@ -1941,7 +1954,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) if (!fromwire_dualopend_got_offer_reply(state, msg, &tx_state->accepter_funding, - &tx_state->feerate_per_kw_funding, &tx_state->psbt, &state->upfront_shutdown_script[LOCAL])) master_badmsg(WIRE_DUALOPEND_GOT_OFFER_REPLY, msg); @@ -2023,7 +2035,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) msg = towire_accept_channel2(tmpctx, &state->channel_id, tx_state->accepter_funding, - tx_state->feerate_per_kw_funding, tx_state->localconf.dust_limit, tx_state->localconf.max_htlc_value_in_flight, tx_state->localconf.htlc_minimum, @@ -2323,7 +2334,6 @@ static void opener_start(struct state *state, u8 *msg) struct channel_id cid; char *err_reason; struct amount_sat total; - u32 feerate_min, feerate_max, feerate_best; struct tx_state *tx_state = state->tx_state; if (!fromwire_dualopend_opener_init(state, msg, @@ -2331,12 +2341,13 @@ static void opener_start(struct state *state, u8 *msg) &tx_state->opener_funding, &state->upfront_shutdown_script[LOCAL], &state->feerate_per_kw_commitment, - &tx_state->feerate_per_kw_funding, + &state->feerate_per_kw_funding, &state->channel_flags)) master_badmsg(WIRE_DUALOPEND_OPENER_INIT, msg); state->our_role = TX_INITIATOR; tx_state->tx_locktime = tx_state->psbt->tx->locktime; + tx_state->feerate_per_kw_funding = state->feerate_per_kw_funding; open_tlv = tlv_opening_tlvs_new(tmpctx); /* Set the channel_id to a temporary id, we'll update @@ -2345,28 +2356,6 @@ static void opener_start(struct state *state, u8 *msg) * understand it */ temporary_channel_id(&state->channel_id); - feerate_min = state->min_feerate; - feerate_max = state->max_feerate; - if (tx_state->feerate_per_kw_funding > state->max_feerate) { - status_info("Selected funding feerate %d is greater than" - " current suggested max %d, adjusing max upwards" - " to match.", - tx_state->feerate_per_kw_funding, - state->max_feerate); - - feerate_max = tx_state->feerate_per_kw_funding; - } - if (tx_state->feerate_per_kw_funding < state->min_feerate) { - status_info("Selected funding feerate %d is less than" - " current suggested min %d, adjusing min downwards" - " to match.", - tx_state->feerate_per_kw_funding, - state->min_feerate); - - feerate_min = tx_state->feerate_per_kw_funding; - } - feerate_best = tx_state->feerate_per_kw_funding; - if (!state->upfront_shutdown_script[LOCAL]) state->upfront_shutdown_script[LOCAL] = no_upfront_shutdown_script(state, @@ -2384,14 +2373,12 @@ static void opener_start(struct state *state, u8 *msg) msg = towire_open_channel2(NULL, &chainparams->genesis_blockhash, &state->channel_id, - feerate_max, - feerate_min, - feerate_best, + state->feerate_per_kw_funding, + state->feerate_per_kw_commitment, tx_state->opener_funding, tx_state->localconf.dust_limit, tx_state->localconf.max_htlc_value_in_flight, tx_state->localconf.htlc_minimum, - state->feerate_per_kw_commitment, tx_state->localconf.to_self_delay, tx_state->localconf.max_accepted_htlcs, tx_state->tx_locktime, @@ -2418,7 +2405,6 @@ static void opener_start(struct state *state, u8 *msg) a_tlv = notleak(tlv_accept_tlvs_new(state)); if (!fromwire_accept_channel2(msg, &cid, &tx_state->accepter_funding, - &tx_state->feerate_per_kw_funding, &tx_state->remoteconf.dust_limit, &tx_state->remoteconf.max_htlc_value_in_flight, &tx_state->remoteconf.htlc_minimum, @@ -2443,10 +2429,6 @@ static void opener_start(struct state *state, u8 *msg) } else state->upfront_shutdown_script[REMOTE] = NULL; - /* Copy the feerate per kw into the state struct as well; this is - * the original feerate we'll use to base RBF upgrades on */ - state->feerate_per_kw_funding = tx_state->feerate_per_kw_funding; - /* Now we can set the 'real channel id' */ derive_channel_id_v2(&state->channel_id, &state->our_points.revocation, @@ -2460,20 +2442,6 @@ static void opener_start(struct state *state, u8 *msg) &state->channel_id), type_to_string(msg, struct channel_id, &cid)); - /* BOLT-5fcbda56901af9e3b1d057cc41d0c5cfa60a2b94 #2: - * The receiving node: - * - if the `feerate_funding` is less than the `feerate_funding_min` - * or above the `feerate_funding_max` - * - MUST error. - */ - if (feerate_min > tx_state->feerate_per_kw_funding - || feerate_max < tx_state->feerate_per_kw_funding) - open_err_warn(state, "Invalid feerate %d chosen. Valid min %d," - " valid max %d", - tx_state->feerate_per_kw_funding, - feerate_min, feerate_max); - - /* Check that total funding doesn't overflow */ if (!amount_sat_add(&total, tx_state->opener_funding, tx_state->accepter_funding)) @@ -2502,11 +2470,11 @@ static void opener_start(struct state *state, u8 *msg) return; } - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * The sending node: - * - if is the `opener`: - * - MUST send at least one `tx_add_output`, the channel - * funding output. + * - if is the *opener*: + * - MUST send at least one `tx_add_output`, which + * contains the channel's funding output */ add_funding_output(tx_state, state, total); @@ -2560,12 +2528,18 @@ static bool update_feerate(struct tx_state *tx_state, u32 feerate = feerate_funding; /* - * BOLT-487dd4b46aad9b59f7f3480b7bdf15862b52d2f9b #2: - * Each `fee_step` adds 1/4 (rounded down) to the initial - * transaction feerate, i.e. if the initial `feerate_per_kw_funding` - * was 512 satoshis per kiloweight, `fee_step` 1 is - * 512 + 512 / 4 or 640 sat/kw, `fee_step` 2 - * is 640 + 640 / 4 or 800 sat/kw. + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * + * `fee_step` is an integer value, which specifies the + * `feerate` for this funding transaction, as a rate of + * increase above the `open_channel2`. `funding_feerate_perkw`. + * + * The effective `funding_feerate_perkw` for this RBF attempt + * if calculated as 1.25^`fee_step` * `funding_feerate_perkw`. + * E.g. if `feerate_per_kw_funding` is 512 and the `fee_step` is 1, + * the effective `feerate` for this RBF attempt is 512 + 512 / 4 + * or 640 sat/kw. A `fee_step` 2 would be `1.25^2 * 512` + * (or 640 + 640 / 4), 800 sat/kw. */ for (; fee_step > 0; fee_step--) feerate += feerate / 4; @@ -2602,12 +2576,11 @@ static void rbf_wrap_up(struct state *state, char *err_reason; u8 *msg; - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2: + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * The sending node: - * - if is the `opener`: - * - MUST send at least one `tx_add_output`, the channel - * funding output. - */ + * - if is the *opener*: + * - MUST send at least one `tx_add_output`, which contains the + * channel's funding output */ if (state->our_role == TX_INITIATOR) add_funding_output(tx_state, state, total); else @@ -3424,8 +3397,6 @@ int main(int argc, char *argv[]) &state->our_points, &state->our_funding_pubkey, &state->minimum_depth, - &state->min_feerate, - &state->max_feerate, &inner)) { /*~ Initially we're not associated with a channel, but * handle_peer_gossip_or_error compares this. */ @@ -3460,8 +3431,6 @@ int main(int argc, char *argv[]) &state->our_funding_pubkey, &state->their_funding_pubkey, &state->minimum_depth, - &state->min_feerate, - &state->max_feerate, &state->tx_state->funding_txid, &state->tx_state->funding_txout, &state->feerate_per_kw_funding, diff --git a/openingd/dualopend_wire.csv b/openingd/dualopend_wire.csv index baa766addc35..0608f57f60c8 100644 --- a/openingd/dualopend_wire.csv +++ b/openingd/dualopend_wire.csv @@ -26,8 +26,6 @@ msgdata,dualopend_init,our_basepoints,basepoints, msgdata,dualopend_init,our_funding_pubkey,pubkey, # Constraints in case the other end tries to open a channel. msgdata,dualopend_init,minimum_depth,u32, -msgdata,dualopend_init,min_feerate,u32, -msgdata,dualopend_init,max_feerate,u32, # Optional msg to send. msgdata,dualopend_init,len,u16, msgdata,dualopend_init,msg,u8,len @@ -48,8 +46,6 @@ msgdata,dualopend_reinit,our_basepoints,basepoints, msgdata,dualopend_reinit,our_funding_pubkey,pubkey, msgdata,dualopend_reinit,their_funding_pubkey,pubkey, msgdata,dualopend_reinit,minimum_depth,u32, -msgdata,dualopend_reinit,min_feerate,u32, -msgdata,dualopend_reinit,max_feerate,u32, msgdata,dualopend_reinit,funding_txid,bitcoin_txid, msgdata,dualopend_reinit,funding_txout,u16, msgdata,dualopend_reinit,orignal_feerate_per_kw_funding,u32, @@ -82,10 +78,8 @@ msgdata,dualopend_got_offer,opener_funding,amount_sat, msgdata,dualopend_got_offer,dust_limit_satoshis,amount_sat, msgdata,dualopend_got_offer,max_htlc_value_in_flight_msat,amount_msat, msgdata,dualopend_got_offer,htlc_minimum_msat,amount_msat, -msgdata,dualopend_got_offer,feerate_funding_max,u32, -msgdata,dualopend_got_offer,feerate_funding_min,u32, -msgdata,dualopend_got_offer,feerate_funding_best,u32, -msgdata,dualopend_got_offer,feerate_per_kw,u32, +msgdata,dualopend_got_offer,feerate_per_kw_funding,u32, +msgdata,dualopend_got_offer,feerate_per_kw_commitment,u32, msgdata,dualopend_got_offer,to_self_delay,u16, msgdata,dualopend_got_offer,max_accepted_htlcs,u16, msgdata,dualopend_got_offer,channel_flags,u8, @@ -96,7 +90,6 @@ msgdata,dualopend_got_offer,shutdown_scriptpubkey,u8,shutdown_len # master->dualopend: reply back with our first funding info/contribs msgtype,dualopend_got_offer_reply,7105 msgdata,dualopend_got_offer_reply,accepter_funding,amount_sat, -msgdata,dualopend_got_offer_reply,feerate_funding,u32, msgdata,dualopend_got_offer_reply,psbt,wally_psbt, msgdata,dualopend_got_offer_reply,shutdown_len,u16, msgdata,dualopend_got_offer_reply,our_shutdown_scriptpubkey,?u8,shutdown_len diff --git a/openingd/dualopend_wiregen.c b/openingd/dualopend_wiregen.c index 52c29589b9aa..e354eca37b0c 100644 --- a/openingd/dualopend_wiregen.c +++ b/openingd/dualopend_wiregen.c @@ -91,7 +91,7 @@ bool dualopend_wire_is_defined(u16 type) /* WIRE: DUALOPEND_INIT */ -u8 *towire_dualopend_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, u32 minimum_depth, u32 min_feerate, u32 max_feerate, const u8 *msg) +u8 *towire_dualopend_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, u32 minimum_depth, const u8 *msg) { u16 their_init_features_len = tal_count(their_init_features); u16 len = tal_count(msg); @@ -113,15 +113,13 @@ u8 *towire_dualopend_init(const tal_t *ctx, const struct chainparams *chainparam towire_pubkey(&p, our_funding_pubkey); /* Constraints in case the other end tries to open a channel. */ towire_u32(&p, minimum_depth); - towire_u32(&p, min_feerate); - towire_u32(&p, max_feerate); /* Optional msg to send. */ towire_u16(&p, len); towire_u8_array(&p, msg, len); return memcheck(p, tal_count(p)); } -bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, u32 *minimum_depth, u32 *min_feerate, u32 *max_feerate, u8 **msg) +bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, u32 *minimum_depth, u8 **msg) { u16 their_init_features_len; u16 len; @@ -148,8 +146,6 @@ bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chain fromwire_pubkey(&cursor, &plen, our_funding_pubkey); /* Constraints in case the other end tries to open a channel. */ *minimum_depth = fromwire_u32(&cursor, &plen); - *min_feerate = fromwire_u32(&cursor, &plen); - *max_feerate = fromwire_u32(&cursor, &plen); /* Optional msg to send. */ len = fromwire_u16(&cursor, &plen); // 2nd case msg @@ -160,7 +156,7 @@ bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chain /* WIRE: DUALOPEND_REINIT */ /* master-dualopend: peer has reconnected */ -u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, u32 min_feerate, u32 max_feerate, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 orignal_feerate_per_kw_funding, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags, const u8 *msg) +u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 orignal_feerate_per_kw_funding, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags, const u8 *msg) { u16 their_init_features_len = tal_count(their_init_features); u16 local_shutdown_len = tal_count(local_shutdown_scriptpubkey); @@ -183,8 +179,6 @@ u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainpar towire_pubkey(&p, our_funding_pubkey); towire_pubkey(&p, their_funding_pubkey); towire_u32(&p, minimum_depth); - towire_u32(&p, min_feerate); - towire_u32(&p, max_feerate); towire_bitcoin_txid(&p, funding_txid); towire_u16(&p, funding_txout); towire_u32(&p, orignal_feerate_per_kw_funding); @@ -212,7 +206,7 @@ u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainpar return memcheck(p, tal_count(p)); } -bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, u32 *min_feerate, u32 *max_feerate, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *orignal_feerate_per_kw_funding, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags, u8 **msg) +bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *orignal_feerate_per_kw_funding, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags, u8 **msg) { u16 their_init_features_len; u16 local_shutdown_len; @@ -240,8 +234,6 @@ bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct cha fromwire_pubkey(&cursor, &plen, our_funding_pubkey); fromwire_pubkey(&cursor, &plen, their_funding_pubkey); *minimum_depth = fromwire_u32(&cursor, &plen); - *min_feerate = fromwire_u32(&cursor, &plen); - *max_feerate = fromwire_u32(&cursor, &plen); fromwire_bitcoin_txid(&cursor, &plen, funding_txid); *funding_txout = fromwire_u16(&cursor, &plen); *orignal_feerate_per_kw_funding = fromwire_u32(&cursor, &plen); @@ -277,7 +269,7 @@ bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct cha /* WIRE: DUALOPEND_GOT_OFFER */ /* dualopend->master: they offered channel */ -u8 *towire_dualopend_got_offer(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat opener_funding, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_msat htlc_minimum_msat, u32 feerate_funding_max, u32 feerate_funding_min, u32 feerate_funding_best, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, u32 locktime, const u8 *shutdown_scriptpubkey) +u8 *towire_dualopend_got_offer(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat opener_funding, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_msat htlc_minimum_msat, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, u32 locktime, const u8 *shutdown_scriptpubkey) { u16 shutdown_len = tal_count(shutdown_scriptpubkey); u8 *p = tal_arr(ctx, u8, 0); @@ -288,10 +280,8 @@ u8 *towire_dualopend_got_offer(const tal_t *ctx, const struct channel_id *channe towire_amount_sat(&p, dust_limit_satoshis); towire_amount_msat(&p, max_htlc_value_in_flight_msat); towire_amount_msat(&p, htlc_minimum_msat); - towire_u32(&p, feerate_funding_max); - towire_u32(&p, feerate_funding_min); - towire_u32(&p, feerate_funding_best); - towire_u32(&p, feerate_per_kw); + towire_u32(&p, feerate_per_kw_funding); + towire_u32(&p, feerate_per_kw_commitment); towire_u16(&p, to_self_delay); towire_u16(&p, max_accepted_htlcs); towire_u8(&p, channel_flags); @@ -301,7 +291,7 @@ u8 *towire_dualopend_got_offer(const tal_t *ctx, const struct channel_id *channe return memcheck(p, tal_count(p)); } -bool fromwire_dualopend_got_offer(const tal_t *ctx, const void *p, struct channel_id *channel_id, struct amount_sat *opener_funding, struct amount_sat *dust_limit_satoshis, struct amount_msat *max_htlc_value_in_flight_msat, struct amount_msat *htlc_minimum_msat, u32 *feerate_funding_max, u32 *feerate_funding_min, u32 *feerate_funding_best, u32 *feerate_per_kw, u16 *to_self_delay, u16 *max_accepted_htlcs, u8 *channel_flags, u32 *locktime, u8 **shutdown_scriptpubkey) +bool fromwire_dualopend_got_offer(const tal_t *ctx, const void *p, struct channel_id *channel_id, struct amount_sat *opener_funding, struct amount_sat *dust_limit_satoshis, struct amount_msat *max_htlc_value_in_flight_msat, struct amount_msat *htlc_minimum_msat, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, u16 *to_self_delay, u16 *max_accepted_htlcs, u8 *channel_flags, u32 *locktime, u8 **shutdown_scriptpubkey) { u16 shutdown_len; @@ -315,10 +305,8 @@ bool fromwire_dualopend_got_offer(const tal_t *ctx, const void *p, struct channe *dust_limit_satoshis = fromwire_amount_sat(&cursor, &plen); *max_htlc_value_in_flight_msat = fromwire_amount_msat(&cursor, &plen); *htlc_minimum_msat = fromwire_amount_msat(&cursor, &plen); - *feerate_funding_max = fromwire_u32(&cursor, &plen); - *feerate_funding_min = fromwire_u32(&cursor, &plen); - *feerate_funding_best = fromwire_u32(&cursor, &plen); - *feerate_per_kw = fromwire_u32(&cursor, &plen); + *feerate_per_kw_funding = fromwire_u32(&cursor, &plen); + *feerate_per_kw_commitment = fromwire_u32(&cursor, &plen); *to_self_delay = fromwire_u16(&cursor, &plen); *max_accepted_htlcs = fromwire_u16(&cursor, &plen); *channel_flags = fromwire_u8(&cursor, &plen); @@ -332,21 +320,20 @@ bool fromwire_dualopend_got_offer(const tal_t *ctx, const void *p, struct channe /* WIRE: DUALOPEND_GOT_OFFER_REPLY */ /* master->dualopend: reply back with our first funding info/contribs */ -u8 *towire_dualopend_got_offer_reply(const tal_t *ctx, struct amount_sat accepter_funding, u32 feerate_funding, const struct wally_psbt *psbt, const u8 *our_shutdown_scriptpubkey) +u8 *towire_dualopend_got_offer_reply(const tal_t *ctx, struct amount_sat accepter_funding, const struct wally_psbt *psbt, const u8 *our_shutdown_scriptpubkey) { u16 shutdown_len = tal_count(our_shutdown_scriptpubkey); u8 *p = tal_arr(ctx, u8, 0); towire_u16(&p, WIRE_DUALOPEND_GOT_OFFER_REPLY); towire_amount_sat(&p, accepter_funding); - towire_u32(&p, feerate_funding); towire_wally_psbt(&p, psbt); towire_u16(&p, shutdown_len); towire_u8_array(&p, our_shutdown_scriptpubkey, shutdown_len); return memcheck(p, tal_count(p)); } -bool fromwire_dualopend_got_offer_reply(const tal_t *ctx, const void *p, struct amount_sat *accepter_funding, u32 *feerate_funding, struct wally_psbt **psbt, u8 **our_shutdown_scriptpubkey) +bool fromwire_dualopend_got_offer_reply(const tal_t *ctx, const void *p, struct amount_sat *accepter_funding, struct wally_psbt **psbt, u8 **our_shutdown_scriptpubkey) { u16 shutdown_len; @@ -356,7 +343,6 @@ bool fromwire_dualopend_got_offer_reply(const tal_t *ctx, const void *p, struct if (fromwire_u16(&cursor, &plen) != WIRE_DUALOPEND_GOT_OFFER_REPLY) return false; *accepter_funding = fromwire_amount_sat(&cursor, &plen); - *feerate_funding = fromwire_u32(&cursor, &plen); *psbt = fromwire_wally_psbt(ctx, &cursor, &plen); shutdown_len = fromwire_u16(&cursor, &plen); // 2nd case our_shutdown_scriptpubkey @@ -946,4 +932,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak) *leak = fromwire_bool(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:407d42d23a8c3b4526b63fdbb572a1d8e75b4e7e390e13af018e289e5ac857cd +// SHA256STAMP:b93c5d3aad8cc2f256ed1205341ff68ea34d5bfc4a0d05071a8fe28177186bc5 diff --git a/openingd/dualopend_wiregen.h b/openingd/dualopend_wiregen.h index 0cfb1b2787f4..f1de1c45f48e 100644 --- a/openingd/dualopend_wiregen.h +++ b/openingd/dualopend_wiregen.h @@ -86,23 +86,23 @@ bool dualopend_wire_is_defined(u16 type); /* WIRE: DUALOPEND_INIT */ -u8 *towire_dualopend_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, u32 minimum_depth, u32 min_feerate, u32 max_feerate, const u8 *msg); -bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, u32 *minimum_depth, u32 *min_feerate, u32 *max_feerate, u8 **msg); +u8 *towire_dualopend_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, u32 minimum_depth, const u8 *msg); +bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, u32 *minimum_depth, u8 **msg); /* WIRE: DUALOPEND_REINIT */ /* master-dualopend: peer has reconnected */ -u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, u32 min_feerate, u32 max_feerate, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 orignal_feerate_per_kw_funding, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags, const u8 *msg); -bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, u32 *min_feerate, u32 *max_feerate, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *orignal_feerate_per_kw_funding, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags, u8 **msg); +u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 orignal_feerate_per_kw_funding, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags, const u8 *msg); +bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *orignal_feerate_per_kw_funding, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags, u8 **msg); /* WIRE: DUALOPEND_GOT_OFFER */ /* dualopend->master: they offered channel */ -u8 *towire_dualopend_got_offer(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat opener_funding, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_msat htlc_minimum_msat, u32 feerate_funding_max, u32 feerate_funding_min, u32 feerate_funding_best, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, u32 locktime, const u8 *shutdown_scriptpubkey); -bool fromwire_dualopend_got_offer(const tal_t *ctx, const void *p, struct channel_id *channel_id, struct amount_sat *opener_funding, struct amount_sat *dust_limit_satoshis, struct amount_msat *max_htlc_value_in_flight_msat, struct amount_msat *htlc_minimum_msat, u32 *feerate_funding_max, u32 *feerate_funding_min, u32 *feerate_funding_best, u32 *feerate_per_kw, u16 *to_self_delay, u16 *max_accepted_htlcs, u8 *channel_flags, u32 *locktime, u8 **shutdown_scriptpubkey); +u8 *towire_dualopend_got_offer(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat opener_funding, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_msat htlc_minimum_msat, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, u32 locktime, const u8 *shutdown_scriptpubkey); +bool fromwire_dualopend_got_offer(const tal_t *ctx, const void *p, struct channel_id *channel_id, struct amount_sat *opener_funding, struct amount_sat *dust_limit_satoshis, struct amount_msat *max_htlc_value_in_flight_msat, struct amount_msat *htlc_minimum_msat, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, u16 *to_self_delay, u16 *max_accepted_htlcs, u8 *channel_flags, u32 *locktime, u8 **shutdown_scriptpubkey); /* WIRE: DUALOPEND_GOT_OFFER_REPLY */ /* master->dualopend: reply back with our first funding info/contribs */ -u8 *towire_dualopend_got_offer_reply(const tal_t *ctx, struct amount_sat accepter_funding, u32 feerate_funding, const struct wally_psbt *psbt, const u8 *our_shutdown_scriptpubkey); -bool fromwire_dualopend_got_offer_reply(const tal_t *ctx, const void *p, struct amount_sat *accepter_funding, u32 *feerate_funding, struct wally_psbt **psbt, u8 **our_shutdown_scriptpubkey); +u8 *towire_dualopend_got_offer_reply(const tal_t *ctx, struct amount_sat accepter_funding, const struct wally_psbt *psbt, const u8 *our_shutdown_scriptpubkey); +bool fromwire_dualopend_got_offer_reply(const tal_t *ctx, const void *p, struct amount_sat *accepter_funding, struct wally_psbt **psbt, u8 **our_shutdown_scriptpubkey); /* WIRE: DUALOPEND_GOT_RBF_OFFER */ /* dualopend->master: they offered a RBF */ @@ -216,4 +216,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak); #endif /* LIGHTNING_OPENINGD_DUALOPEND_WIREGEN_H */ -// SHA256STAMP:407d42d23a8c3b4526b63fdbb572a1d8e75b4e7e390e13af018e289e5ac857cd +// SHA256STAMP:b93c5d3aad8cc2f256ed1205341ff68ea34d5bfc4a0d05071a8fe28177186bc5 diff --git a/plugins/spender/multifundchannel.c b/plugins/spender/multifundchannel.c index 081a5f87b712..f354497f3b18 100644 --- a/plugins/spender/multifundchannel.c +++ b/plugins/spender/multifundchannel.c @@ -741,7 +741,7 @@ perform_fundpsbt(struct multifundchannel_command *mfc) } /* If we've got v2 opens, we need to use a min weight of 110. */ - /* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2 + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #3: * The minimum witness weight for an input is 110. */ if (dest_count(mfc, OPEN_CHANNEL) > 0) { diff --git a/tests/plugins/df_accepter.py b/tests/plugins/df_accepter.py index 5c708b4275f0..31b0ede6ced1 100755 --- a/tests/plugins/df_accepter.py +++ b/tests/plugins/df_accepter.py @@ -13,20 +13,6 @@ plugin = Plugin() -def find_feerate(best, their_min, their_max, our_min, our_max): - if best >= our_min and best <= our_max: - return best - - if their_max < our_min or their_min > our_max: - return False - - if best < our_min: - return our_min - - # best > our_max: - return our_max - - def find_inputs(b64_psbt): serial_id_key = bytes.fromhex('fc096c696768746e696e6701') psbt = psbt_from_base64(b64_psbt) @@ -106,20 +92,18 @@ def on_openchannel(openchannel2, plugin, **kwargs): return {'result': 'continue'} # ...unless they send us totally unacceptable feerates. - feerate = find_feerate(openchannel2['funding_feerate_best'], - openchannel2['funding_feerate_min'], - openchannel2['funding_feerate_max'], - openchannel2['feerate_our_min'], - openchannel2['feerate_our_max']) + proposed_feerate = openchannel2['funding_feerate_per_kw'] + our_min = openchannel2['feerate_our_min'] + our_max = openchannel2['feerate_our_max'] # Their feerate range is out of bounds, we're not going to # participate. - if not feerate: - plugin.log("Declining to fund, no feerate found.") + if proposed_feerate > our_max or proposed_feerate < our_min: + plugin.log("Declining to fund, feerate unacceptable.") return {'result': 'continue'} funding = plugin.rpc.fundpsbt(int(amount.to_satoshi()), - '{}perkw'.format(feerate), + '{}perkw'.format(proposed_feerate), 0, # because we're the accepter!! reserve=True, locktime=locktime, @@ -128,11 +112,10 @@ def on_openchannel(openchannel2, plugin, **kwargs): excess_as_change=True) add_inflight(plugin, openchannel2['id'], openchannel2['channel_id'], funding['psbt']) - plugin.log("contributing {} at feerate {}".format(amount, feerate)) + plugin.log("contributing {} at feerate {}".format(amount, proposed_feerate)) return {'result': 'continue', 'psbt': funding['psbt'], - 'accepter_funding_msat': amount, - 'funding_feerate': feerate} + 'accepter_funding_msat': amount} @plugin.hook('openchannel2_changed') diff --git a/wire/extracted_peer_exp_dual_fund_more.patch b/wire/extracted_peer_exp_dual_fund_more.patch deleted file mode 100644 index 95c4c8c14a48..000000000000 --- a/wire/extracted_peer_exp_dual_fund_more.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- wire/peer_exp_wire.csv 2020-09-16 20:59:05.170975876 -0500 -+++ - 2020-10-22 16:56:33.413063210 -0500 -@@ -33,7 +33,7 @@ - tlvdata,n2,tlv2,cltv_expiry,tu32, - msgtype,tx_add_input,66 - msgdata,tx_add_input,channel_id,channel_id, --msgdata,tx_add_input,serial_id,u16, -+msgdata,tx_add_input,serial_id,u64, - msgdata,tx_add_input,prevtx_len,u16, - msgdata,tx_add_input,prevtx,byte,prevtx_len - msgdata,tx_add_input,prevtx_vout,u32, -@@ -48,16 +48,16 @@ - msgdata,tx_add_input,script,byte,redeemscript_len - msgtype,tx_add_output,67 - msgdata,tx_add_output,channel_id,channel_id, --msgdata,tx_add_output,serial_id,u16, -+msgdata,tx_add_output,serial_id,u64, - msgdata,tx_add_output,sats,u64, - msgdata,tx_add_output,scriptlen,u16, - msgdata,tx_add_output,script,byte,scriptlen - msgtype,tx_remove_input,68 - msgdata,tx_remove_input,channel_id,channel_id, --msgdata,tx_remove_input,serial_id,u16, -+msgdata,tx_remove_input,serial_id,u64, - msgtype,tx_remove_output,69 - msgdata,tx_remove_output,channel_id,channel_id, --msgdata,tx_remove_output,serial_id,u16, -+msgdata,tx_remove_output,serial_id,u64, - msgtype,tx_complete,70 - msgdata,tx_complete,channel_id,channel_id, - msgtype,tx_signatures,71 -@@ -125,7 +125,9 @@ - msgdata,funding_locked,next_per_commitment_point,point, - msgtype,open_channel2,64 - msgdata,open_channel2,chain_hash,chain_hash, --msgdata,open_channel2,feerate_per_kw_funding,u32, -+msgdata,open_channel2,feerate_funding_max,u32, -+msgdata,open_channel2,feerate_funding_min,u32, -+msgdata,open_channel2,feerate_funding_best,u32, - msgdata,open_channel2,funding_satoshis,u64, - msgdata,open_channel2,dust_limit_satoshis,u64, - msgdata,open_channel2,max_htlc_value_in_flight_msat,u64, -@@ -148,6 +150,7 @@ - msgtype,accept_channel2,65 - msgdata,accept_channel2,channel_id,channel_id, - msgdata,accept_channel2,funding_satoshis,u64, -+msgdata,accept_channel2,feerate_funding,u32, - msgdata,accept_channel2,dust_limit_satoshis,u64, - msgdata,accept_channel2,max_htlc_value_in_flight_msat,u64, - msgdata,accept_channel2,htlc_minimum_msat,u64, diff --git a/wire/extracted_peer_exp_dual_fund.patch b/wire/extracted_peer_exp_openchannelv2.patch similarity index 83% rename from wire/extracted_peer_exp_dual_fund.patch rename to wire/extracted_peer_exp_openchannelv2.patch index 599f7a7d8d7f..3c233e3e682a 100644 --- a/wire/extracted_peer_exp_dual_fund.patch +++ b/wire/extracted_peer_exp_openchannelv2.patch @@ -1,30 +1,30 @@ ---- wire/extracted_peer_wire_csv 2020-07-28 12:36:12.063168014 -0500 -+++ - 2020-08-31 21:00:40.856646471 -0500 -@@ -31,6 +31,40 @@ +--- wire/peer_exp_wire.csv 2021-03-03 15:46:56.845901075 -0600 ++++ - 2021-03-03 15:48:50.342984083 -0600 +@@ -35,6 +31,40 @@ tlvdata,n2,tlv1,amount_msat,tu64, tlvtype,n2,tlv2,11 tlvdata,n2,tlv2,cltv_expiry,tu32, +msgtype,tx_add_input,66 +msgdata,tx_add_input,channel_id,channel_id, -+msgdata,tx_add_input,serial_id,u16, ++msgdata,tx_add_input,serial_id,u64, +msgdata,tx_add_input,prevtx_len,u16, +msgdata,tx_add_input,prevtx,byte,prevtx_len +msgdata,tx_add_input,prevtx_vout,u32, +msgdata,tx_add_input,sequence,u32, -+msgdata,tx_add_input,redeemscript_len,u16, -+msgdata,tx_add_input,script,byte,redeemscript_len ++msgdata,tx_add_input,script_sig_len,u16, ++msgdata,tx_add_input,script_sig,byte,script_sig_len +msgtype,tx_add_output,67 +msgdata,tx_add_output,channel_id,channel_id, -+msgdata,tx_add_output,serial_id,u16, ++msgdata,tx_add_output,serial_id,u64, +msgdata,tx_add_output,sats,u64, +msgdata,tx_add_output,scriptlen,u16, +msgdata,tx_add_output,script,byte,scriptlen +msgtype,tx_remove_input,68 +msgdata,tx_remove_input,channel_id,channel_id, -+msgdata,tx_remove_input,serial_id,u16, ++msgdata,tx_remove_input,serial_id,u64, +msgtype,tx_remove_output,69 +msgdata,tx_remove_output,channel_id,channel_id, -+msgdata,tx_remove_output,serial_id,u16, ++msgdata,tx_remove_output,serial_id,u64, +msgtype,tx_complete,70 +msgdata,tx_complete,channel_id,channel_id, +msgtype,tx_signatures,71 @@ -41,18 +41,19 @@ msgtype,open_channel,32 msgdata,open_channel,chain_hash,chain_hash, msgdata,open_channel,temporary_channel_id,byte,32 -@@ -82,6 +122,53 @@ +@@ -86,6 +116,56 @@ msgtype,funding_locked,36 msgdata,funding_locked,channel_id,channel_id, msgdata,funding_locked,next_per_commitment_point,point, +msgtype,open_channel2,64 +msgdata,open_channel2,chain_hash,chain_hash, -+msgdata,open_channel2,feerate_per_kw_funding,u32, ++msgdata,open_channel2,channel_id,channel_id, ++msgdata,open_channel2,funding_feerate_perkw,u32, ++msgdata,open_channel2,commitment_feerate_perkw,u32, +msgdata,open_channel2,funding_satoshis,u64, +msgdata,open_channel2,dust_limit_satoshis,u64, +msgdata,open_channel2,max_htlc_value_in_flight_msat,u64, +msgdata,open_channel2,htlc_minimum_msat,u64, -+msgdata,open_channel2,feerate_per_kw,u32, +msgdata,open_channel2,to_self_delay,u16, +msgdata,open_channel2,max_accepted_htlcs,u16, +msgdata,open_channel2,locktime,u32, @@ -63,7 +64,7 @@ +msgdata,open_channel2,htlc_basepoint,point, +msgdata,open_channel2,first_per_commitment_point,point, +msgdata,open_channel2,channel_flags,byte, -+msgdata,open_channel2,opening_tlv,opening_tlvs, ++msgdata,open_channel2,tlvs,opening_tlvs, +tlvtype,opening_tlvs,option_upfront_shutdown_script,1 +tlvdata,opening_tlvs,option_upfront_shutdown_script,shutdown_len,u16, +tlvdata,opening_tlvs,option_upfront_shutdown_script,shutdown_scriptpubkey,byte,shutdown_len @@ -82,7 +83,7 @@ +msgdata,accept_channel2,delayed_payment_basepoint,point, +msgdata,accept_channel2,htlc_basepoint,point, +msgdata,accept_channel2,first_per_commitment_point,point, -+msgdata,accept_channel2,accept_tlv,accept_tlvs, ++msgdata,accept_channel2,tlvs,accept_tlvs, +tlvtype,accept_tlvs,option_upfront_shutdown_script,1 +tlvdata,accept_tlvs,option_upfront_shutdown_script,shutdown_len,u16, +tlvdata,accept_tlvs,option_upfront_shutdown_script,shutdown_scriptpubkey,byte,shutdown_len @@ -90,8 +91,10 @@ +msgdata,init_rbf,channel_id,channel_id, +msgdata,init_rbf,funding_satoshis,u64, +msgdata,init_rbf,locktime,u32, -+msgdata,init_rbf,feerate_per_kw,u32, +msgdata,init_rbf,fee_step,byte, ++msgtype,ack_rbf,73 ++msgdata,ack_rbf,channel_id,channel_id, ++msgdata,ack_rbf,funding_satoshis,u64, msgtype,shutdown,38 msgdata,shutdown,channel_id,channel_id, msgdata,shutdown,len,u16, diff --git a/wire/extracted_peer_exp_tmp_chan_id.patch b/wire/extracted_peer_exp_tmp_chan_id.patch deleted file mode 100644 index 44536a3b6577..000000000000 --- a/wire/extracted_peer_exp_tmp_chan_id.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- wire/peer_exp_wire.csv 2020-11-19 17:11:03.375890549 -0600 -+++ - 2020-12-10 15:56:19.617197279 -0600 -@@ -124,6 +124,7 @@ - msgdata,funding_locked,next_per_commitment_point,point, - msgtype,open_channel2,64 - msgdata,open_channel2,chain_hash,chain_hash, -+msgdata,open_channel2,temporary_channel_id,byte,32 - msgdata,open_channel2,feerate_funding_max,u32, - msgdata,open_channel2,feerate_funding_min,u32, - msgdata,open_channel2,feerate_funding_best,u32, diff --git a/wire/extracted_peer_experimental_dual_fund_more_more.patch b/wire/extracted_peer_experimental_dual_fund_more_more.patch deleted file mode 100644 index 413870ecc634..000000000000 --- a/wire/extracted_peer_experimental_dual_fund_more_more.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- wire/peer_exp_wire.csv 2021-01-07 19:57:53.230947150 -0600 -+++ - 2021-01-08 15:17:40.600855619 -0600 -@@ -172,8 +172,10 @@ - msgdata,init_rbf,channel_id,channel_id, - msgdata,init_rbf,funding_satoshis,u64, - msgdata,init_rbf,locktime,u32, --msgdata,init_rbf,feerate_per_kw,u32, - msgdata,init_rbf,fee_step,byte, -+msgtype,ack_rbf,73 -+msgdata,ack_rbf,channel_id,channel_id, -+msgdata,ack_rbf,funding_satoshis,u64, - msgtype,shutdown,38 - msgdata,shutdown,channel_id,channel_id, - msgdata,shutdown,len,u16, From 29adf9de3df61aa01a42a5319e8b1fc6fef554e3 Mon Sep 17 00:00:00 2001 From: niftynei Date: Wed, 3 Mar 2021 14:07:32 -0600 Subject: [PATCH 3/7] df-spec: use an empty bit-set as the basepoint for chan-id at start > If the peer's revocation basepoint is unknown (e.g. `open_channel2`), > a temporary `channel_id` should be found by using a zeroed out basepoint > for the unknown peer. --- common/channel_id.c | 18 ++++++++++ common/channel_id.h | 10 +++++- openingd/dualopend.c | 78 ++++++++++++++++++++++++++------------------ 3 files changed, 74 insertions(+), 32 deletions(-) diff --git a/common/channel_id.c b/common/channel_id.c index 7b1bae721bbb..504cb3033e69 100644 --- a/common/channel_id.c +++ b/common/channel_id.c @@ -47,6 +47,24 @@ void derive_channel_id_v2(struct channel_id *channel_id, memcpy(channel_id, &sha, sizeof(*channel_id)); } +void derive_tmp_channel_id(struct channel_id *channel_id, + const struct pubkey *opener_basepoint) +{ + struct sha256 sha; + + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * If the peer's revocation basepoint is unknown + * (e.g. `open_channel2`), a temporary `channel_id` should be + * found by using a zeroed out basepoint for the unknown peer. + */ + u8 der_keys[PUBKEY_CMPR_LEN * 2]; + memset(der_keys, 0, PUBKEY_CMPR_LEN); + pubkey_to_der(der_keys + PUBKEY_CMPR_LEN, opener_basepoint); + sha256(&sha, der_keys, sizeof(der_keys)); + BUILD_ASSERT(sizeof(*channel_id) == sizeof(sha)); + memcpy(channel_id, &sha, sizeof(*channel_id)); +} + /* BOLT #2: * * The sending node: diff --git a/common/channel_id.h b/common/channel_id.h index 78e1109bd5d5..9a3aa13e0495 100644 --- a/common/channel_id.h +++ b/common/channel_id.h @@ -20,14 +20,22 @@ struct channel_id { /* Define channel_id_eq (no padding) */ STRUCTEQ_DEF(channel_id, 0, id); +/* For v1 channel establishment */ void derive_channel_id(struct channel_id *channel_id, const struct bitcoin_txid *txid, u16 txout); +/* For v1 channel establishment */ +void temporary_channel_id(struct channel_id *channel_id); + +/* For v2 channel establishment */ void derive_channel_id_v2(struct channel_id *channel_id, const struct pubkey *basepoint_1, const struct pubkey *basepoint_2); -void temporary_channel_id(struct channel_id *channel_id); +/* For v2 channel establishment */ +void derive_tmp_channel_id(struct channel_id *channel_id, + const struct pubkey *opener_basepoint); + /* Marshalling/unmarshalling functions */ void towire_channel_id(u8 **pptr, const struct channel_id *channel_id); void fromwire_channel_id(const u8 **cursor, size_t *max, diff --git a/openingd/dualopend.c b/openingd/dualopend.c index fe937f7a47fa..ff6bc04849b8 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -434,6 +434,13 @@ static void check_channel_id(struct state *state, id_in)); } +static bool is_dust(struct tx_state *tx_state, + struct amount_sat amount) +{ + return !amount_sat_greater(amount, tx_state->localconf.dust_limit) + || !amount_sat_greater(amount, tx_state->remoteconf.dust_limit); +} + static void set_reserve(struct tx_state *tx_state, struct amount_sat funding_total, enum tx_role our_role) @@ -542,7 +549,8 @@ static char *check_balances(const tal_t *ctx, * - segwit marker + flag * - input count * - output count - * - locktime */ + * - locktime + */ size_t initiator_weight = bitcoin_tx_core_weight(psbt->num_inputs, psbt->num_outputs); @@ -596,12 +604,8 @@ static char *check_balances(const tal_t *ctx, * - the value of the funding output is * less than the `dust_limit` */ - if (!amount_sat_greater(output_val, - tx_state->remoteconf.dust_limit) || - !amount_sat_greater(output_val, - tx_state->localconf.dust_limit)) { + if (is_dust(tx_state, output_val)) return "funding output is dust"; - } } else { /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * @@ -667,12 +671,8 @@ static char *check_balances(const tal_t *ctx, * - the `sats` amount is less than or equal to * the `dust_limit` */ - if (!amount_sat_greater(amt, - tx_state->remoteconf.dust_limit) || - !amount_sat_greater(amt, - tx_state->localconf.dust_limit)) { + if (is_dust(tx_state, amt)) return "output is dust"; - } if (is_openers(&psbt->outputs[i].unknowns)) { /* Don't add the funding output to @@ -704,9 +704,9 @@ static char *check_balances(const tal_t *ctx, * ... * - the peer's total input satoshis is less than their outputs */ - if (!amount_sat_greater_eq(tot_input_amt, tot_output_amt)) { - return "inputs less than total outputs"; - } + /* We check both, why not? */ + if (!amount_sat_greater_eq(initiator_inputs, initiator_outs)) + return "initiator inputs less than outputs"; /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * The receiving node: ... @@ -1421,6 +1421,7 @@ static bool run_tx_interactive(struct state *state, * to a currently added input (or output) */ input_index = psbt_find_serial_input(psbt, serial_id); + /* We choose to error/fail negotiation */ if (input_index == -1) open_err_warn(state, "No input added with serial_id" @@ -1850,7 +1851,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) struct bitcoin_blkid chain_hash; struct tlv_opening_tlvs *open_tlv; char *err_reason; - struct channel_id cid; + struct channel_id tmp_chan_id; u8 *msg; struct amount_sat total; enum dualopend_wire msg_type; @@ -1860,7 +1861,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) open_tlv = tlv_opening_tlvs_new(tmpctx); if (!fromwire_open_channel2(oc2_msg, &chain_hash, - &state->channel_id, + &state->channel_id, /* Temporary! */ &state->feerate_per_kw_funding, &state->feerate_per_kw_commitment, &tx_state->opener_funding, @@ -1887,6 +1888,27 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) } else state->upfront_shutdown_script[REMOTE] = NULL; + /* BOLT-* #2 + * If the peer's revocation basepoint is unknown (e.g. + * `open_channel2`), a temporary `channel_id` should be found + * by using a zeroed out basepoint for the unknown peer. + */ + derive_tmp_channel_id(&tmp_chan_id, + &state->their_points.revocation); + if (!channel_id_eq(&state->channel_id, &tmp_chan_id)) + negotiation_failed(state, "open_channel2 channel_id incorrect." + " Expected %s, received %s", + type_to_string(tmpctx, struct channel_id, + &tmp_chan_id), + type_to_string(tmpctx, struct channel_id, + &state->channel_id)); + + /* Everything's ok. Let's figure out the actual channel_id now */ + derive_channel_id_v2(&state->channel_id, + &state->our_points.revocation, + &state->their_points.revocation); + + /* Save feerate on the tx_state as well */ tx_state->feerate_per_kw_funding = state->feerate_per_kw_funding; @@ -1922,13 +1944,8 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) return; } - /* We can figure out the channel id now */ - derive_channel_id_v2(&cid, - &state->our_points.revocation, - &state->their_points.revocation); - msg = towire_dualopend_got_offer(NULL, - &cid, + &state->channel_id, tx_state->opener_funding, tx_state->remoteconf.dust_limit, tx_state->remoteconf.max_htlc_value_in_flight, @@ -1962,9 +1979,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) * the original feerate we'll base any increases off of. */ state->feerate_per_kw_funding = tx_state->feerate_per_kw_funding; - /* Set the channel id now */ - state->channel_id = cid; - if (!tx_state->psbt) tx_state->psbt = create_psbt(tx_state, 0, 0, tx_state->tx_locktime); @@ -2350,11 +2364,13 @@ static void opener_start(struct state *state, u8 *msg) tx_state->feerate_per_kw_funding = state->feerate_per_kw_funding; open_tlv = tlv_opening_tlvs_new(tmpctx); - /* Set the channel_id to a temporary id, we'll update - * this as soon as we hear back from accept, but if they - * send us an error in the meantime, we need to be able to - * understand it */ - temporary_channel_id(&state->channel_id); + /* BOLT-* #2 + * If the peer's revocation basepoint is unknown (e.g. + * `open_channel2`), a temporary `channel_id` should be found + * by using a zeroed out basepoint for the unknown peer. + */ + derive_tmp_channel_id(&state->channel_id, + &state->our_points.revocation); if (!state->upfront_shutdown_script[LOCAL]) state->upfront_shutdown_script[LOCAL] @@ -2429,7 +2445,7 @@ static void opener_start(struct state *state, u8 *msg) } else state->upfront_shutdown_script[REMOTE] = NULL; - /* Now we can set the 'real channel id' */ + /* Now we know the 'real channel id' */ derive_channel_id_v2(&state->channel_id, &state->our_points.revocation, &state->their_points.revocation); From 8e8ac2ee2b6aa8586796adbe8d70b99fdd9887f9 Mon Sep 17 00:00:00 2001 From: niftynei Date: Wed, 3 Mar 2021 14:50:46 -0600 Subject: [PATCH 4/7] psbt: mark psbt arg as const for `psbt_compute_fee` --- bitcoin/psbt.c | 2 +- bitcoin/psbt.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bitcoin/psbt.c b/bitcoin/psbt.c index 015a0eb42739..04906276577f 100644 --- a/bitcoin/psbt.c +++ b/bitcoin/psbt.c @@ -821,7 +821,7 @@ void psbt_txid(const tal_t *ctx, wally_tx_free(tx); } -struct amount_sat psbt_compute_fee(struct wally_psbt *psbt) +struct amount_sat psbt_compute_fee(const struct wally_psbt *psbt) { struct amount_sat fee, input_amt; struct amount_asset asset; diff --git a/bitcoin/psbt.h b/bitcoin/psbt.h index 18b29862a85e..e1fa9b4068e8 100644 --- a/bitcoin/psbt.h +++ b/bitcoin/psbt.h @@ -249,7 +249,7 @@ struct amount_sat psbt_output_get_amount(const struct wally_psbt *psbt, * * @psbt -psbt */ -struct amount_sat psbt_compute_fee(struct wally_psbt *psbt); +struct amount_sat psbt_compute_fee(const struct wally_psbt *psbt); /* psbt_has_input - Is this input present on this psbt * From e328b9c71b9336d91f616ad71f5cc11f8d8fa395 Mon Sep 17 00:00:00 2001 From: niftynei Date: Wed, 3 Mar 2021 14:51:32 -0600 Subject: [PATCH 5/7] bitcoin: method for finding weight of 'wally_tx' --- bitcoin/tx.c | 9 +++++++-- bitcoin/tx.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/bitcoin/tx.c b/bitcoin/tx.c index 6be607b74d18..f6fb836de084 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -443,14 +443,19 @@ u8 *linearize_wtx(const tal_t *ctx, const struct wally_tx *wtx) return arr; } -size_t bitcoin_tx_weight(const struct bitcoin_tx *tx) +size_t wally_tx_weight(const struct wally_tx *wtx) { size_t weight; - int ret = wally_tx_get_weight(tx->wtx, &weight); + int ret = wally_tx_get_weight(wtx, &weight); assert(ret == WALLY_OK); return weight; } +size_t bitcoin_tx_weight(const struct bitcoin_tx *tx) +{ + return wally_tx_weight(tx->wtx); +} + void wally_txid(const struct wally_tx *wtx, struct bitcoin_txid *txid) { u8 *arr; diff --git a/bitcoin/tx.h b/bitcoin/tx.h index 40d7f6969412..3ebac3f4ae17 100644 --- a/bitcoin/tx.h +++ b/bitcoin/tx.h @@ -59,6 +59,7 @@ u8 *linearize_wtx(const tal_t *ctx, const struct wally_tx *wtx); /* Get weight of tx in Sipa. */ size_t bitcoin_tx_weight(const struct bitcoin_tx *tx); +size_t wally_tx_weight(const struct wally_tx *wtx); /* Allocate a tx: you just need to fill in inputs and outputs (they're * zeroed with inputs' sequence_number set to FFFFFFFF) */ From 0d9265077a8631910b98de35accf279fb6c31c0b Mon Sep 17 00:00:00 2001 From: niftynei Date: Wed, 3 Mar 2021 14:52:17 -0600 Subject: [PATCH 6/7] df: fail channel if peer sends witnesses that aren't paid for The receiving node: ... - MUST fail the channel if: - the `witness_stack` weight lowers the effective `feerate` below the agreed upon transaction `feerate` --- lightningd/dual_open_control.c | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 3afeff0701fa..e06c4e819f95 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -982,6 +982,23 @@ REGISTER_PLUGIN_HOOK(rbf_channel, rbf_channel_hook_serialize, struct rbf_channel_payload *); +static bool feerate_satisfied(struct wally_psbt *psbt, + u32 funding_feerate) +{ + struct wally_tx *wtx; + size_t tx_weight; + struct amount_sat fee_paid, expected_fee; + + wtx = psbt_final_tx(NULL, psbt); + tx_weight = wally_tx_weight(wtx); + tal_free(wtx); + + fee_paid = psbt_compute_fee(psbt); + expected_fee = amount_tx_fee(funding_feerate, tx_weight); + + return amount_sat_greater_eq(fee_paid, expected_fee); +} + static struct amount_sat calculate_reserve(struct channel_config *their_config, struct amount_sat funding_total, enum side opener) @@ -1419,6 +1436,24 @@ static void handle_peer_tx_sigs_sent(struct subd *dualopend, &channel->funding, &channel->funding_txid, &channel->remote_funding_locked); + + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2 + * The receiving node: ... + * - MUST fail the channel if: + * - the `witness_stack` weight lowers the + * effective `feerate` below the agreed upon + * transaction `feerate` + */ + if (!feerate_satisfied(inflight->funding_psbt, + inflight->funding->feerate)) + channel_fail_permanent(channel, + REASON_PROTOCOL, + "Agreed feerate %dperkw not" + " met with witnesses %s", + inflight->funding->feerate, + type_to_string(tmpctx, + struct wally_psbt, + inflight->funding_psbt)); } } @@ -1716,6 +1751,24 @@ static void handle_peer_tx_sigs_msg(struct subd *dualopend, &channel->funding, &channel->funding_txid, &channel->remote_funding_locked); + + /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2 + * The receiving node: ... + * - MUST fail the channel if: + * - the `witness_stack` weight lowers the + * effective `feerate` below the agreed upon + * transaction `feerate` + */ + if (!feerate_satisfied(inflight->funding_psbt, + inflight->funding->feerate)) + channel_fail_permanent(channel, + REASON_PROTOCOL, + "Agreed feerate %dperkw not" + " met with witnesses %s", + inflight->funding->feerate, + type_to_string(tmpctx, + struct wally_psbt, + inflight->funding_psbt)); } /* Send notification with peer's signed PSBT */ From 3ef059b0ba90075f30f5ab514377054556ef7513 Mon Sep 17 00:00:00 2001 From: niftynei Date: Wed, 3 Mar 2021 16:47:04 -0600 Subject: [PATCH 7/7] df-spec: limit allowable inputs/outputs to 252 The maximum inputs and outputs are capped at 252. This effectively fixes the byte size of the input and output counts on the transaction to one (1). --- openingd/dualopend.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/openingd/dualopend.c b/openingd/dualopend.c index ff6bc04849b8..8bbe344bb6f4 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -74,15 +74,21 @@ enum tx_msgs { /* * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: - * The receiving node: - * ... - * - MUST fail the negotiation if: ... - * - if has received 4096 `tx_add_input` messages during this negotiation - * ... - * - it has received 4096 `tx_add_output` messages during this negotiation + * The maximum inputs and outputs are capped at 252. This effectively fixes + * the byte size of the input and output counts on the transaction to one (1). */ #define MAX_TX_MSG_RCVD (1 << 12) +/* + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - there are more than 252 inputs + * - there are more than 252 outputs + */ +#define MAX_FUNDING_INPUTS 252 +#define MAX_FUNDING_OUTPUTS 252 + /* State for a 'new' funding transaction. There should be one * for every new funding transaction attempt */ struct tx_state { @@ -560,6 +566,29 @@ static char *check_balances(const tal_t *ctx, &state->our_funding_pubkey, &state->their_funding_pubkey); + /* + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - there are more than 252 inputs + */ + if (tx_state->psbt->num_inputs > MAX_FUNDING_INPUTS) + negotiation_failed(state, "Too many inputs. Have %zu," + " Max allowed %zu", + tx_state->psbt->num_inputs, + MAX_FUNDING_INPUTS); + /* + * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: + * The receiving node: ... + * - MUST fail the negotiation if: ... + * - there are more than 252 outputs + */ + if (tx_state->psbt->num_outputs > MAX_FUNDING_OUTPUTS) + negotiation_failed(state, "Too many inputs. Have %zu," + " Max allowed %zu", + tx_state->psbt->num_outputs, + MAX_FUNDING_OUTPUTS); + /* Find funding output, check balance */ if (find_txout(psbt, scriptpubkey_p2wsh(tmpctx, funding_wscript),