Skip to content

Commit a45189c

Browse files
ddustinrustyrussell
authored andcommitted
splice: Update to current spec
Updating splice related reestablish code to lightning/bolts#1289 and lightning/bolts#1160 Changelog-Changed: Breaking change -- if you have splicing enabled on a channel both nodes must upgrade in unison due to updating `channel_reestablish` for to new splice specifications
1 parent add398f commit a45189c

File tree

4 files changed

+136
-114
lines changed

4 files changed

+136
-114
lines changed

channeld/channeld.c

Lines changed: 123 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,32 @@ static void check_mutual_splice_locked(struct peer *peer)
487487
peer->splice_state->remote_locked_txid = tal_free(peer->splice_state->remote_locked_txid);
488488
}
489489

490+
static void implied_peer_splice_locked(struct peer *peer,
491+
struct bitcoin_txid splice_txid)
492+
{
493+
/* If we've `mutual_splice_locked` but our peer hasn't, we can ignore
494+
* this message harmlessly */
495+
if (!tal_count(peer->splice_state->inflights)) {
496+
status_info("Peer implied redundant splice_locked, ignoring");
497+
return;
498+
}
499+
500+
/* If we've `mutual_splice_locked` but our peer hasn't, we can ignore
501+
* this message harmlessly */
502+
if (!tal_count(peer->splice_state->inflights)) {
503+
status_info("Peer implied redundant splice_locked, ignoring");
504+
return;
505+
}
506+
507+
peer->splice_state->remote_locked_txid = tal(peer->splice_state,
508+
struct bitcoin_txid);
509+
510+
*peer->splice_state->remote_locked_txid = splice_txid;
511+
512+
peer->splice_state->locked_ready[REMOTE] = true;
513+
check_mutual_splice_locked(peer);
514+
}
515+
490516
/* Our peer told us they saw our splice confirm on chain with `splice_locked`.
491517
* If we see it to we jump into transitioning to post-splice, otherwise we mark
492518
* a flag and wait until we see it on chain too. */
@@ -504,11 +530,6 @@ static void handle_peer_splice_locked(struct peer *peer, const u8 *msg)
504530
"Peer sent duplicate splice_locked message %s",
505531
tal_hex(tmpctx, msg));
506532

507-
peer->splice_state->remote_locked_txid = tal(peer->splice_state,
508-
struct bitcoin_txid);
509-
510-
*peer->splice_state->remote_locked_txid = splice_txid;
511-
512533
if (!channel_id_eq(&chanid, &peer->channel_id))
513534
peer_failed_err(peer->pps, &chanid,
514535
"Wrong splice lock channel id in %s "
@@ -523,8 +544,7 @@ static void handle_peer_splice_locked(struct peer *peer, const u8 *msg)
523544
return;
524545
}
525546

526-
peer->splice_state->locked_ready[REMOTE] = true;
527-
check_mutual_splice_locked(peer);
547+
implied_peer_splice_locked(peer, splice_txid);
528548
}
529549

530550
static void handle_peer_channel_ready(struct peer *peer, const u8 *msg)
@@ -5491,8 +5511,8 @@ static void peer_reconnect(struct peer *peer,
54915511
bool dataloss_protect, check_extra_fields;
54925512
const u8 **premature_msgs = tal_arr(peer, const u8 *, 0);
54935513
struct inflight *inflight;
5494-
struct bitcoin_txid *local_next_funding, *remote_next_funding,
5495-
*remote_your_last_funding;
5514+
struct tlv_channel_reestablish_tlvs_next_funding *local_next_funding,
5515+
*remote_next_funding;
54965516
u64 send_next_commitment_number;
54975517

54985518
struct tlv_channel_reestablish_tlvs *send_tlvs, *recv_tlvs;
@@ -5535,17 +5555,25 @@ static void peer_reconnect(struct peer *peer,
55355555
* tal off peer */
55365556
send_tlvs = tlv_channel_reestablish_tlvs_new(peer);
55375557
}
5538-
send_tlvs->next_funding = &inflight->outpoint.txid;
5539-
5540-
/* Eclair wants us to decrement commitment number to
5541-
* indicate that we would like them to re-send
5542-
* commitment signatures */
5543-
/* DTODO: Add bolt reference */
5558+
send_tlvs->next_funding = talz(send_tlvs, struct tlv_channel_reestablish_tlvs_next_funding);
5559+
send_tlvs->next_funding->next_funding_txid = inflight->outpoint.txid;
5560+
5561+
/* BOLT-??? #2:
5562+
* The `next_funding.retransmit_flags` bitfield is used to let the
5563+
* receiving peer know which messages they must retransmit for the
5564+
* corresponding `next_funding_txid` after the reconnection:
5565+
* | Bit Position | Name |
5566+
* | ------------- | --------------------|
5567+
* | 0 | `commitment_signed` |
5568+
*/
55445569
if (!inflight->last_tx)
5545-
send_next_commitment_number--;
5570+
send_tlvs->next_funding->retransmit_flags |= 1; /* commitment_signed */
55465571
}
55475572
}
55485573

