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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-10-26 13:03:28 +10:30
parent 01d31e7dde
commit e609bc934e
7 changed files with 92 additions and 33 deletions

View File

@ -1501,14 +1501,17 @@ static bool want_blockheight_update(const struct peer *peer, u32 *height)
return true; return true;
} }
static u8 *send_commit_part(struct peer *peer, /* Returns commitment_signed msg, sets @local_anchor */
static u8 *send_commit_part(const tal_t *ctx,
struct peer *peer,
const struct bitcoin_outpoint *funding, const struct bitcoin_outpoint *funding,
struct amount_sat funding_sats, struct amount_sat funding_sats,
const struct htlc **changed_htlcs, const struct htlc **changed_htlcs,
bool notify_master, bool notify_master,
s64 splice_amnt, s64 splice_amnt,
s64 remote_splice_amnt, s64 remote_splice_amnt,
u64 remote_index) u64 remote_index,
struct local_anchor_info **anchor)
{ {
u8 *msg; u8 *msg;
struct bitcoin_signature commit_sig, *htlc_sigs; struct bitcoin_signature commit_sig, *htlc_sigs;
@ -1517,6 +1520,7 @@ static u8 *send_commit_part(struct peer *peer,
const struct htlc **htlc_map; const struct htlc **htlc_map;
struct wally_tx_output *direct_outputs[NUM_SIDES]; struct wally_tx_output *direct_outputs[NUM_SIDES];
struct penalty_base *pbase; struct penalty_base *pbase;
int local_anchor_outnum;
struct tlv_commitment_signed_tlvs *cs_tlv struct tlv_commitment_signed_tlvs *cs_tlv
= tlv_commitment_signed_tlvs_new(tmpctx); = tlv_commitment_signed_tlvs_new(tmpctx);
@ -1537,7 +1541,7 @@ static u8 *send_commit_part(struct peer *peer,
direct_outputs, &funding_wscript, direct_outputs, &funding_wscript,
peer->channel, &peer->remote_per_commit, peer->channel, &peer->remote_per_commit,
remote_index, REMOTE, remote_index, REMOTE,
splice_amnt, remote_splice_amnt); splice_amnt, remote_splice_amnt, &local_anchor_outnum);
htlc_sigs = htlc_sigs =
calc_commitsigs(tmpctx, peer, txs, funding_wscript, htlc_map, calc_commitsigs(tmpctx, peer, txs, funding_wscript, htlc_map,
remote_index, &commit_sig); remote_index, &commit_sig);
@ -1552,6 +1556,16 @@ static u8 *send_commit_part(struct peer *peer,
} else } else
pbase = NULL; 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) { if (peer->dev_disable_commit) {
(*peer->dev_disable_commit)--; (*peer->dev_disable_commit)--;
if (*peer->dev_disable_commit == 0) if (*peer->dev_disable_commit == 0)
@ -1574,7 +1588,7 @@ static u8 *send_commit_part(struct peer *peer,
tal_count(htlc_sigs)); tal_count(htlc_sigs));
} }
msg = towire_commitment_signed(NULL, &peer->channel_id, msg = towire_commitment_signed(ctx, &peer->channel_id,
&commit_sig.s, &commit_sig.s,
raw_sigs(tmpctx, htlc_sigs), raw_sigs(tmpctx, htlc_sigs),
cs_tlv); cs_tlv);
@ -1594,6 +1608,7 @@ static void send_commit(struct peer *peer)
u32 feerate_target; u32 feerate_target;
u8 **msgs = tal_arr(tmpctx, u8*, 1); u8 **msgs = tal_arr(tmpctx, u8*, 1);
u8 *msg; u8 *msg;
struct local_anchor_info *local_anchor, *anchors_info;
if (peer->dev_disable_commit && !*peer->dev_disable_commit) { if (peer->dev_disable_commit && !*peer->dev_disable_commit) {
peer->commit_timer = NULL; peer->commit_timer = NULL;
@ -1705,9 +1720,13 @@ static void send_commit(struct peer *peer)
return; 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, 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 /* Loop over current inflights
* BOLT-0d8b701614b09c6ee4172b04da2203e73deec7e2 #2: * BOLT-0d8b701614b09c6ee4172b04da2203e73deec7e2 #2:
@ -1725,15 +1744,23 @@ static void send_commit(struct peer *peer)
- peer->splice_state->inflights[i]->splice_amnt; - peer->splice_state->inflights[i]->splice_amnt;
tal_arr_expand(&msgs, tal_arr_expand(&msgs,
send_commit_part(peer, send_commit_part(msgs, peer,
&peer->splice_state->inflights[i]->outpoint, &peer->splice_state->inflights[i]->outpoint,
peer->splice_state->inflights[i]->amnt, peer->splice_state->inflights[i]->amnt,
changed_htlcs, false, changed_htlcs, false,
peer->splice_state->inflights[i]->splice_amnt, peer->splice_state->inflights[i]->splice_amnt,
remote_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]++; peer->next_index[REMOTE]++;
for(u32 i = 0; i < tal_count(msgs); i++) 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 amount_sat funding_sats;
struct channel_id active_id; struct channel_id active_id;
const struct commitsig **commitsigs; const struct commitsig **commitsigs;
int remote_anchor_outnum;
status_debug("handle_peer_commit_sig(splice: %d, remote_splice: %d)", status_debug("handle_peer_commit_sig(splice: %d, remote_splice: %d)",
(int)splice_amnt, (int)remote_splice_amnt); (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, NULL, &funding_wscript, peer->channel,
&peer->next_local_per_commit, &peer->next_local_per_commit,
peer->next_index[LOCAL], LOCAL, splice_amnt, 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 */ /* Set the commit_sig on the commitment tx psbt */
if (!psbt_input_set_signature(txs[0]->psbt, 0, 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; size_t i;
u8 *msg; u8 *msg;
u8 **msgs = tal_arr(tmpctx, u8*, 1); u8 **msgs = tal_arr(tmpctx, u8*, 1);
struct local_anchor_info *local_anchor;
status_debug("Retransmitting commitment, feerate LOCAL=%u REMOTE=%u," status_debug("Retransmitting commitment, feerate LOCAL=%u REMOTE=%u,"
" blockheight 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, 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 /* Loop over current inflights
* BOLT-0d8b701614b09c6ee4172b04da2203e73deec7e2 #2: * 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; - peer->splice_state->inflights[i]->splice_amnt;
tal_arr_expand(&msgs, tal_arr_expand(&msgs,
send_commit_part(peer, send_commit_part(msgs, peer,
&peer->splice_state->inflights[i]->outpoint, &peer->splice_state->inflights[i]->outpoint,
peer->splice_state->inflights[i]->amnt, peer->splice_state->inflights[i]->amnt,
NULL, false, NULL, false,
peer->splice_state->inflights[i]->splice_amnt, peer->splice_state->inflights[i]->splice_amnt,
remote_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++) 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_UPDATE_INFLIGHT:
case WIRE_CHANNELD_GOT_INFLIGHT: case WIRE_CHANNELD_GOT_INFLIGHT:
case WIRE_CHANNELD_SPLICE_STATE_ERROR: case WIRE_CHANNELD_SPLICE_STATE_ERROR:
case WIRE_CHANNELD_LOCAL_ANCHOR_INFO:
break; break;
} }
master_badmsg(-1, msg); master_badmsg(-1, msg);

View File

@ -128,6 +128,18 @@ msgdata,channeld_got_splice_locked,locked_txid,bitcoin_txid,
#include <common/penalty_base.h> #include <common/penalty_base.h>
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. # When we send a commitment_signed message, tell master.
msgtype,channeld_sending_commitsig,1020 msgtype,channeld_sending_commitsig,1020
msgdata,channeld_sending_commitsig,commitnum,u64, 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,num_changed,u16,
msgdata,channeld_sending_commitsig,changed,changed_htlc,num_changed msgdata,channeld_sending_commitsig,changed,changed_htlc,num_changed
# Wait for reply, to make sure it's on disk before we send commit. # Wait for reply, to make sure it's on disk before we send commit.
msgtype,channeld_sending_commitsig_reply,1120 msgtype,channeld_sending_commitsig_reply,1120

Can't render this file because it has a wrong number of fields in line 15.

View File

@ -309,13 +309,13 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx,
u64 commitment_number, u64 commitment_number,
enum side side, enum side side,
s64 splice_amnt, s64 splice_amnt,
s64 remote_splice_amnt) s64 remote_splice_amnt,
int *other_anchor_outnum)
{ {
struct bitcoin_tx **txs; struct bitcoin_tx **txs;
const struct htlc **committed; const struct htlc **committed;
struct keyset keyset; struct keyset keyset;
struct amount_msat side_pay, other_side_pay; struct amount_msat side_pay, other_side_pay;
int local_anchor;
if (!derive_keyset(per_commitment_point, if (!derive_keyset(per_commitment_point,
&channel->basepoints[side], &channel->basepoints[side],
@ -364,7 +364,7 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx,
commitment_number ^ channel->commitment_number_obscurer, commitment_number ^ channel->commitment_number_obscurer,
channel_has(channel, OPT_ANCHOR_OUTPUTS), channel_has(channel, OPT_ANCHOR_OUTPUTS),
channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX), 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 */ /* Set the remote/local pubkeys on the commitment tx psbt */
psbt_input_add_pubkey(txs[0]->psbt, 0, psbt_input_add_pubkey(txs[0]->psbt, 0,

View File

@ -66,6 +66,7 @@ struct channel *new_full_channel(const tal_t *ctx,
* @side: which side to get the commitment transaction for * @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. * @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. * @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 * Returns the unsigned commitment transaction for the committed state
* for @side, followed by the htlc transactions in output order and * 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, u64 commitment_number,
enum side side, enum side side,
s64 local_splice_amnt, 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. * actual_feerate: what is the actual feerate for the local side.

View File

@ -541,7 +541,8 @@ int main(int argc, const char *argv[])
txs = channel_txs(tmpctx, &funding, funding_amount, txs = channel_txs(tmpctx, &funding, funding_amount,
&htlc_map, NULL, &funding_wscript_alt, &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(txs) == 1);
assert(tal_count(htlc_map) == 2); assert(tal_count(htlc_map) == 2);
assert(scripteq(funding_wscript_alt, funding_wscript)); 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, txs2 = channel_txs(tmpctx, &funding, funding_amount,
&htlc_map, NULL, &funding_wscript, &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); txs_must_be_eq(txs, txs2);
/* BOLT #3: /* BOLT #3:
@ -577,11 +579,13 @@ int main(int argc, const char *argv[])
txs = channel_txs(tmpctx, &funding, funding_amount, txs = channel_txs(tmpctx, &funding, funding_amount,
&htlc_map, NULL, &funding_wscript, &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); assert(tal_count(txs) == 1);
txs2 = channel_txs(tmpctx, &funding, funding_amount, txs2 = channel_txs(tmpctx, &funding, funding_amount,
&htlc_map, NULL, &funding_wscript, &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); txs_must_be_eq(txs, txs2);
update_feerate(lchannel, feerate_per_kw[LOCAL]); 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, txs = channel_txs(tmpctx, &funding, funding_amount,
&htlc_map, NULL, &funding_wscript, &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); assert(tal_count(txs) == 6);
txs2 = channel_txs(tmpctx, &funding, funding_amount, txs2 = channel_txs(tmpctx, &funding, funding_amount,
&htlc_map, NULL, &funding_wscript, &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); txs_must_be_eq(txs, txs2);
/* FIXME: Compare signatures! */ /* FIXME: Compare signatures! */
@ -675,13 +681,15 @@ int main(int argc, const char *argv[])
txs = channel_txs(tmpctx, &funding, funding_amount, txs = channel_txs(tmpctx, &funding, funding_amount,
&htlc_map, NULL, &funding_wscript, &htlc_map, NULL, &funding_wscript,
lchannel, &local_per_commitment_point, 42, lchannel, &local_per_commitment_point, 42,
LOCAL, 0, 0); LOCAL, 0, 0,
&local_anchor);
tx_must_be_eq(txs[0], raw_tx); tx_must_be_eq(txs[0], raw_tx);
txs2 = channel_txs(tmpctx, &funding, funding_amount, txs2 = channel_txs(tmpctx, &funding, funding_amount,
&htlc_map, NULL, &funding_wscript, &htlc_map, NULL, &funding_wscript,
rchannel, &local_per_commitment_point, rchannel, &local_per_commitment_point,
42, REMOTE, 0, 0); 42, REMOTE, 0, 0,
&local_anchor);
txs_must_be_eq(txs, txs2); txs_must_be_eq(txs, txs2);
} }

View File

@ -270,6 +270,7 @@ int main(int argc, char *argv[])
const struct channel_type *channel_type; const struct channel_type *channel_type;
struct sha256_double hash; struct sha256_double hash;
u32 blockheight = 0; u32 blockheight = 0;
int local_anchor_outnum;
setup_locale(); setup_locale();
chainparams = chainparams_for_network("bitcoin"); 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, local_txs = channel_txs(NULL, &channel->funding, channel->funding_sats,
&htlcmap, NULL, &funding_wscript, channel, &htlcmap, NULL, &funding_wscript, channel,
&local_per_commit_point, commitnum, &local_per_commit_point, commitnum,
LOCAL, 0, 0); LOCAL, 0, 0, &local_anchor_outnum);
printf("## local_commitment\n" printf("## local_commitment\n"
"# input amount %s, funding_wscript %s, pubkey %s\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, remote_txs = channel_txs(NULL, &channel->funding, channel->funding_sats,
&htlcmap, NULL, &funding_wscript, channel, &htlcmap, NULL, &funding_wscript, channel,
&remote_per_commit_point, commitnum, &remote_per_commit_point, commitnum,
REMOTE, 0, 0); REMOTE, 0, 0, &local_anchor_outnum);
printf("## remote_commitment\n" printf("## remote_commitment\n"
"# input amount %s, funding_wscript %s, key %s\n", "# input amount %s, funding_wscript %s, key %s\n",

View File

@ -1228,6 +1228,9 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
case WIRE_CHANNELD_SENDING_COMMITSIG: case WIRE_CHANNELD_SENDING_COMMITSIG:
peer_sending_commitsig(sd->channel, msg); peer_sending_commitsig(sd->channel, msg);
break; break;
case WIRE_CHANNELD_LOCAL_ANCHOR_INFO:
/* FIXME */
break;
case WIRE_CHANNELD_GOT_COMMITSIG: case WIRE_CHANNELD_GOT_COMMITSIG:
peer_got_commitsig(sd->channel, msg); peer_got_commitsig(sd->channel, msg);
break; break;