Alice Bob
| |
| splice_locked -------> |
| update_add_htlc -------> |
| commit_sig -------> | batch_size=2, funding_tx=funding_tx_1
| commit_sig -------> | batch_size=2, funding_tx=funding_tx_2
| splice_locked | (recieved)
| <------- splice_locked | (sent)
| | NOTE: Bob now expects a single commit_sig
2025-02-01T22:42:36.4316216Z Current runner version: '2.322.0' | |
2025-02-01T22:42:36.4345187Z ##[group]Operating System | |
2025-02-01T22:42:36.4345932Z Ubuntu | |
2025-02-01T22:42:36.4346362Z 22.04.5 | |
2025-02-01T22:42:36.4346982Z LTS | |
2025-02-01T22:42:36.4347454Z ##[endgroup] | |
2025-02-01T22:42:36.4347914Z ##[group]Runner Image | |
2025-02-01T22:42:36.4348582Z Image: ubuntu-22.04 | |
2025-02-01T22:42:36.4349089Z Version: 20250126.1.0 | |
2025-02-01T22:42:36.4350035Z Included Software: https://github.com/actions/runner-images/blob/ubuntu22/20250126.1/images/ubuntu/Ubuntu2204-Readme.md |
I accomplished two primary things with my time. The first is a large progression towards so called "inter-op" for Splicing with Eclair. Inter-op is when two separate lightning implementations support splicing and are able to perform a splice between the two implementations. Essentially this means having a channel between the Eclair and CLN implementations, then doing a splice over that channel. Once a single splice is completed, numerous edge and corner cases are tested and must be handled robustly by both implementations.
This step is a big deal because once completed splicing officially becomes part of the Lightning specification for BOLTs 2, 7, and 9.
In a test environment I setup Eclair and CLN nodes and formed a channel between them. Then I attempted splicing. Numerous issues and incompatibilities emerged and had to be addressed.
These tests are important to lightning for two reasons:
Question of reestablish and `tx_abort`. | |
We two nodes, l1 and l2 who are doing an interactive splice. Both sides have sent `tx_complete` and the splice has reached the signing phase. | |
By signature ordering rules, l2 signs first. | |
``` | |
l1 l2 | |
<- commit_sig | |
*l1 restarts* |
Imagine a three node network with two channels
A <-> B <-> C
Let's say B would like to perform two splices:
splice-out 10M sats from A <-> B
splice-out 10M sats from B <-> C
IMMEDIATELY AFTER RECEIVING CHANNEL_REESTABLISH
- Do we have any active inflight splices?
- Yes:
- does latest splice inflight have commit and remote sig?
- Yes: continue
- No: send next_funding txid of latest inflight candidate, then, continue
- peer sends next_funding value of:
- None: Have I sent splice tx signatures?
- Yes: Have I received splice tx signatures?
- None: Have I sent splice tx signatures?
- does latest splice inflight have commit and remote sig?
- Yes:
- Yes: send nothing
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/stat.h> | |
#include <sys/mman.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
/* | |
* Often while rebasing, the git merge algorithm will leave these |
splice_locked -> | |
<- splice_locked | |
(Whichever side has lower funding pubkey starts STFU) | |
STFU -> | |
<- STFU (ack) | |
splice_locked_ack -> | |
<- splice_locked_ack | |
Receiving splice_locked_ack ends STFU mode and | |
means we can atomically move to the new channel | |
confirmed state. |
Legend: | |
Item -> means sent | |
Item <- means received | |
Chan X (implies a channel at block height X) | |
(Since these happen at different times) | |
Splice locked race condition example | |
Node A. Node B. |
#include <stdio.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <math.h> | |
#include "BTCUtil.h" | |
#include "../libraries/mnemonic/mnemonic.h" | |
#include "../libraries/mnemonic/wordlist.h" | |
static const char *answer = "bc1qh07vgylvs66k850vr5e7efxxemhdgczj8w72xq"; | |
static int found = 0; |