5574+
/* BOLT-??? #2:
5575+
* - if `option_splice` was negotiated:
5576+
*/
55495577
if (feature_negotiated(peer->our_features, peer->their_features,
55505578
OPT_SPLICE)) {
55515579
if (!send_tlvs) {
@@ -5554,46 +5582,67 @@ static void peer_reconnect(struct peer *peer,
55545582
send_tlvs = tlv_channel_reestablish_tlvs_new(peer);
55555583
}
55565584

5557-
if (peer->channel_ready[REMOTE])
5558-
send_tlvs->your_last_funding_locked_txid = &peer->channel->funding.txid;
5559-
5560-
send_tlvs->my_current_funding_locked_txid = &peer->channel->funding.txid;
5561-
status_debug("Setting send_tlvs->my_current_funding_locked_txid"
5562-
" to %s",
5563-
fmt_bitcoin_txid(tmpctx,
5564-
&peer->channel->funding.txid));
5565-
55665585
for (size_t i = 0; i < tal_count(peer->splice_state->inflights); i++) {
55675586
struct inflight *itr = peer->splice_state->inflights[i];
55685587
if (itr->locked_scid) {
5569-
send_tlvs->my_current_funding_locked_txid = &itr->outpoint.txid;
5570-
status_debug("Overriding send_tlvs->my_current_"
5571-
"funding_locked_txid to %s because"
5572-
" inflight is locked to scid %s",
5573-
fmt_bitcoin_txid(tmpctx,
5574-
&itr->outpoint.txid),
5575-
fmt_short_channel_id(tmpctx,
5576-
*itr->locked_scid));
5588+
peer->splice_state->short_channel_id = *itr->locked_scid;
5589+
peer->splice_state->locked_txid = itr->outpoint.txid;
5590+
peer->splice_state->locked_ready[LOCAL] = true;
55775591
}
55785592
}
5593+
5594+
/* BOLT-??? #2:
5595+
* - if a splice transaction reached acceptable depth while disconnected:
5596+
* - MUST include `my_current_funding_locked` with the txid of the latest such transaction.
5597+
* - otherwise, if it has already sent `splice_locked` for any transaction:
5598+
* - MUST include `my_current_funding_locked` with the txid of the last `splice_locked` it sent.
5599+
*/
5600+
if (peer->splice_state->locked_ready[LOCAL]) {
5601+
5602+
send_tlvs->my_current_funding_locked = talz(send_tlvs, struct tlv_channel_reestablish_tlvs_my_current_funding_locked);
5603+
send_tlvs->my_current_funding_locked->my_current_funding_locked_txid = peer->splice_state->locked_txid;
5604+
status_debug("Setting send_tlvs->my_current_funding"
5605+
"_locked_txid to splice txid %s",
5606+
fmt_bitcoin_txid(tmpctx,
5607+
&peer->splice_state->locked_txid));
5608+
}
5609+
/* BOLT-??? #2:
5610+
* - otherwise, if it has already sent `channel_ready`:
5611+
* - MUST include `my_current_funding_locked` with the txid of the channel funding transaction.
5612+
*/
5613+
else if (peer->channel_ready[LOCAL]) {
5614+
5615+
send_tlvs->my_current_funding_locked = talz(send_tlvs, struct tlv_channel_reestablish_tlvs_my_current_funding_locked);
5616+
send_tlvs->my_current_funding_locked->my_current_funding_locked_txid = peer->channel->funding.txid;
5617+
status_debug("Setting send_tlvs->my_current_funding"
5618+
"_locked_txid to channel txid %s",
5619+
fmt_bitcoin_txid(tmpctx,
5620+
&peer->channel->funding.txid));
5621+
}
5622+
/* BOLT-??? #2:
5623+
* - otherwise (it has never sent `channel_ready` or `splice_locked`):
5624+
* - MUST NOT include `my_current_funding_locked`.
5625+
*/
5626+
else {
5627+
status_debug("Not setting send_tlvs->my_current_funding"
5628+
"_locked_txid (funding txid %s)",
5629+
fmt_bitcoin_txid(tmpctx,
5630+
&peer->channel->funding.txid));
5631+
assert(!send_tlvs->my_current_funding_locked);
5632+
}
55795633
}
55805634

55815635
status_debug("Sending channel_reestablish with"
55825636
" next_funding_tx_id: %s,"
5583-
" your_last_funding_locked: %s,"
55845637
" my_current_funding_locked: %s,"
55855638
" next_local_commit_number: %"PRIu64",",
55865639
send_tlvs && send_tlvs->next_funding
55875640
? fmt_bitcoin_txid(tmpctx,
5588-
send_tlvs->next_funding)
5589-
: "NULL",
5590-
send_tlvs && send_tlvs->your_last_funding_locked_txid
5591-
? fmt_bitcoin_txid(tmpctx,
5592-
send_tlvs->your_last_funding_locked_txid)
5641+
&send_tlvs->next_funding->next_funding_txid)
55935642
: "NULL",
5594-
send_tlvs && send_tlvs->my_current_funding_locked_txid
5643+
send_tlvs && send_tlvs->my_current_funding_locked
55955644
? fmt_bitcoin_txid(tmpctx,
5596-
send_tlvs->my_current_funding_locked_txid)
5645+
&send_tlvs->my_current_funding_locked->my_current_funding_locked_txid)
55975646
: "NULL",
55985647
send_next_commitment_number);
55995648

