Skip to content

Commit ea75b61

Browse files
committed
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 4f9e13c commit ea75b61

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
@@ -489,6 +489,32 @@ static void check_mutual_splice_locked(struct peer *peer)
489489
peer->splice_state->remote_locked_txid = tal_free(peer->splice_state->remote_locked_txid);
490490
}
491491

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

509-
peer->splice_state->remote_locked_txid = tal(peer->splice_state,
510-
struct bitcoin_txid);
511-
512-
*peer->splice_state->remote_locked_txid = splice_txid;
513-
514535
if (!channel_id_eq(&chanid, &peer->channel_id))
515536
peer_failed_err(peer->pps, &chanid,
516537
"Wrong splice lock channel id in %s "
@@ -525,8 +546,7 @@ static void handle_peer_splice_locked(struct peer *peer, const u8 *msg)
525546
return;
526547
}
527548

528-
peer->splice_state->locked_ready[REMOTE] = true;
529-
check_mutual_splice_locked(peer);
549+
implied_peer_splice_locked(peer, splice_txid);
530550
}
531551

532552
static void handle_peer_channel_ready(struct peer *peer, const u8 *msg)
@@ -5485,8 +5505,8 @@ static void peer_reconnect(struct peer *peer,
54855505
bool dataloss_protect, check_extra_fields;
54865506
const u8 **premature_msgs = tal_arr(peer, const u8 *, 0);
54875507
struct inflight *inflight;
5488-
struct bitcoin_txid *local_next_funding, *remote_next_funding,
5489-
*remote_your_last_funding;
5508+
struct tlv_channel_reestablish_tlvs_next_funding *local_next_funding,
5509+
*remote_next_funding;
54905510
u64 send_next_commitment_number;
54915511

54925512
struct tlv_channel_reestablish_tlvs *send_tlvs, *recv_tlvs;
@@ -5529,17 +5549,27 @@ static void peer_reconnect(struct peer *peer,
55295549
* tal off peer */
55305550
send_tlvs = tlv_channel_reestablish_tlvs_new(peer);
55315551
}
5532-
send_tlvs->next_funding = &inflight->outpoint.txid;
5533-
5534-
/* Eclair wants us to decrement commitment number to
5535-
* indicate that we would like them to re-send
5536-
* commitment signatures */
5537-
/* DTODO: Add bolt reference */
5538-
if (!inflight->last_tx)
5552+
send_tlvs->next_funding = talz(send_tlvs, struct tlv_channel_reestablish_tlvs_next_funding);
5553+
send_tlvs->next_funding->next_funding_txid = inflight->outpoint.txid;
5554+
5555+
/* BOLT-??? #2:
5556+
* The `next_funding.retransmit_flags` bitfield is used to let the
5557+
* receiving peer know which messages they must retransmit for the
5558+
* corresponding `next_funding_txid` after the reconnection:
5559+
* | Bit Position | Name |
5560+
* | ------------- | --------------------|
5561+
* | 0 | `commitment_signed` |
5562+
*/
5563+
if (!inflight->last_tx) {
55395564
send_next_commitment_number--;
5565+
send_tlvs->next_funding->retransmit_flags |= 1; /* commitment_signed */
5566+
}
55405567
}
55415568
}
55425569

