@@ -178,6 +178,35 @@ The `CloseErr` state provides recovery paths when protocol violations occur:
178178
179179Recovery typically involves restarting the negotiation with a new closing offer.
180180
181+ ### RBF Nonce Flow Example
182+
183+ Here's how nonces flow through an RBF cooperative close with taproot:
184+
185+ 1 . ** Initial Shutdown** :
186+ - Alice sends ` shutdown ` with her closee nonce ` NA `
187+ - Bob sends ` shutdown ` with his closee nonce ` NB `
188+
189+ 2 . ** First Close Attempt** (Alice as closer):
190+ - Alice sends ` closing_complete ` :
191+ - Uses Bob's nonce NB (from shutdown) to create her closer signature
192+ - Includes ` PartialSigWithNonce ` with her next closee nonce ` NA2 `
193+ - Bob sends ` closing_sig ` :
194+ - Uses Alice's nonce NA (from shutdown) to create his closee signature
195+ - Includes ` NextCloseeNonce ` with his next closee nonce ` NB2 `
196+
197+ 3 . ** RBF Iteration** (Bob as closer):
198+ - Bob sends ` closing_complete ` :
199+ - Uses Alice's nonce NA2 (from previous ` PartialSigWithNonce ` ) to create
200+ his closer signature
201+ - Includes ` PartialSigWithNonce ` with his next closee nonce ` NB3 `
202+ - Alice sends ` closing_sig ` :
203+ - Uses Bob's nonce NB2 (from previous ` NextCloseeNonce ` ) to create her
204+ closee signature
205+ - Includes ` NextCloseeNonce ` with her next closee nonce ` NA3 `
206+
207+ The pattern continues with each party using the nonce they received in the
208+ previous round.
209+
181210## Example Scenarios
182211
183212### Standard Cooperative Close
@@ -211,9 +240,103 @@ Recovery typically involves restarting the negotiation with a new closing offer.
2112405 . When agreement is reached on new fees: ` ClosePending ` → ` CloseFin ` (via
212241 ` txn_confirmation ` )
213242
243+ ## Taproot Channel Support
244+
245+ ### MuSig2 Nonce Handling
246+
247+ For taproot channels, the cooperative close process requires coordination for
248+ MuSig2 signature creation using a JIT (Just-In-Time) nonce pattern:
249+
250+ #### Nonce Exchange During Shutdown
251+
252+ For taproot channels using the modern RBF cooperative close flow:
253+ - The ` shutdown ` message includes a single nonce field:
254+ - ` shutdown_nonce ` (TLV type 8): The sender's "closee nonce" used when they
255+ send ` closing_sig `
256+ - This simplified approach works because nonces are sent JIT with signatures
257+
258+ #### JIT (Just-In-Time) Nonce Pattern
259+
260+ The protocol uses an asymmetric signature pattern for taproot channels that
261+ optimizes nonce delivery:
262+
263+ ** Asymmetric Roles** :
264+ - ** Closer** : The party proposing a fee (sends ` closing_complete ` )
265+ - ** Closee** : The party accepting the fee (sends ` closing_sig ` )
266+
267+ ** ClosingComplete (from Closer)** :
268+ - Uses ` PartialSigWithNonce ` (98 bytes total):
269+ - The partial signature (32 bytes)
270+ - The sender's next closee nonce (66 bytes)
271+ - Bundles the nonce because the closee hasn't seen it yet
272+ - TLV types 5, 6, 7 (distinct from non-taproot types 1, 2, 3)
273+
274+ ** ClosingSig (from Closee)** :
275+ - Uses ` PartialSig ` (32 bytes) + separate ` NextCloseeNonce ` :
276+ - The partial signature in TLV types 5, 6, 7
277+ - The next closee nonce in TLV type 22 (66 bytes)
278+ - Separates the nonce because the closer already knows the current nonce from
279+ shutdown or previous ` PartialSigWithNonce `
280+
281+ This asymmetric pattern minimizes redundancy while ensuring both parties always
282+ have the nonces they need for signing.
283+
284+ #### Nonce State Management
285+
286+ The state machine maintains a simplified ` NonceState ` structure with only 2 fields:
287+ - ` LocalCloseeNonce ` : Our closee nonce sent in our shutdown message
288+ - ` RemoteCloseeNonce ` : The peer's closee nonce from their shutdown message
289+
290+ The JIT pattern eliminates complex nonce rotation:
291+ - New nonces arrive with signatures, not pre-generated
292+ - Remote nonces are updated automatically from ` PartialSigWithNonce ` in
293+ ` closing_complete `
294+ - Local nonces are generated on-demand when creating signatures
295+
296+ ### Wire Message Extensions
297+
298+ The following messages have been extended with optional TLV fields for taproot:
299+
300+ ** shutdown** :
301+ - Type 8: ` shutdown_nonce ` - Sender's closee nonce for cooperative close signing
302+
303+ ** closing_complete** :
304+ - Types 5, 6, 7: ` PartialSigWithNonce ` - Partial signature with embedded next closee nonce
305+ - Type 5: ` closer_no_closee ` (closer has output, closee is dust)
306+ - Type 6: ` no_closer_closee ` (closer is dust, closee has output)
307+ - Type 7: ` closer_and_closee ` (both have outputs)
308+
309+ ** closing_sig** :
310+ - Types 5, 6, 7: ` PartialSig ` - Just the partial signature (32 bytes)
311+ - Same TLV type meanings as above
312+ - Type 22: ` NextCloseeNonce ` - Next closee nonce for RBF iterations (66 bytes)
313+
314+ ### Validation Requirements
315+
316+ For taproot channels:
317+ - Shutdown messages MUST include the sender's closee nonce
318+ - ClosingComplete messages MUST use PartialSigWithNonce (includes next nonce
319+ bundled with signature)
320+ - ClosingSig messages MUST use PartialSig with separate NextCloseeNonce field
321+ - Terminal offers (final RBF attempts) MAY omit next nonces to signal finality
322+
323+ ### Implementation Notes for Nonce Handling
324+
325+ The MuSig2 session's ` InitRemoteNonce ` method is called at two specific times:
326+ 1 . When processing the remote's ` shutdown ` message (to initialize with their
327+ closee nonce)
328+
329+ 2 . After receiving a ` closing_sig ` message that contains a ` NextCloseeNonce `
330+ (for RBF iterations)
331+
332+ The nonce from ` PartialSigWithNonce ` in ` closing_complete ` is stored but not
333+ immediately used with ` InitRemoteNonce ` - it's used when we need to sign as the
334+ closee in the next round.
335+
214336## Implementation Notes
215337
216338- This state machine is implemented in the ` peer.go ` and ` channel.go ` files
217339within the lnd codebase
218340- State transitions are logged at the debug level
219341- The ` ChanCloser ` interface manages the state machine execution
342+ - Taproot support requires the ` MusigSession ` interface for nonce coordination
0 commit comments