@@ -5709,7 +5758,7 @@ static void peer_reconnect(struct peer *peer,
57095758
!inflight->last_tx,
57105759
false,
57115760
true);
5712-
} else if (bitcoin_txid_eq(remote_next_funding,
5761+
} else if (bitcoin_txid_eq(&remote_next_funding->next_funding_txid,
57135762
&inflight->outpoint.txid)) {
57145763
/* Don't send sigs unless we have theirs */
57155764
assert(local_next_funding || inflight->remote_tx_sigs);
@@ -5719,11 +5768,13 @@ static void peer_reconnect(struct peer *peer,
57195768
if (local_next_funding)
57205769
assume_stfu_mode(peer);
57215770
resume_splice_negotiation(peer,
5722-
next_commitment_number == peer->next_index[REMOTE] - 1,
5771+
remote_next_funding
5772+
? remote_next_funding->retransmit_flags & 1
5773+
: false,
57235774
local_next_funding && !inflight->last_tx,
57245775
true,
57255776
local_next_funding);
5726-
} else if (bitcoin_txid_eq(remote_next_funding,
5777+
} else if (bitcoin_txid_eq(&remote_next_funding->next_funding_txid,
57275778
&peer->channel->funding.txid)) {
57285779
peer_failed_err(peer->pps,
57295780
&peer->channel_id,
@@ -5732,7 +5783,7 @@ static void peer_reconnect(struct peer *peer,
57325783
" active funding txid %s. Should be %s"
57335784
" or NULL",
57345785
fmt_bitcoin_txid(tmpctx,
5735-
remote_next_funding),
5786+
&remote_next_funding->next_funding_txid),
57365787
fmt_bitcoin_txid(tmpctx,
57375788
&peer->channel->funding.txid),
57385789
fmt_bitcoin_txid(tmpctx,
@@ -5743,71 +5794,21 @@ static void peer_reconnect(struct peer *peer,
57435794
"Invalid reestablish with unrecognized"
57445795
" next_funding txid %s, should be %s",
57455796
fmt_bitcoin_txid(tmpctx,
5746-
remote_next_funding),
5797+
&remote_next_funding->next_funding_txid),
57475798
fmt_bitcoin_txid(tmpctx,
57485799
&inflight->outpoint.txid));
57495800
}
57505801
} else if (remote_next_funding) { /* No current inflight */
57515802
/* If our peer is trying to negotiate details about a splice
57525803
* that is already onchain, jump ahead to sending splice_lock */
5753-
if (bitcoin_txid_eq(remote_next_funding,
5754-
&peer->channel->funding.txid)) {
5804+
if (bitcoin_txid_eq(&remote_next_funding->next_funding_txid,
5805+
&peer->channel->funding.txid))
57555806
status_info("We have no pending splice but peer"
5756-
" is negotiating one; resending"
5757-
" splice_lock %s",
5807+
" is negotiating one that matches current"
5808+
" channel, ignoring it: %s",
57585809
fmt_bitcoin_outpoint(tmpctx, &peer->channel->funding));
5759-
peer_write(peer->pps,
5760-
take(towire_splice_locked(NULL,
5761-
&peer->channel_id,
5762-
&peer->channel->funding.txid)));
5763-
}
5764-
else {
5765-
splice_abort(peer, "next_funding_txid not recognized."
5766-
" Sending tx_abort.");
5767-
}
5768-
}
5769-
5770-
/* Re-send `splice_locked` if an inflight is locked */
5771-
for (size_t i = 0; i < tal_count(peer->splice_state->inflights); i++) {
5772-
struct inflight *itr = peer->splice_state->inflights[i];
5773-
if (!itr->locked_scid)
5774-
continue;
5775-
5776-
status_info("Resending splice_locked because an inflight %s is"
5777-
" locked",
5778-
fmt_bitcoin_outpoint(tmpctx, &itr->outpoint));
5779-
peer_write(peer->pps,
5780-
take(towire_splice_locked(NULL,
5781-
&peer->channel_id,
5782-
&itr->outpoint.txid)));
5783-
peer->splice_state->locked_ready[LOCAL] = true;
5784-
}
5785-
5786-
/* If no inflight, no splice negotiation, but
5787-
`your_last_funding_locked_txid is stale, re-send `splice_locked`. */
5788-
if (!inflight && !remote_next_funding
5789-
&& feature_negotiated(peer->our_features, peer->their_features,
5790-
OPT_SPLICE)) {
5791-
remote_your_last_funding = recv_tlvs
5792-
? recv_tlvs->your_last_funding_locked_txid : NULL;
5793-
if (remote_your_last_funding
5794-
&& !bitcoin_txid_eq(&peer->channel->funding.txid,
5795-
remote_your_last_funding)) {
5796-
status_info("Resending splice_locked with no inflight,"
5797-
" no splice negotation, but we did recv"
5798-
" remote_your_last_funding value of %s"
5799-
" instead of %s. Our sent splice_locked"
5800-
" value is %s.",
5801-
remote_your_last_funding
5802-
? fmt_bitcoin_txid(tmpctx, remote_your_last_funding)
5803-
: "NULL",
5804-
fmt_bitcoin_outpoint(tmpctx, &peer->channel->funding),
5805-
fmt_bitcoin_txid(tmpctx, &peer->channel->funding.txid));
5806-
peer_write(peer->pps,
5807-
take(towire_splice_locked(NULL,
5808-
&peer->channel_id,
5809-
&peer->channel->funding.txid)));
5810-
}
5810+
else
5811+
splice_abort(peer, "next_funding_txid not recognized.");
58115812
}
58125813

58135814
/* BOLT #2:
@@ -5835,6 +5836,26 @@ static void peer_reconnect(struct peer *peer,
58355836
peer_write(peer->pps, take(msg));
58365837
}
58375838

5839+
/* BOLT-??? #2
5840+
* A receiving node:
5841+
* - if splice transactions are pending and `my_current_funding_locked` matches one of
5842+
* those splice transactions, for which it hasn't received `splice_locked` yet:
5843+
*/
5844+
if (inflight && recv_tlvs && recv_tlvs->my_current_funding_locked) {
5845+
for (size_t i = 0; i < tal_count(peer->splice_state->inflights); i++) {
5846+
struct inflight *itr = peer->splice_state->inflights[i];
5847+
if (!bitcoin_txid_eq(&itr->outpoint.txid,
5848+
&recv_tlvs->my_current_funding_locked->my_current_funding_locked_txid))
5849+
continue;
5850+
/* BOLT-??? #2
5851+
* - MUST process `my_current_funding_locked` as if it was receiving `splice_locked`
5852+
* for this `txid`.
5853+
*/
5854+
implied_peer_splice_locked(peer, itr->outpoint.txid);
5855+
break;
5856+
}
5857+
}
5858+
58385859
/* Note: next_index is the index of the current commit we're working
58395860
* on, but BOLT #2 refers to the *last* commit index, so we -1 where
58405861
* required. */

openingd/dualopend.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3986,8 +3986,11 @@ static void do_reconnect_dance(struct state *state)
39863986
* - MUST NOT set `next_funding_txid`.
39873987
*/
39883988
tlvs = tlv_channel_reestablish_tlvs_new(tmpctx);
3989-
if (!tx_state->remote_funding_sigs_rcvd)
3990-
tlvs->next_funding = &tx_state->funding.txid;
3989+
if (!tx_state->remote_funding_sigs_rcvd) {
3990+
tlvs->next_funding = talz(tlvs, struct tlv_channel_reestablish_tlvs_next_funding);
3991+
tlvs->next_funding->next_funding_txid = tx_state->funding.txid;
3992+
tlvs->next_funding->retransmit_flags = 1; /* COMMITMENT_SIGNED */
3993+
}
39913994

39923995
msg = towire_channel_reestablish
39933996
(NULL, &state->channel_id, 1, 0,
@@ -4060,7 +4063,7 @@ static void do_reconnect_dance(struct state *state)
40604063
*/
40614064
if (tlvs->next_funding) {
40624065
/* Does this match ours? */
4063-
if (bitcoin_txid_eq(tlvs->next_funding, &tx_state->funding.txid)) {
4066+
if (bitcoin_txid_eq(&tlvs->next_funding->next_funding_txid, &tx_state->funding.txid)) {
40644067
bool send_our_sigs = true;
40654068
char *err;
40664069
/* We haven't gotten their tx_sigs */
@@ -4089,7 +4092,7 @@ static void do_reconnect_dance(struct state *state)
40894092
open_abort(state, "Sent next_funding_txid %s doesn't match ours %s",
40904093

40914094
fmt_bitcoin_txid(tmpctx,
4092-
tlvs->next_funding),
4095+
&tlvs->next_funding->next_funding_txid),
40934096
fmt_bitcoin_txid(tmpctx,
40944097
&tx_state->funding.txid));
40954098
return;

tests/fuzz/fuzz-wire-channel_reestablish.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ static bool equal(const struct channel_reestablish *x,
4848

4949
if (!tal_arr_eq(x->tlvs->next_funding, y->tlvs->next_funding))
5050
return false;
51-
if (!tal_arr_eq(x->tlvs->your_last_funding_locked_txid, y->tlvs->your_last_funding_locked_txid))
52-
return false;
53-
if (!tal_arr_eq(x->tlvs->my_current_funding_locked_txid, y->tlvs->my_current_funding_locked_txid))
51+
if (!tal_arr_eq(x->tlvs->my_current_funding_locked, y->tlvs->my_current_funding_locked))
5452
return false;
5553
#if EXPERIMENTAL_UPGRADE_ENABLED
5654
if (!tal_arr_eq(x->tlvs->next_to_send, y->tlvs->next_to_send))

wire/peer_wire.csv

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -326,12 +326,12 @@ msgdata,channel_reestablish,next_commitment_number,u64,
326326
msgdata,channel_reestablish,next_revocation_number,u64,
327327
msgdata,channel_reestablish,your_last_per_commitment_secret,byte,32
328328
msgdata,channel_reestablish,my_current_per_commitment_point,point,
329-
tlvtype,channel_reestablish_tlvs,next_funding,0
329+
tlvtype,channel_reestablish_tlvs,next_funding,1
330330
tlvdata,channel_reestablish_tlvs,next_funding,next_funding_txid,sha256,
331-
tlvtype,channel_reestablish_tlvs,your_last_funding_locked_txid,1
332-
tlvdata,channel_reestablish_tlvs,your_last_funding_locked_txid,your_last_funding_locked_txid,sha256,
333-
tlvtype,channel_reestablish_tlvs,my_current_funding_locked_txid,3
334-
tlvdata,channel_reestablish_tlvs,my_current_funding_locked_txid,my_current_funding_locked_txid,sha256,
331+
tlvdata,channel_reestablish_tlvs,next_funding,retransmit_flags,byte,
332+
tlvtype,channel_reestablish_tlvs,my_current_funding_locked,5
333+
tlvdata,channel_reestablish_tlvs,my_current_funding_locked,my_current_funding_locked_txid,sha256,
334+
tlvdata,channel_reestablish_tlvs,my_current_funding_locked,retransmit_flags,byte,
335335
msgtype,announcement_signatures,259
336336
msgdata,announcement_signatures,channel_id,channel_id,
337337
msgdata,announcement_signatures,short_channel_id,short_channel_id,

0 commit comments

Comments
 (0)