5570+
/* BOLT-??? #2:
5571+
* - if `option_splice` was negotiated:
5572+
*/
55435573
if (feature_negotiated(peer->our_features, peer->their_features,
55445574
OPT_SPLICE)) {
55455575
if (!send_tlvs) {
@@ -5548,46 +5578,67 @@ static void peer_reconnect(struct peer *peer,
55485578
send_tlvs = tlv_channel_reestablish_tlvs_new(peer);
55495579
}
55505580

5551-
if (peer->channel_ready[REMOTE])
5552-
send_tlvs->your_last_funding_locked_txid = &peer->channel->funding.txid;
5553-
5554-
send_tlvs->my_current_funding_locked_txid = &peer->channel->funding.txid;
5555-
status_debug("Setting send_tlvs->my_current_funding_locked_txid"
5556-
" to %s",
5557-
fmt_bitcoin_txid(tmpctx,
5558-
&peer->channel->funding.txid));
5559-
55605581
for (size_t i = 0; i < tal_count(peer->splice_state->inflights); i++) {
55615582
struct inflight *itr = peer->splice_state->inflights[i];
55625583
if (itr->locked_scid) {
5563-
send_tlvs->my_current_funding_locked_txid = &itr->outpoint.txid;
5564-
status_debug("Overriding send_tlvs->my_current_"
5565-
"funding_locked_txid to %s because"
5566-
" inflight is locked to scid %s",
5567-
fmt_bitcoin_txid(tmpctx,
5568-
&itr->outpoint.txid),
5569-
fmt_short_channel_id(tmpctx,
5570-
*itr->locked_scid));
5584+
peer->splice_state->short_channel_id = *itr->locked_scid;
5585+
peer->splice_state->locked_txid = itr->outpoint.txid;
5586+
peer->splice_state->locked_ready[LOCAL] = true;
55715587
}
55725588
}
5589+
5590+
/* BOLT-??? #2:
5591+
* - if a splice transaction reached acceptable depth while disconnected:
5592+
* - MUST include `my_current_funding_locked` with the txid of the latest such transaction.
5593+
* - otherwise, if it has already sent `splice_locked` for any transaction:
5594+
* - MUST include `my_current_funding_locked` with the txid of the last `splice_locked` it sent.
5595+
*/
5596+
if (peer->splice_state->locked_ready[LOCAL]) {
5597+
5598+
send_tlvs->my_current_funding_locked = talz(send_tlvs, struct tlv_channel_reestablish_tlvs_my_current_funding_locked);
5599+
send_tlvs->my_current_funding_locked->my_current_funding_locked_txid = peer->splice_state->locked_txid;
5600+
status_debug("Setting send_tlvs->my_current_funding"
5601+
"_locked_txid to splice txid %s",
5602+
fmt_bitcoin_txid(tmpctx,
5603+
&peer->splice_state->locked_txid));
5604+
}
5605+
/* BOLT-??? #2:
5606+
* - otherwise, if it has already sent `channel_ready`:
5607+
* - MUST include `my_current_funding_locked` with the txid of the channel funding transaction.
5608+
*/
5609+
else if (peer->channel_ready[LOCAL]) {
5610+
5611+
send_tlvs->my_current_funding_locked = talz(send_tlvs, struct tlv_channel_reestablish_tlvs_my_current_funding_locked);
5612+
send_tlvs->my_current_funding_locked->my_current_funding_locked_txid = peer->channel->funding.txid;
5613+
status_debug("Setting send_tlvs->my_current_funding"
5614+
"_locked_txid to channel txid %s",
5615+
fmt_bitcoin_txid(tmpctx,
5616+
&peer->channel->funding.txid));
5617+
}
5618+
/* BOLT-??? #2:
5619+
* - otherwise (it has never sent `channel_ready` or `splice_locked`):
5620+
* - MUST NOT include `my_current_funding_locked`.
5621+
*/
5622+
else {
5623+
status_debug("Not setting send_tlvs->my_current_funding"
5624+
"_locked_txid (funding txid %s)",
5625+
fmt_bitcoin_txid(tmpctx,
5626+
&peer->channel->funding.txid));
5627+
assert(!send_tlvs->my_current_funding_locked);
5628+
}
55735629
}
55745630

55755631
status_debug("Sending channel_reestablish with"
55765632
" next_funding_tx_id: %s,"
5577-
" your_last_funding_locked: %s,"
55785633
" my_current_funding_locked: %s,"
55795634
" next_local_commit_number: %"PRIu64",",
55805635
send_tlvs && send_tlvs->next_funding
55815636
? fmt_bitcoin_txid(tmpctx,
5582-
send_tlvs->next_funding)
5583-
: "NULL",
5584-
send_tlvs && send_tlvs->your_last_funding_locked_txid
5585-
? fmt_bitcoin_txid(tmpctx,
5586-
send_tlvs->your_last_funding_locked_txid)
5637+
&send_tlvs->next_funding->next_funding_txid)
55875638
: "NULL",
5588-
send_tlvs && send_tlvs->my_current_funding_locked_txid
5639+
send_tlvs && send_tlvs->my_current_funding_locked
55895640
? fmt_bitcoin_txid(tmpctx,
5590-
send_tlvs->my_current_funding_locked_txid)
5641+
&send_tlvs->my_current_funding_locked->my_current_funding_locked_txid)
55915642
: "NULL",
55925643
send_next_commitment_number);
55935644

