Skip to content

Commit 39da2f4

Browse files
committed
splice: Fixes from splice-out test
Added a test for splicing out that exposed some behavior and code glitches that are addressed in this commit. Added test for splice gossip. Also added documentation for how to do a splice out. ChangeLog-Fixed: Added docs, testing, and some fixes related to splicing out, insufficent balance handling, and restarting during a splice.
1 parent 9c95761 commit 39da2f4

File tree

6 files changed

+255
-121
lines changed

6 files changed

+255
-121
lines changed

channeld/channeld.c

Lines changed: 85 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
((msg) == WIRE_SPLICE || \
6262
(msg) == WIRE_SPLICE_ACK)
6363

64+
#define SAT_MIN(a, b) (amount_sat_less((a), (b)) ? (a) : (b))
65+
6466
struct peer {
6567
struct per_peer_state *pps;
6668
bool channel_ready[NUM_SIDES];
@@ -756,6 +758,9 @@ static void check_mutual_splice_locked(struct peer *peer)
756758
&inflight->outpoint.txid);
757759
wire_sync_write(MASTER_FD, take(msg));
758760

761+
/* We must regossip the scid since it has changed */
762+
peer->gossip_scid_announced = false;
763+
759764
channel_announcement_negotiate(peer);
760765
billboard_update(peer);
761766
send_channel_update(peer, 0);
@@ -1487,7 +1492,8 @@ static u8 *send_commit_part(struct peer *peer,
14871492
const struct htlc **changed_htlcs,
14881493
bool notify_master,
14891494
s64 splice_amnt,
1490-
s64 remote_splice_amnt)
1495+
s64 remote_splice_amnt,
1496+
u64 remote_index)
14911497
{
14921498
u8 *msg;
14931499
struct bitcoin_signature commit_sig, *htlc_sigs;
@@ -1515,14 +1521,14 @@ static u8 *send_commit_part(struct peer *peer,
15151521
txs = channel_splice_txs(tmpctx, funding, funding_sats, &htlc_map,
15161522
direct_outputs, &funding_wscript,
15171523
peer->channel, &peer->remote_per_commit,
1518-
peer->next_index[REMOTE], REMOTE,
1524+
remote_index, REMOTE,
15191525
splice_amnt, remote_splice_amnt);
15201526
htlc_sigs =
15211527
calc_commitsigs(tmpctx, peer, txs, funding_wscript, htlc_map,
1522-
peer->next_index[REMOTE], &commit_sig);
1528+
remote_index, &commit_sig);
15231529

15241530
if (direct_outputs[LOCAL] != NULL) {
1525-
pbase = penalty_base_new(tmpctx, peer->next_index[REMOTE],
1531+
pbase = penalty_base_new(tmpctx, remote_index,
15261532
txs[0], direct_outputs[LOCAL]);
15271533

15281534
/* Add the penalty_base to our in-memory list as well, so we
@@ -1543,8 +1549,7 @@ static u8 *send_commit_part(struct peer *peer,
15431549
status_debug("Telling master we're about to commit...");
15441550
/* Tell master to save this next commit to database, then wait.
15451551
*/
1546-
msg = sending_commitsig_msg(NULL, peer->next_index[REMOTE],
1547-
pbase,
1552+
msg = sending_commitsig_msg(NULL, remote_index, pbase,
15481553
peer->channel->fee_states,
15491554
peer->channel->blockheight_states,
15501555
changed_htlcs,
@@ -1692,7 +1697,7 @@ static void send_commit(struct peer *peer)
16921697

16931698
msgs[0] = send_commit_part(peer, &peer->channel->funding,
16941699
peer->channel->funding_sats, changed_htlcs,
1695-
true, 0, 0);
1700+
true, 0, 0, peer->next_index[REMOTE]);
16961701

16971702
/* Loop over current inflights
16981703
* BOLT-0d8b701614b09c6ee4172b04da2203e73deec7e2 #2:
@@ -1715,7 +1720,8 @@ static void send_commit(struct peer *peer)
17151720
peer->splice_state->inflights[i]->amnt,
17161721
changed_htlcs, false,
17171722
peer->splice_state->inflights[i]->splice_amnt,
1718-
remote_splice_amnt));
1723+
remote_splice_amnt,
1724+
peer->next_index[REMOTE]));
17191725
}
17201726

17211727
peer->next_index[REMOTE]++;
@@ -2907,7 +2913,7 @@ static size_t calc_weight(enum tx_role role, const struct wally_psbt *psbt)
29072913
weight += psbt_input_get_weight(psbt, i);
29082914

29092915
for (size_t i = 0; i < psbt->num_outputs; i++)
2910-
if (is_initiators_serial(&psbt->inputs[i].unknowns)) {
2916+
if (is_initiators_serial(&psbt->outputs[i].unknowns)) {
29112917
if (role == TX_INITIATOR)
29122918
weight += psbt_output_get_weight(psbt, i);
29132919
}
@@ -2928,7 +2934,7 @@ static struct amount_sat check_balances(struct peer *peer,
29282934
{
29292935
struct amount_sat min_initiator_fee, min_accepter_fee,
29302936
max_initiator_fee, max_accepter_fee,
2931-
funding_amount_res;
2937+
funding_amount_res, min_multiplied;
29322938
struct amount_msat funding_amount,
29332939
initiator_fee, accepter_fee;
29342940
struct amount_msat in[NUM_TX_ROLES], out[NUM_TX_ROLES];
@@ -2977,45 +2983,23 @@ static struct amount_sat check_balances(struct peer *peer,
29772983
* While we're, here, adjust the output counts by splice amount.
29782984
*/
29792985

2980-
if(peer->splicing->opener_relative > 0) {
2981-
if (!amount_msat_add_sat(&funding_amount, funding_amount,
2982-
amount_sat((u64)peer->splicing->opener_relative)))
2983-
peer_failed_warn(peer->pps, &peer->channel_id,
2984-
"Unable to add opener funding");
2985-
if (!amount_msat_add_sat(&out[TX_INITIATOR], out[TX_INITIATOR],
2986-
amount_sat((u64)peer->splicing->opener_relative)))
2987-
peer_failed_warn(peer->pps, &peer->channel_id,
2988-
"Unable to add opener funding to out amnt.");
2989-
} else {
2990-
if (!amount_msat_sub_sat(&funding_amount, funding_amount,
2991-
amount_sat((u64)-peer->splicing->opener_relative)))
2992-
peer_failed_warn(peer->pps, &peer->channel_id,
2993-
"Unable to sub opener funding");
2994-
if (!amount_msat_sub_sat(&out[TX_INITIATOR], out[TX_INITIATOR],
2995-
amount_sat((u64)peer->splicing->opener_relative)))
2996-
peer_failed_warn(peer->pps, &peer->channel_id,
2997-
"Unable to sub opener funding from out amnt.");
2998-
}
2986+
if (!amount_msat_add_sat_s64(&funding_amount, funding_amount,
2987+
peer->splicing->opener_relative))
2988+
peer_failed_warn(peer->pps, &peer->channel_id,
2989+
"Unable to add opener funding");
2990+
if (!amount_msat_add_sat_s64(&out[TX_INITIATOR], out[TX_INITIATOR],
2991+
peer->splicing->opener_relative))
2992+
peer_failed_warn(peer->pps, &peer->channel_id,
2993+
"Unable to add opener funding to out amnt.");
29992994

3000-
if(peer->splicing->accepter_relative > 0) {
3001-
if (!amount_msat_add_sat(&funding_amount, funding_amount,
3002-
amount_sat((u64)peer->splicing->accepter_relative)))
3003-
peer_failed_warn(peer->pps, &peer->channel_id,
3004-
"Unable to add accepter funding");
3005-
if (!amount_msat_add_sat(&out[TX_ACCEPTER], out[TX_ACCEPTER],
3006-
amount_sat((u64)peer->splicing->accepter_relative)))
3007-
peer_failed_warn(peer->pps, &peer->channel_id,
3008-
"Unable to add accepter funding to out amnt.");
3009-
} else {
3010-
if (!amount_msat_sub_sat(&funding_amount, funding_amount,
3011-
amount_sat((u64)-peer->splicing->accepter_relative)))
3012-
peer_failed_warn(peer->pps, &peer->channel_id,
3013-
"Unable to subtract accepter funding");
3014-
if (!amount_msat_sub_sat(&out[TX_ACCEPTER], out[TX_ACCEPTER],
3015-
amount_sat((u64)-peer->splicing->accepter_relative)))
3016-
peer_failed_warn(peer->pps, &peer->channel_id,
3017-
"Unable to sub accepter funding from out amnt.");
3018-
}
2995+
if (!amount_msat_add_sat_s64(&funding_amount, funding_amount,
2996+
peer->splicing->accepter_relative))
2997+
peer_failed_warn(peer->pps, &peer->channel_id,
2998+
"Unable to add accepter funding");
2999+
if (!amount_msat_add_sat_s64(&out[TX_ACCEPTER], out[TX_ACCEPTER],
3000+
peer->splicing->accepter_relative))
3001+
peer_failed_warn(peer->pps, &peer->channel_id,
3002+
"Unable to add accepter funding to out amnt.");
30193003

30203004
if (amount_msat_less(in[TX_INITIATOR], out[TX_INITIATOR])) {
30213005
msg = towire_channeld_splice_funding_error(NULL, in[TX_INITIATOR],
@@ -3064,6 +3048,14 @@ static struct amount_sat check_balances(struct peer *peer,
30643048
max_initiator_fee = amount_tx_fee(peer->feerate_max,
30653049
calc_weight(TX_INITIATOR, psbt));
30663050

3051+
/* Sometimes feerate_max is some absurdly high value, in that case we
3052+
* give a fee warning based of a multiple of the min value. */
3053+
amount_sat_mul(&min_multiplied, min_accepter_fee, 5);
3054+
max_accepter_fee = SAT_MIN(min_multiplied, max_accepter_fee);
3055+
3056+
amount_sat_mul(&min_multiplied, min_initiator_fee, 5);
3057+
max_initiator_fee = SAT_MIN(min_multiplied, max_initiator_fee);
3058+
30673059
/* Check initiator fee */
30683060
if (amount_msat_less_sat(initiator_fee, min_initiator_fee)) {
30693061
msg = towire_channeld_splice_feerate_error(NULL, initiator_fee,
@@ -3302,11 +3294,11 @@ static void resume_splice_negotiation(struct peer *peer,
33023294
txsig_tlvs);
33033295

33043296
if (do_i_sign_first(peer, current_psbt, our_role)) {
3305-
status_debug("Splice: we sign first");
33063297
msg = towire_channeld_update_inflight(NULL, current_psbt,
33073298
NULL, NULL);
33083299
wire_sync_write(MASTER_FD, take(msg));
33093300
peer_write(peer->pps, sigmsg);
3301+
status_debug("Splice: we signed first");
33103302
}
33113303

33123304
msg = peer_read(tmpctx, peer->pps);
@@ -3423,8 +3415,8 @@ static void resume_splice_negotiation(struct peer *peer,
34233415
wire_sync_write(MASTER_FD, take(msg));
34243416

34253417
if (!do_i_sign_first(peer, current_psbt, our_role)) {
3426-
status_debug("Splice: we sign second");
34273418
peer_write(peer->pps, sigmsg);
3419+
status_debug("Splice: we signed second");
34283420
}
34293421

34303422
peer->splicing = tal_free(peer->splicing);
@@ -4263,12 +4255,8 @@ static int cmp_changed_htlc_id(const struct changed_htlc *a,
42634255
static void resend_commitment(struct peer *peer, struct changed_htlc *last)
42644256
{
42654257
size_t i;
4266-
struct bitcoin_signature commit_sig, *htlc_sigs;
42674258
u8 *msg;
4268-
struct bitcoin_tx **txs;
4269-
const u8 *funding_wscript;
4270-
const struct htlc **htlc_map;
4271-
struct wally_tx_output *direct_outputs[NUM_SIDES];
4259+
u8 **msgs = tal_arr(tmpctx, u8*, 1);
42724260

42734261
status_debug("Retransmitting commitment, feerate LOCAL=%u REMOTE=%u,"
42744262
" blockheight LOCAL=%u REMOTE=%u",
@@ -4359,19 +4347,37 @@ static void resend_commitment(struct peer *peer, struct changed_htlc *last)
43594347
}
43604348
}
43614349

4362-
/* Re-send the commitment_signed itself. */
4363-
txs = channel_txs(tmpctx, &htlc_map, direct_outputs,
4364-
&funding_wscript, peer->channel, &peer->remote_per_commit,
4365-
peer->next_index[REMOTE]-1, REMOTE);
4350+
msgs[0] = send_commit_part(peer, &peer->channel->funding,
4351+
peer->channel->funding_sats, NULL,
4352+
false, 0, 0, peer->next_index[REMOTE] - 1);
43664353

4367-
htlc_sigs = calc_commitsigs(tmpctx, peer, txs, funding_wscript, htlc_map, peer->next_index[REMOTE]-1,
4368-
&commit_sig);
4354+
/* Loop over current inflights
4355+
* BOLT-0d8b701614b09c6ee4172b04da2203e73deec7e2 #2:
4356+
*
4357+
* A sending node:
4358+
*...
4359+
* - MUST first send a `commitment_signed` for the active channel then immediately
4360+
* send a `commitment_signed` for each splice awaiting confirmation, in increasing
4361+
* feerate order.
4362+
*/
4363+
for (i = 0; i < tal_count(peer->splice_state->inflights); i++) {
4364+
s64 funding_diff = sats_diff(peer->splice_state->inflights[i]->amnt,
4365+
peer->channel->funding_sats);
4366+
s64 remote_splice_amnt = funding_diff
4367+
- peer->splice_state->inflights[i]->splice_amnt;
43694368

4370-
msg = towire_commitment_signed(NULL, &peer->channel_id,
4371-
&commit_sig.s,
4372-
raw_sigs(tmpctx, htlc_sigs),
4373-
NULL);
4374-
peer_write(peer->pps, take(msg));
4369+
tal_arr_expand(&msgs,
4370+
send_commit_part(peer,
4371+
&peer->splice_state->inflights[i]->outpoint,
4372+
peer->splice_state->inflights[i]->amnt,
4373+
NULL, false,
4374+
peer->splice_state->inflights[i]->splice_amnt,
4375+
remote_splice_amnt,
4376+
peer->next_index[REMOTE] - 1));
4377+
}
4378+
4379+
for(i = 0; i < tal_count(msgs); i++)
4380+
peer_write(peer->pps, take(msgs[i]));
43754381

43764382
/* If we have already received the revocation for the previous, the
43774383
* other side shouldn't be asking for a retransmit! */
@@ -4638,8 +4644,14 @@ static void peer_reconnect(struct peer *peer,
46384644
send_tlvs = tlv_channel_reestablish_tlvs_new(peer);
46394645

46404646
/* If inflight with no sigs on it, send next_funding */
4641-
if (inflight && !inflight->last_tx)
4647+
if (inflight && !inflight->last_tx) {
4648+
status_debug("Reestablish with an inflight but missing"
4649+
" last_tx, will send next_funding %s",
4650+
type_to_string(tmpctx,
4651+
struct bitcoin_txid,
4652+
&inflight->outpoint.txid));
46424653
send_tlvs->next_funding = &inflight->outpoint.txid;
4654+
}
46434655

46444656
/* BOLT-upgrade_protocol #2:
46454657
* A node sending `channel_reestablish`, if it supports upgrading channels:
@@ -4772,9 +4784,12 @@ static void peer_reconnect(struct peer *peer,
47724784
tal_hex(msg, msg));
47734785
}
47744786

4775-
status_debug("Got reestablish commit=%"PRIu64" revoke=%"PRIu64,
4787+
status_debug("Got reestablish commit=%"PRIu64" revoke=%"PRIu64
4788+
" inflights: %lu, active splices: %"PRIu32,
47764789
next_commitment_number,
4777-
next_revocation_number);
4790+
next_revocation_number,
4791+
tal_count(peer->splice_state->inflights),
4792+
peer->splice_state->count);
47784793

47794794
/* BOLT #2:
47804795
*
@@ -5079,6 +5094,7 @@ static void peer_reconnect(struct peer *peer,
50795094
&peer->channel->funding.txid));
50805095
}
50815096
else {
5097+
status_info("Resuming splice negotation");
50825098
resume_splice_negotiation(peer, inflight, false,
50835099
inflight->i_am_initiator
50845100
? TX_INITIATOR

channeld/inflight.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,15 @@ struct inflight *fromwire_inflight(const tal_t *ctx, const u8 **cursor, size_t *
1212
inflight->amnt = fromwire_amount_sat(cursor, max);
1313
inflight->psbt = fromwire_wally_psbt(inflight, cursor, max);
1414
inflight->splice_amnt = fromwire_s64(cursor, max);
15-
inflight->last_tx = fromwire_bitcoin_tx(inflight, cursor, max);
16-
fromwire_bitcoin_signature(cursor, max, &inflight->last_sig);
15+
int has_tx = fromwire_u8(cursor, max);
16+
if(has_tx) {
17+
inflight->last_tx = fromwire_bitcoin_tx(inflight, cursor, max);
18+
fromwire_bitcoin_signature(cursor, max, &inflight->last_sig);
19+
}
20+
else {
21+
inflight->last_tx = NULL;
22+
memset(&inflight->last_sig, 0, sizeof(inflight->last_sig));
23+
}
1724
inflight->i_am_initiator = fromwire_bool(cursor, max);
1825

1926
return inflight;
@@ -25,8 +32,11 @@ void towire_inflight(u8 **pptr, const struct inflight *inflight)
2532
towire_amount_sat(pptr, inflight->amnt);
2633
towire_wally_psbt(pptr, inflight->psbt);
2734
towire_s64(pptr, inflight->splice_amnt);
28-
towire_bitcoin_tx(pptr, inflight->last_tx);
29-
towire_bitcoin_signature(pptr, &inflight->last_sig);
35+
towire_u8(pptr, inflight->last_tx ? 1 : 0);
36+
if(inflight->last_tx) {
37+
towire_bitcoin_tx(pptr, inflight->last_tx);
38+
towire_bitcoin_signature(pptr, &inflight->last_sig);
39+
}
3040
towire_bool(pptr, inflight->i_am_initiator);
3141
}
3242

common/jsonrpc_errors.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ enum jsonrpc_errcode {
7373
SPLICE_NOT_SUPPORTED = 354,
7474
SPLICE_BUSY_ERROR = 355,
7575
SPLICE_INPUT_ERROR = 356,
76+
SPLICE_FUNDING_LOW = 357,
77+
SPLICE_STATE_ERROR = 358,
78+
SPLICE_LOW_FEE = 359,
79+
SPLICE_HIGH_FEE = 360,
7680

7781
/* `connect` errors */
7882
CONNECT_NO_KNOWN_ADDRESS = 400,

0 commit comments

Comments
 (0)