multi: add taproot support to the new RBF close flow
In this PR, we implement comprehensive taproot RBF cooperative channel closing support for LND. The implementation extends the existing RBF cooperative close protocol to support taproot channels using MuSig2 signatures and introduces a JIT (Just-In-Time) nonce pattern for secure and efficient nonce management during RBF iterations.
wire + state machine changes
The implementation introduces taproot-specific wire protocol extensions for the shutdown, closing_complete, and closing_sig messages. The shutdown message now carries closee nonces for taproot channels, while closing_complete uses PartialSigWithNonce structures that bundle partial signatures with next-round nonces. The closing_sig message uses separate PartialSig and NextCloseeNonce fields to optimize nonce delivery timing.
The cooperative close state machine has been extended with taproot channel detection through the IsTaproot() method and comprehensive nonce state management. The implementation maintains separate LocalMusigSession and RemoteMusigSession contexts for handling the asymmetric closer/closee roles in the taproot closing flow.
New signature extraction and validation helpers handle both taproot partial signatures and traditional ECDSA signatures with proper type validation. The partialSigToWireSig, extractTaprootSigAndNonce, and validateAndExtractSigAndNonce functions provide robust signature handling while maintaining backward compatibility.
The state transitions have been updated to properly initialize MuSig2 sessions with appropriate closee nonces, handle signature preparation for both channel types, and manage the complex nonce rotation required for secure RBF iterations. The implementation includes comprehensive error handling for taproot-specific validation requirements.
Fixes https://github.com/lightningnetwork/lnd/issues/9662
Pull reviewers stats
Stats of the last 30 days for lnd:
| User | Total reviews | Time to review | Total comments | |
|---|---|---|---|---|
| guggero 🥇 |
47 ▀▀▀ |
1d 4h 25m |
87 ▀▀▀ |
|
| yyforyongyu 🥈 |
25 ▀▀ |
22h 50m |
43 ▀ |
|
| bhandras 🥉 |
22 ▀ |
1d 6h 15m |
29 ▀ |
|
| ellemouton |
14 ▀ |
2d 17h 12m ▀ |
42 ▀ |
|
| ziggie1984 |
14 ▀ |
2d 3h 47m ▀ |
63 ▀▀ |
|
| Roasbeef |
8 ▀ |
1d 16h 16m ▀ |
21 ▀ |
|
| bitromortac |
7 |
1d 6h 40m |
13 |
|
| starius |
3 |
1d 8h 1m |
7 |
|
| ViktorTigerstrom |
3 |
6h 49m |
0 |
|
| Abdulkbk |
3 |
12h 13m |
3 |
|
| saubyk |
2 |
3d 3h 14m ▀ |
4 |
|
| MPins |
2 |
2d 19h 55m ▀ |
4 |
|
| alexbosworth |
1 |
3d 16h 59m ▀ |
1 |
|
| ffranr |
1 |
7d 2h 16m ▀▀ |
1 |
|
| gijswijs |
1 |
22m |
0 |
|
| hieblmi |
1 |
10h 12m |
0 |
|
| morehouse |
1 |
7h |
0 |
Tacked on a commit to revise the way to handling the parsing of the various sigs. I still find the spec somewhat confusing (eg: why would I ever send both sig types? the sig can only cover one txn...), but I think this should fix a regression reported by t-bast when testing, and also make the logic here a bit more explicit.
I'm halfway there, meanwhile I just realized there are some commits in the base branch, i think we should rebase on master?
So it's built on a few branches stacked on top of each other, it can't be directly based on master.
Pushed a major bug fix, discovered during interop testing: https://github.com/lightningnetwork/lnd/pull/10063/commits/7fa6395416391ee0b9d6bb59dba46b53660af87f
@gijswijs: review reminder @roasbeef, remember to re-request review from reviewers when ready