Skip to content

Commit

Permalink
channeld: tell lightningd about local anchor for each commitment tx.
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
rustyrussell committed Oct 27, 2023
1 parent 01d31e7 commit e609bc9
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 33 deletions.
70 changes: 51 additions & 19 deletions channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);

Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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:
Expand All @@ -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++)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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:
Expand All @@ -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++)
Expand Down Expand Up @@ -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);
Expand Down
13 changes: 13 additions & 0 deletions channeld/channeld_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,18 @@ msgdata,channeld_got_splice_locked,locked_txid,bitcoin_txid,

#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.
msgtype,channeld_sending_commitsig,1020
msgdata,channeld_sending_commitsig,commitnum,u64,
Expand All @@ -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

Expand Down
6 changes: 3 additions & 3 deletions channeld/full_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 3 additions & 1 deletion channeld/full_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
24 changes: 16 additions & 8 deletions channeld/test/run-full_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,15 +541,17 @@ 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));
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);
rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0,
&local_anchor);
txs_must_be_eq(txs, txs2);

/* BOLT #3:
Expand Down Expand Up @@ -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]);
Expand All @@ -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! */
Expand Down Expand Up @@ -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);
}

Expand Down
5 changes: 3 additions & 2 deletions devtools/mkcommit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions lightningd/channel_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit e609bc9

Please sign in to comment.