From e609bc934e0a2ab4147a66581d4a4278790b449a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 26 Oct 2023 13:03:28 +1030 Subject: [PATCH] channeld: tell lightningd about local anchor for each commitment tx. It's going to want to remember these, in case it encounters peers' commitment tx and needs to boost it with CPFP on the anchor. Signed-off-by: Rusty Russell --- channeld/channeld.c | 70 +++++++++++++++++++++++--------- channeld/channeld_wire.csv | 13 ++++++ channeld/full_channel.c | 6 +-- channeld/full_channel.h | 4 +- channeld/test/run-full_channel.c | 24 +++++++---- devtools/mkcommit.c | 5 ++- lightningd/channel_control.c | 3 ++ 7 files changed, 92 insertions(+), 33 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index 137f359d6..308f551c1 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -1501,14 +1501,17 @@ static bool want_blockheight_update(const struct peer *peer, u32 *height) return true; } -static u8 *send_commit_part(struct peer *peer, - const struct bitcoin_outpoint *funding, - struct amount_sat funding_sats, - const struct htlc **changed_htlcs, - bool notify_master, - s64 splice_amnt, - s64 remote_splice_amnt, - u64 remote_index) +/* Returns commitment_signed msg, sets @local_anchor */ +static u8 *send_commit_part(const tal_t *ctx, + struct peer *peer, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, + const struct htlc **changed_htlcs, + bool notify_master, + s64 splice_amnt, + s64 remote_splice_amnt, + u64 remote_index, + struct local_anchor_info **anchor) { u8 *msg; struct bitcoin_signature commit_sig, *htlc_sigs; @@ -1517,6 +1520,7 @@ static u8 *send_commit_part(struct peer *peer, const struct htlc **htlc_map; struct wally_tx_output *direct_outputs[NUM_SIDES]; struct penalty_base *pbase; + int local_anchor_outnum; struct tlv_commitment_signed_tlvs *cs_tlv = tlv_commitment_signed_tlvs_new(tmpctx); @@ -1537,7 +1541,7 @@ static u8 *send_commit_part(struct peer *peer, direct_outputs, &funding_wscript, peer->channel, &peer->remote_per_commit, remote_index, REMOTE, - splice_amnt, remote_splice_amnt); + splice_amnt, remote_splice_amnt, &local_anchor_outnum); htlc_sigs = calc_commitsigs(tmpctx, peer, txs, funding_wscript, htlc_map, remote_index, &commit_sig); @@ -1552,6 +1556,16 @@ static u8 *send_commit_part(struct peer *peer, } else pbase = NULL; + if (local_anchor_outnum == -1) { + *anchor = NULL; + } else { + *anchor = tal(ctx, struct local_anchor_info); + bitcoin_txid(txs[0], &(*anchor)->anchor_point.txid); + (*anchor)->anchor_point.n = local_anchor_outnum; + (*anchor)->commitment_weight = bitcoin_tx_weight(txs[0]); + (*anchor)->commitment_fee = bitcoin_tx_compute_fee(txs[0]); + } + if (peer->dev_disable_commit) { (*peer->dev_disable_commit)--; if (*peer->dev_disable_commit == 0) @@ -1574,7 +1588,7 @@ static u8 *send_commit_part(struct peer *peer, tal_count(htlc_sigs)); } - msg = towire_commitment_signed(NULL, &peer->channel_id, + msg = towire_commitment_signed(ctx, &peer->channel_id, &commit_sig.s, raw_sigs(tmpctx, htlc_sigs), cs_tlv); @@ -1594,6 +1608,7 @@ static void send_commit(struct peer *peer) u32 feerate_target; u8 **msgs = tal_arr(tmpctx, u8*, 1); u8 *msg; + struct local_anchor_info *local_anchor, *anchors_info; if (peer->dev_disable_commit && !*peer->dev_disable_commit) { peer->commit_timer = NULL; @@ -1705,9 +1720,13 @@ static void send_commit(struct peer *peer) return; } - msgs[0] = send_commit_part(peer, &peer->channel->funding, + anchors_info = tal_arr(tmpctx, struct local_anchor_info, 0); + msgs[0] = send_commit_part(msgs, peer, &peer->channel->funding, peer->channel->funding_sats, changed_htlcs, - true, 0, 0, peer->next_index[REMOTE]); + true, 0, 0, peer->next_index[REMOTE], + &local_anchor); + if (local_anchor) + tal_arr_expand(&anchors_info, *local_anchor); /* Loop over current inflights * BOLT-0d8b701614b09c6ee4172b04da2203e73deec7e2 #2: @@ -1725,15 +1744,23 @@ static void send_commit(struct peer *peer) - peer->splice_state->inflights[i]->splice_amnt; tal_arr_expand(&msgs, - send_commit_part(peer, + send_commit_part(msgs, peer, &peer->splice_state->inflights[i]->outpoint, peer->splice_state->inflights[i]->amnt, changed_htlcs, false, peer->splice_state->inflights[i]->splice_amnt, remote_splice_amnt, - peer->next_index[REMOTE])); + peer->next_index[REMOTE], + &local_anchor)); + if (local_anchor) + tal_arr_expand(&anchors_info, *local_anchor); } + /* Now, tell master about the anchor on each of their commitments */ + msg = towire_channeld_local_anchor_info(NULL, peer->next_index[REMOTE], + anchors_info); + wire_sync_write(MASTER_FD, take(msg)); + peer->next_index[REMOTE]++; for(u32 i = 0; i < tal_count(msgs); i++) @@ -1967,6 +1994,7 @@ static struct commitsig *handle_peer_commit_sig(struct peer *peer, struct amount_sat funding_sats; struct channel_id active_id; const struct commitsig **commitsigs; + int remote_anchor_outnum; status_debug("handle_peer_commit_sig(splice: %d, remote_splice: %d)", (int)splice_amnt, (int)remote_splice_amnt); @@ -2051,7 +2079,7 @@ static struct commitsig *handle_peer_commit_sig(struct peer *peer, NULL, &funding_wscript, peer->channel, &peer->next_local_per_commit, peer->next_index[LOCAL], LOCAL, splice_amnt, - remote_splice_amnt); + remote_splice_amnt, &remote_anchor_outnum); /* Set the commit_sig on the commitment tx psbt */ if (!psbt_input_set_signature(txs[0]->psbt, 0, @@ -4382,6 +4410,7 @@ static void resend_commitment(struct peer *peer, struct changed_htlc *last) size_t i; u8 *msg; u8 **msgs = tal_arr(tmpctx, u8*, 1); + struct local_anchor_info *local_anchor; status_debug("Retransmitting commitment, feerate LOCAL=%u REMOTE=%u," " blockheight LOCAL=%u REMOTE=%u", @@ -4472,9 +4501,10 @@ static void resend_commitment(struct peer *peer, struct changed_htlc *last) } } - msgs[0] = send_commit_part(peer, &peer->channel->funding, + msgs[0] = send_commit_part(msgs, peer, &peer->channel->funding, peer->channel->funding_sats, NULL, - false, 0, 0, peer->next_index[REMOTE] - 1); + false, 0, 0, peer->next_index[REMOTE] - 1, + &local_anchor); /* Loop over current inflights * BOLT-0d8b701614b09c6ee4172b04da2203e73deec7e2 #2: @@ -4492,13 +4522,14 @@ static void resend_commitment(struct peer *peer, struct changed_htlc *last) - peer->splice_state->inflights[i]->splice_amnt; tal_arr_expand(&msgs, - send_commit_part(peer, + send_commit_part(msgs, peer, &peer->splice_state->inflights[i]->outpoint, peer->splice_state->inflights[i]->amnt, NULL, false, peer->splice_state->inflights[i]->splice_amnt, remote_splice_amnt, - peer->next_index[REMOTE] - 1)); + peer->next_index[REMOTE] - 1, + &local_anchor)); } for(i = 0; i < tal_count(msgs); i++) @@ -5782,6 +5813,7 @@ static void req_in(struct peer *peer, const u8 *msg) case WIRE_CHANNELD_UPDATE_INFLIGHT: case WIRE_CHANNELD_GOT_INFLIGHT: case WIRE_CHANNELD_SPLICE_STATE_ERROR: + case WIRE_CHANNELD_LOCAL_ANCHOR_INFO: break; } master_badmsg(-1, msg); diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index b6db7a224..1992f7fa1 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -128,6 +128,18 @@ msgdata,channeld_got_splice_locked,locked_txid,bitcoin_txid, #include +subtype,local_anchor_info +subtypedata,local_anchor_info,commitment_weight,u32, +subtypedata,local_anchor_info,commitment_fee,amount_sat, +subtypedata,local_anchor_info,anchor_point,bitcoin_outpoint, + +# lightningd needs to track our anchor outputs on remote txs. +# This includes splices, so there could be more than one! +msgtype,channeld_local_anchor_info,1003 +msgdata,channeld_local_anchor_info,remote_commitnum,u64, +msgdata,channeld_local_anchor_info,num_anchors,u16, +msgdata,channeld_local_anchor_info,anchors,local_anchor_info,num_anchors + # When we send a commitment_signed message, tell master. msgtype,channeld_sending_commitsig,1020 msgdata,channeld_sending_commitsig,commitnum,u64, @@ -138,6 +150,7 @@ msgdata,channeld_sending_commitsig,blockheight_states,height_states, msgdata,channeld_sending_commitsig,num_changed,u16, msgdata,channeld_sending_commitsig,changed,changed_htlc,num_changed + # Wait for reply, to make sure it's on disk before we send commit. msgtype,channeld_sending_commitsig_reply,1120 diff --git a/channeld/full_channel.c b/channeld/full_channel.c index e0aaeb39b..45639328c 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -309,13 +309,13 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, u64 commitment_number, enum side side, s64 splice_amnt, - s64 remote_splice_amnt) + s64 remote_splice_amnt, + int *other_anchor_outnum) { struct bitcoin_tx **txs; const struct htlc **committed; struct keyset keyset; struct amount_msat side_pay, other_side_pay; - int local_anchor; if (!derive_keyset(per_commitment_point, &channel->basepoints[side], @@ -364,7 +364,7 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, commitment_number ^ channel->commitment_number_obscurer, channel_has(channel, OPT_ANCHOR_OUTPUTS), channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX), - side, &local_anchor); + side, other_anchor_outnum); /* Set the remote/local pubkeys on the commitment tx psbt */ psbt_input_add_pubkey(txs[0]->psbt, 0, diff --git a/channeld/full_channel.h b/channeld/full_channel.h index 66f467e5c..05ebf8da0 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -66,6 +66,7 @@ struct channel *new_full_channel(const tal_t *ctx, * @side: which side to get the commitment transaction for * @local_splice_amnt: how much is being spliced in (or out, if -ve) of local side. * @remote_splice_amnt: how much is being spliced in (or out, if -ve) of remote side. + * @other_anchor_outnum: which output (-1 if none) is the !!side anchor * * Returns the unsigned commitment transaction for the committed state * for @side, followed by the htlc transactions in output order and @@ -82,7 +83,8 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, u64 commitment_number, enum side side, s64 local_splice_amnt, - s64 remote_splice_amnt); + s64 remote_splice_amnt, + int *local_anchor_outnum); /** * actual_feerate: what is the actual feerate for the local side. diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index c9efc7876..cfc1b2137 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -541,7 +541,8 @@ int main(int argc, const char *argv[]) txs = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript_alt, - lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0); + lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0, + &local_anchor); assert(tal_count(txs) == 1); assert(tal_count(htlc_map) == 2); assert(scripteq(funding_wscript_alt, funding_wscript)); @@ -549,7 +550,8 @@ int main(int argc, const char *argv[]) txs2 = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, - rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0); + rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0, + &local_anchor); txs_must_be_eq(txs, txs2); /* BOLT #3: @@ -577,11 +579,13 @@ int main(int argc, const char *argv[]) txs = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, - lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0); + lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0, + &local_anchor); assert(tal_count(txs) == 1); txs2 = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, - rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0); + rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0, + &local_anchor); txs_must_be_eq(txs, txs2); update_feerate(lchannel, feerate_per_kw[LOCAL]); @@ -597,11 +601,13 @@ int main(int argc, const char *argv[]) txs = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, - lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0); + lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0, + &local_anchor); assert(tal_count(txs) == 6); txs2 = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, - rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0); + rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0, + &local_anchor); txs_must_be_eq(txs, txs2); /* FIXME: Compare signatures! */ @@ -675,13 +681,15 @@ int main(int argc, const char *argv[]) txs = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, lchannel, &local_per_commitment_point, 42, - LOCAL, 0, 0); + LOCAL, 0, 0, + &local_anchor); tx_must_be_eq(txs[0], raw_tx); txs2 = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, rchannel, &local_per_commitment_point, - 42, REMOTE, 0, 0); + 42, REMOTE, 0, 0, + &local_anchor); txs_must_be_eq(txs, txs2); } diff --git a/devtools/mkcommit.c b/devtools/mkcommit.c index cc460b36e..1d54f8cab 100644 --- a/devtools/mkcommit.c +++ b/devtools/mkcommit.c @@ -270,6 +270,7 @@ int main(int argc, char *argv[]) const struct channel_type *channel_type; struct sha256_double hash; u32 blockheight = 0; + int local_anchor_outnum; setup_locale(); chainparams = chainparams_for_network("bitcoin"); @@ -425,7 +426,7 @@ int main(int argc, char *argv[]) local_txs = channel_txs(NULL, &channel->funding, channel->funding_sats, &htlcmap, NULL, &funding_wscript, channel, &local_per_commit_point, commitnum, - LOCAL, 0, 0); + LOCAL, 0, 0, &local_anchor_outnum); printf("## local_commitment\n" "# input amount %s, funding_wscript %s, pubkey %s\n", @@ -536,7 +537,7 @@ int main(int argc, char *argv[]) remote_txs = channel_txs(NULL, &channel->funding, channel->funding_sats, &htlcmap, NULL, &funding_wscript, channel, &remote_per_commit_point, commitnum, - REMOTE, 0, 0); + REMOTE, 0, 0, &local_anchor_outnum); printf("## remote_commitment\n" "# input amount %s, funding_wscript %s, key %s\n", diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 772d83322..5d5432e72 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -1228,6 +1228,9 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) case WIRE_CHANNELD_SENDING_COMMITSIG: peer_sending_commitsig(sd->channel, msg); break; + case WIRE_CHANNELD_LOCAL_ANCHOR_INFO: + /* FIXME */ + break; case WIRE_CHANNELD_GOT_COMMITSIG: peer_got_commitsig(sd->channel, msg); break;