@@ -5703,7 +5754,7 @@ static void peer_reconnect(struct peer *peer,
57035754
!inflight->last_tx,
57045755
false,
57055756
true);
5706-
} else if (bitcoin_txid_eq(remote_next_funding,
5757+
} else if (bitcoin_txid_eq(&remote_next_funding->next_funding_txid,
57075758
&inflight->outpoint.txid)) {
57085759
/* Don't send sigs unless we have theirs */
57095760
assert(local_next_funding || inflight->remote_tx_sigs);
@@ -5713,11 +5764,11 @@ static void peer_reconnect(struct peer *peer,
57135764
if (local_next_funding)
57145765
assume_stfu_mode(peer);
57155766
resume_splice_negotiation(peer,
5716-
next_commitment_number == peer->next_index[REMOTE] - 1,
5767+
remote_next_funding ? remote_next_funding->retransmit_flags & 1 : false,
57175768
local_next_funding && !inflight->last_tx,
57185769
true,
57195770
local_next_funding);
5720-
} else if (bitcoin_txid_eq(remote_next_funding,
5771+
} else if (bitcoin_txid_eq(&remote_next_funding->next_funding_txid,
57215772
&peer->channel->funding.txid)) {
57225773
peer_failed_err(peer->pps,
57235774
&peer->channel_id,
@@ -5726,7 +5777,7 @@ static void peer_reconnect(struct peer *peer,
57265777
" active funding txid %s. Should be %s"
57275778
" or NULL",
57285779
fmt_bitcoin_txid(tmpctx,
5729-
remote_next_funding),
5780+
&remote_next_funding->next_funding_txid),
57305781
fmt_bitcoin_txid(tmpctx,
57315782
&peer->channel->funding.txid),
57325783
fmt_bitcoin_txid(tmpctx,
@@ -5737,71 +5788,21 @@ static void peer_reconnect(struct peer *peer,
57375788
"Invalid reestablish with unrecognized"
57385789
" next_funding txid %s, should be %s",
57395790
fmt_bitcoin_txid(tmpctx,
5740-
remote_next_funding),
5791+
&remote_next_funding->next_funding_txid),
57415792
fmt_bitcoin_txid(tmpctx,
57425793
&inflight->outpoint.txid));
57435794
}
57445795
} else if (remote_next_funding) { /* No current inflight */
57455796
/* If our peer is trying to negotiate details about a splice
57465797
* that is already onchain, jump ahead to sending splice_lock */
5747-
if (bitcoin_txid_eq(remote_next_funding,
5748-
&peer->channel->funding.txid)) {
5798+
if (bitcoin_txid_eq(&remote_next_funding->next_funding_txid,
5799+
&peer->channel->funding.txid))
57495800
status_info("We have no pending splice but peer"
5750-
" is negotiating one; resending"
5751-
" splice_lock %s",
5801+
" is negotiating one that matches current"
5802+
" channel, ignoring it: %s",
57525803
fmt_bitcoin_outpoint(tmpctx, &peer->channel->funding));
5753-
peer_write(peer->pps,
5754-
take(towire_splice_locked(NULL,
5755-
&peer->channel_id,
5756-
&peer->channel->funding.txid)));
5757-
}
5758-
else {
5759-
splice_abort(peer, "next_funding_txid not recognized."
5760-
" Sending tx_abort.");
5761-
}
5762-
}
5763-
5764-
/* Re-send `splice_locked` if an inflight is locked */
5765-
for (size_t i = 0; i < tal_count(peer->splice_state->inflights); i++) {
5766-
struct inflight *itr = peer->splice_state->inflights[i];
5767-
if (!itr->locked_scid)
5768-
continue;
5769-
5770-
status_info("Resending splice_locked because an inflight %s is"
5771-
" locked",
5772-
fmt_bitcoin_outpoint(tmpctx, &itr->outpoint));
5773-
peer_write(peer->pps,
5774-
take(towire_splice_locked(NULL,
5775-
&peer->channel_id,
5776-
&itr->outpoint.txid)));
5777-
peer->splice_state->locked_ready[LOCAL] = true;
5778-
}
5779-
5780-
/* If no inflight, no splice negotiation, but
5781-
`your_last_funding_locked_txid is stale, re-send `splice_locked`. */
5782-
if (!inflight && !remote_next_funding
5783-
&& feature_negotiated(peer->our_features, peer->their_features,
5784-
OPT_SPLICE)) {
5785-
remote_your_last_funding = recv_tlvs
5786-
? recv_tlvs->your_last_funding_locked_txid : NULL;
5787-
if (remote_your_last_funding
5788-
&& !bitcoin_txid_eq(&peer->channel->funding.txid,
5789-
remote_your_last_funding)) {
5790-
status_info("Resending splice_locked with no inflight,"
5791-
" no splice negotation, but we did recv"
5792-
" remote_your_last_funding value of %s"
5793-
" instead of %s. Our sent splice_locked"
5794-
" value is %s.",
5795-
remote_your_last_funding
5796-
? fmt_bitcoin_txid(tmpctx, remote_your_last_funding)
5797-
: "NULL",
5798-
fmt_bitcoin_outpoint(tmpctx, &peer->channel->funding),
5799-
fmt_bitcoin_txid(tmpctx, &peer->channel->funding.txid));
5800-
peer_write(peer->pps,
5801-
take(towire_splice_locked(NULL,
5802-
&peer->channel_id,
5803-
&peer->channel->funding.txid)));
5804-
}
5804+
else
5805+
splice_abort(peer, "next_funding_txid not recognized.");
58055806
}
58065807

58075808
/* BOLT #2:
@@ -5829,6 +5830,26 @@ static void peer_reconnect(struct peer *peer,
58295830
peer_write(peer->pps, take(msg));
58305831
}
58315832

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