From 77ae7afe7811e71ba86bcfe7357b938015e2209e Mon Sep 17 00:00:00 2001 From: Jonathan Harvey-Buschel Date: Thu, 17 Oct 2024 13:38:34 +0200 Subject: [PATCH] multi: link quit can interrupt commitment signing In this commit, we make sig job handling when singing a next commitment non-blocking by allowing the shutdown of a channel link to prevent further waiting on sig jobs by the channel state machine. This addresses possible cases where the aux signer may be shut down via a separate quit signal, so the state machine could block indefinitely on receiving an update on a sig job. --- contractcourt/chain_watcher_test.go | 13 +- htlcswitch/link.go | 51 +++--- htlcswitch/link_isolated_test.go | 5 +- htlcswitch/link_test.go | 54 ++++-- htlcswitch/test_utils.go | 14 +- lnwallet/channel.go | 31 +++- lnwallet/channel_test.go | 252 +++++++++++++++------------- lnwallet/test_utils.go | 9 +- lnwallet/transactions_test.go | 4 +- 9 files changed, 256 insertions(+), 177 deletions(-) diff --git a/contractcourt/chain_watcher_test.go b/contractcourt/chain_watcher_test.go index 489a60518..2781170f0 100644 --- a/contractcourt/chain_watcher_test.go +++ b/contractcourt/chain_watcher_test.go @@ -2,6 +2,7 @@ package contractcourt import ( "bytes" + "context" "crypto/sha256" "fmt" "testing" @@ -145,17 +146,15 @@ func TestChainWatcherRemoteUnilateralClosePendingCommit(t *testing.T) { // With the HTLC added, we'll now manually initiate a state transition // from Alice to Bob. - _, err = aliceChannel.SignNextCommitment() - if err != nil { - t.Fatal(err) - } + testQuit, testQuitFunc := context.WithCancel(context.Background()) + t.Cleanup(testQuitFunc) + _, err = aliceChannel.SignNextCommitment(testQuit) + require.NoError(t, err) // At this point, we'll now Bob broadcasting this new pending unrevoked // commitment. bobPendingCommit, err := aliceChannel.State().RemoteCommitChainTip() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // We'll craft a fake spend notification with Bob's actual commitment. // The chain watcher should be able to detect that this is a pending diff --git a/htlcswitch/link.go b/htlcswitch/link.go index d395a94b4..7ce618574 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -387,8 +387,10 @@ type channelLink struct { // our next CommitSig. incomingCommitHooks hookMap - wg sync.WaitGroup - quit chan struct{} + // ContextGuard is a helper that encapsulates a wait group and quit + // channel and allows contexts that either block or cancel on those + // depending on the use case. + *fn.ContextGuard } // hookMap is a data structure that is used to track the hooks that need to be @@ -469,7 +471,7 @@ func NewChannelLink(cfg ChannelLinkConfig, flushHooks: newHookMap(), outgoingCommitHooks: newHookMap(), incomingCommitHooks: newHookMap(), - quit: make(chan struct{}), + ContextGuard: fn.NewContextGuard(), } } @@ -548,7 +550,7 @@ func (l *channelLink) Start() error { l.updateFeeTimer = time.NewTimer(l.randomFeeUpdateTimeout()) - l.wg.Add(1) + l.Wg.Add(1) go l.htlcManager() return nil @@ -588,8 +590,8 @@ func (l *channelLink) Stop() { l.hodlQueue.Stop() } - close(l.quit) - l.wg.Wait() + close(l.Quit) + l.Wg.Wait() // Now that the htlcManager has completely exited, reset the packet // courier. This allows the mailbox to revaluate any lingering Adds that @@ -614,7 +616,7 @@ func (l *channelLink) Stop() { // WaitForShutdown blocks until the link finishes shutting down, which includes // termination of all dependent goroutines. func (l *channelLink) WaitForShutdown() { - l.wg.Wait() + l.Wg.Wait() } // EligibleToForward returns a bool indicating if the channel is able to @@ -675,7 +677,7 @@ func (l *channelLink) IsFlushing(linkDirection LinkDirection) bool { func (l *channelLink) OnFlushedOnce(hook func()) { select { case l.flushHooks.newTransients <- hook: - case <-l.quit: + case <-l.Quit: } } @@ -694,7 +696,7 @@ func (l *channelLink) OnCommitOnce(direction LinkDirection, hook func()) { select { case queue <- hook: - case <-l.quit: + case <-l.Quit: } } @@ -903,8 +905,10 @@ func (l *channelLink) syncChanStates() error { // We've just received a ChanSync message from the remote // party, so we'll process the message in order to determine // if we need to re-transmit any messages to the remote party. + ctx, cancel := l.WithCtxQuitNoTimeout() + defer cancel() msgsToReSend, openedCircuits, closedCircuits, err = - l.channel.ProcessChanSyncMsg(remoteChanSyncMsg) + l.channel.ProcessChanSyncMsg(ctx, remoteChanSyncMsg) if err != nil { return err } @@ -933,7 +937,7 @@ func (l *channelLink) syncChanStates() error { l.cfg.Peer.SendMessage(false, msg) } - case <-l.quit: + case <-l.Quit: return ErrLinkShuttingDown } @@ -1023,7 +1027,7 @@ func (l *channelLink) resolveFwdPkg(fwdPkg *channeldb.FwdPkg) error { // // NOTE: This MUST be run as a goroutine. func (l *channelLink) fwdPkgGarbager() { - defer l.wg.Done() + defer l.Wg.Done() l.cfg.FwdPkgGCTicker.Resume() defer l.cfg.FwdPkgGCTicker.Stop() @@ -1040,7 +1044,7 @@ func (l *channelLink) fwdPkgGarbager() { err) continue } - case <-l.quit: + case <-l.Quit: return } } @@ -1163,7 +1167,7 @@ func (l *channelLink) handleChanSyncErr(err error) { func (l *channelLink) htlcManager() { defer func() { l.cfg.BatchTicker.Stop() - l.wg.Done() + l.Wg.Done() l.log.Infof("exited") }() @@ -1257,7 +1261,7 @@ func (l *channelLink) htlcManager() { // With our link's in-memory state fully reconstructed, spawn a // goroutine to manage the reclamation of disk space occupied by // completed forwarding packages. - l.wg.Add(1) + l.Wg.Add(1) go l.fwdPkgGarbager() } @@ -1441,7 +1445,7 @@ func (l *channelLink) htlcManager() { ) } - case <-l.quit: + case <-l.Quit: return } } @@ -2299,7 +2303,7 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) { } select { - case <-l.quit: + case <-l.Quit: return default: } @@ -2360,7 +2364,7 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) { } select { - case <-l.quit: + case <-l.Quit: return default: } @@ -2590,7 +2594,10 @@ func (l *channelLink) updateCommitTx() error { return nil } - newCommit, err := l.channel.SignNextCommitment() + ctx, done := l.WithCtxQuitNoTimeout() + defer done() + + newCommit, err := l.channel.SignNextCommitment(ctx) if err == lnwallet.ErrNoWindow { l.cfg.PendingCommitTicker.Resume() l.log.Trace("PendingCommitTicker resumed") @@ -2627,7 +2634,7 @@ func (l *channelLink) updateCommitTx() error { } select { - case <-l.quit: + case <-l.Quit: return ErrLinkShuttingDown default: } @@ -3233,7 +3240,7 @@ func (l *channelLink) handleSwitchPacket(pkt *htlcPacket) error { // NOTE: Part of the ChannelLink interface. func (l *channelLink) HandleChannelUpdate(message lnwire.Message) { select { - case <-l.quit: + case <-l.Quit: // Return early if the link is already in the process of // quitting. It doesn't make sense to hand the message to the // mailbox here. @@ -3932,7 +3939,7 @@ func (l *channelLink) forwardBatch(replay bool, packets ...*htlcPacket) { filteredPkts = append(filteredPkts, pkt) } - err := l.cfg.ForwardPackets(l.quit, replay, filteredPkts...) + err := l.cfg.ForwardPackets(l.Quit, replay, filteredPkts...) if err != nil { log.Errorf("Unhandled error while reforwarding htlc "+ "settle/fail over htlcswitch: %v", err) diff --git a/htlcswitch/link_isolated_test.go b/htlcswitch/link_isolated_test.go index 5d769d920..5281cbed7 100644 --- a/htlcswitch/link_isolated_test.go +++ b/htlcswitch/link_isolated_test.go @@ -1,6 +1,7 @@ package htlcswitch import ( + "context" "crypto/sha256" "testing" "time" @@ -94,7 +95,9 @@ func (l *linkTestContext) receiveHtlcAliceToBob() { func (l *linkTestContext) sendCommitSigBobToAlice(expHtlcs int) { l.t.Helper() - sigs, err := l.bobChannel.SignNextCommitment() + testQuit, testQuitFunc := context.WithCancel(context.Background()) + defer testQuitFunc() + sigs, err := l.bobChannel.SignNextCommitment(testQuit) if err != nil { l.t.Fatalf("error signing commitment: %v", err) } diff --git a/htlcswitch/link_test.go b/htlcswitch/link_test.go index e473f9111..5bfb79ee0 100644 --- a/htlcswitch/link_test.go +++ b/htlcswitch/link_test.go @@ -2252,12 +2252,14 @@ func newSingleLinkTestHarness(t *testing.T, chanAmt, return aliceSwitch.AddLink(aliceLink) } go func() { - for { - select { - case <-notifyUpdateChan: - case <-aliceLink.(*channelLink).quit: - close(doneChan) - return + if chanLink, ok := aliceLink.(*channelLink); ok { + for { + select { + case <-notifyUpdateChan: + case <-chanLink.Quit: + close(doneChan) + return + } } } }() @@ -2324,7 +2326,10 @@ func handleStateUpdate(link *channelLink, } link.HandleChannelUpdate(remoteRev) - remoteSigs, err := remoteChannel.SignNextCommitment() + ctx, done := link.WithCtxQuitNoTimeout() + defer done() + + remoteSigs, err := remoteChannel.SignNextCommitment(ctx) if err != nil { return err } @@ -2367,7 +2372,7 @@ func updateState(batchTick chan time.Time, link *channelLink, // Trigger update by ticking the batchTicker. select { case batchTick <- time.Now(): - case <-link.quit: + case <-link.Quit: return fmt.Errorf("link shutting down") } return handleStateUpdate(link, remoteChannel) @@ -2375,7 +2380,10 @@ func updateState(batchTick chan time.Time, link *channelLink, // The remote is triggering the state update, emulate this by // signing and sending CommitSig to the link. - remoteSigs, err := remoteChannel.SignNextCommitment() + ctx, done := link.WithCtxQuitNoTimeout() + defer done() + + remoteSigs, err := remoteChannel.SignNextCommitment(ctx) if err != nil { return err } @@ -4931,12 +4939,14 @@ func (h *persistentLinkHarness) restartLink( return nil, nil, err } go func() { - for { - select { - case <-notifyUpdateChan: - case <-aliceLink.(*channelLink).quit: - close(doneChan) - return + if chanLink, ok := aliceLink.(*channelLink); ok { + for { + select { + case <-notifyUpdateChan: + case <-chanLink.Quit: + close(doneChan) + return + } } } }() @@ -5919,7 +5929,12 @@ func TestChannelLinkFail(t *testing.T) { // Sign a commitment that will include // signature for the HTLC just sent. - sigs, err := remoteChannel.SignNextCommitment() + quitCtx, done := c.WithCtxQuitNoTimeout() + defer done() + + sigs, err := remoteChannel.SignNextCommitment( + quitCtx, + ) if err != nil { t.Fatalf("error signing commitment: %v", err) @@ -5961,7 +5976,12 @@ func TestChannelLinkFail(t *testing.T) { // Sign a commitment that will include // signature for the HTLC just sent. - sigs, err := remoteChannel.SignNextCommitment() + quitCtx, done := c.WithCtxQuitNoTimeout() + defer done() + + sigs, err := remoteChannel.SignNextCommitment( + quitCtx, + ) if err != nil { t.Fatalf("error signing commitment: %v", err) diff --git a/htlcswitch/test_utils.go b/htlcswitch/test_utils.go index 5ef83c8f1..427dc8cb5 100644 --- a/htlcswitch/test_utils.go +++ b/htlcswitch/test_utils.go @@ -1197,12 +1197,14 @@ func (h *hopNetwork) createChannelLink(server, peer *mockServer, } go func() { - for { - select { - case <-notifyUpdateChan: - case <-link.(*channelLink).quit: - close(doneChan) - return + if chanLink, ok := link.(*channelLink); ok { + for { + select { + case <-notifyUpdateChan: + case <-chanLink.Quit: + close(doneChan) + return + } } } }() diff --git a/lnwallet/channel.go b/lnwallet/channel.go index fedc7e4d2..3a980df1a 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -3,6 +3,7 @@ package lnwallet import ( "bytes" "cmp" + "context" "crypto/sha256" "errors" "fmt" @@ -138,6 +139,10 @@ var ( // errNoPartialSig is returned when a partial signature is required, // but none is found. errNoPartialSig = errors.New("no partial signature found") + + // errQuit is returned when a quit signal was received, interrupting the + // current operation. + errQuit = errors.New("received quit signal") ) // ErrCommitSyncLocalDataLoss is returned in the case that we receive a valid @@ -3893,7 +3898,9 @@ type NewCommitState struct { // for the remote party's commitment are also returned. // //nolint:funlen -func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) { +func (lc *LightningChannel) SignNextCommitment( + ctx context.Context) (*NewCommitState, error) { + lc.Lock() defer lc.Unlock() @@ -4059,7 +4066,13 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) { auxSigs := make([]fn.Option[tlv.Blob], 0, len(auxSigBatch)) for i := range sigBatch { htlcSigJob := sigBatch[i] - jobResp := <-htlcSigJob.Resp + var jobResp SignJobResp + + select { + case jobResp = <-htlcSigJob.Resp: + case <-ctx.Done(): + return nil, errQuit + } // If an error occurred, then we'll cancel any other active // jobs. @@ -4075,7 +4088,13 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) { } auxHtlcSigJob := auxSigBatch[i] - auxJobResp := <-auxHtlcSigJob.Resp + var auxJobResp AuxSigJobResp + + select { + case auxJobResp = <-auxHtlcSigJob.Resp: + case <-ctx.Done(): + return nil, errQuit + } // If an error occurred, then we'll cancel any other active // jobs. @@ -4169,7 +4188,9 @@ func (lc *LightningChannel) resignMusigCommit( // previous commitment txn. This allows the link to clear its mailbox of those // circuits in case they are still in memory, and ensure the switch's circuit // map has been updated by deleting the closed circuits. -func (lc *LightningChannel) ProcessChanSyncMsg( +// +//nolint:funlen +func (lc *LightningChannel) ProcessChanSyncMsg(ctx context.Context, msg *lnwire.ChannelReestablish) ([]lnwire.Message, []models.CircuitKey, []models.CircuitKey, error) { @@ -4333,7 +4354,7 @@ func (lc *LightningChannel) ProcessChanSyncMsg( // revocation, but also initiate a state transition to re-sync // them. if lc.OweCommitment() { - newCommit, err := lc.SignNextCommitment() + newCommit, err := lc.SignNextCommitment(ctx) switch { // If we signed this state, then we'll accumulate diff --git a/lnwallet/channel_test.go b/lnwallet/channel_test.go index f3fa052fe..ae2f474f2 100644 --- a/lnwallet/channel_test.go +++ b/lnwallet/channel_test.go @@ -124,7 +124,7 @@ func testAddSettleWorkflow(t *testing.T, tweakless bool, // we expect the messages to be ordered, Bob will receive the HTLC we // just sent before he receives this signature, so the signature will // cover the HTLC. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "alice unable to sign commitment") // Bob receives this signature message, and checks that this covers the @@ -142,7 +142,7 @@ func testAddSettleWorkflow(t *testing.T, tweakless bool, // This signature will cover the HTLC, since Bob will first send the // revocation just created. The revocation also acks every received // HTLC up to the point where Alice sent here signature. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign alice's commitment") // Alice then processes this revocation, sending her own revocation for @@ -255,14 +255,14 @@ func testAddSettleWorkflow(t *testing.T, tweakless bool, t.Fatalf("alice unable to accept settle of outbound htlc: %v", err) } - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign settle commitment") err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err, "alice unable to process bob's new commitment") aliceRevocation2, _, _, err := aliceChannel.RevokeCurrentCommitment() require.NoError(t, err, "alice unable to generate revocation") - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "alice unable to sign new commitment") fwdPkg, _, err = bobChannel.ReceiveRevocation(aliceRevocation2) @@ -470,7 +470,7 @@ func TestChannelZeroAddLocalHeight(t *testing.T) { // Bob should send a commitment signature to Alice. // <----sig------ - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) @@ -501,7 +501,7 @@ func TestChannelZeroAddLocalHeight(t *testing.T) { // Bob should now send a commitment signature to Alice. // <----sig----- - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) // Alice should accept the commitment. Previously she would @@ -636,7 +636,7 @@ func testCommitHTLCSigTieBreak(t *testing.T, restart bool) { // tie-breaking for commitment sorting won't affect the commitment // signed by Alice because received HTLC scripts commit to the CLTV // directly, so the outputs will have different scriptPubkeys. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign alice's commitment") err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) @@ -651,7 +651,7 @@ func testCommitHTLCSigTieBreak(t *testing.T, restart bool) { // the offered HTLC scripts he adds for Alice will need to have the // tie-breaking applied because the CLTV is not committed, but instead // implicit via the construction of the second-level transactions. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign bob's commitment") if len(bobNewCommit.PendingHTLCs) != numHtlcs { @@ -760,7 +760,7 @@ func TestCommitHTLCSigCustomRecordSize(t *testing.T) { } // We expect an error because of the large custom records blob. - _, err = aliceChannel.SignNextCommitment() + _, err = aliceChannel.SignNextCommitment(ctxb) require.ErrorContains(t, err, "exceeds max allowed size") } @@ -1574,7 +1574,7 @@ func TestHTLCSigNumber(t *testing.T) { // =================================================================== aliceChannel, bobChannel := createChanWithHTLC(aboveDust, aboveDust) - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "Error signing next commitment") if len(aliceNewCommit.HtlcSigs) != 2 { @@ -1597,7 +1597,7 @@ func TestHTLCSigNumber(t *testing.T) { // =================================================================== aliceChannel, bobChannel = createChanWithHTLC(aboveDust) - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "Error signing next commitment") if len(aliceNewCommit.HtlcSigs) != 1 { @@ -1619,7 +1619,7 @@ func TestHTLCSigNumber(t *testing.T) { // ============================================================== aliceChannel, bobChannel = createChanWithHTLC(belowDust) - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "Error signing next commitment") // Since the HTLC is below Bob's dust limit, Alice won't need to send @@ -1637,7 +1637,7 @@ func TestHTLCSigNumber(t *testing.T) { // ================================================================ aliceChannel, bobChannel = createChanWithHTLC(aboveDust) - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "Error signing next commitment") // Since the HTLC is above Bob's dust limit, Alice should send a @@ -1658,7 +1658,7 @@ func TestHTLCSigNumber(t *testing.T) { // Alice should produce only one signature, since one HTLC is below // dust. - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "Error signing next commitment") if len(aliceNewCommit.HtlcSigs) != 1 { @@ -2428,7 +2428,7 @@ func TestUpdateFeeFail(t *testing.T) { // Alice sends signature for commitment that does not cover any fee // update. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "alice unable to sign commitment") // Bob verifies this commit, meaning that he checks that it is @@ -2471,11 +2471,11 @@ func TestUpdateFeeConcurrentSig(t *testing.T) { } // Alice signs a commitment, and sends this to bob. - aliceNewCommits, err := aliceChannel.SignNextCommitment() + aliceNewCommits, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "alice unable to sign commitment") // At the same time, Bob signs a commitment. - bobNewCommits, err := bobChannel.SignNextCommitment() + bobNewCommits, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign alice's commitment") // ...that Alice receives. @@ -2542,7 +2542,7 @@ func TestUpdateFeeSenderCommits(t *testing.T) { // Alice signs a commitment, which will cover everything sent to Bob // (the HTLC and the fee update), and everything acked by Bob (nothing // so far). - aliceNewCommits, err := aliceChannel.SignNextCommitment() + aliceNewCommits, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "alice unable to sign commitment") // Bob receives this signature message, and verifies that it is @@ -2572,7 +2572,7 @@ func TestUpdateFeeSenderCommits(t *testing.T) { // Bob commits to all updates he has received from Alice. This includes // the HTLC he received, and the fee update. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign alice's commitment") // Alice receives the revocation of the old one, and can now assume @@ -2646,7 +2646,7 @@ func TestUpdateFeeReceiverCommits(t *testing.T) { // Bob commits to every change he has sent since last time (none). He // does not commit to the received HTLC and fee update, since Alice // cannot know if he has received them. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "alice unable to sign commitment") // Alice receives this signature message, and verifies that it is @@ -2667,7 +2667,7 @@ func TestUpdateFeeReceiverCommits(t *testing.T) { // Alice will sign next commitment. Since she sent the revocation, she // also ack'ed everything received, but in this case this is nothing. // Since she sent the two updates, this signature will cover those two. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign alice's commitment") // Bob gets the signature for the new commitment from Alice. He assumes @@ -2697,7 +2697,7 @@ func TestUpdateFeeReceiverCommits(t *testing.T) { // Bob will send a new signature, which will cover what he just acked: // the HTLC and fee update. - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "alice unable to sign commitment") // Alice receives revocation from Bob, and can now be sure that Bob @@ -2787,7 +2787,7 @@ func TestUpdateFeeMultipleUpdates(t *testing.T) { // Alice signs a commitment, which will cover everything sent to Bob // (the HTLC and the fee update), and everything acked by Bob (nothing // so far). - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "alice unable to sign commitment") bobChannel.ReceiveUpdateFee(fee1) @@ -2833,7 +2833,7 @@ func TestUpdateFeeMultipleUpdates(t *testing.T) { // Bob commits to all updates he has received from Alice. This includes // the HTLC he received, and the fee update. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign alice's commitment") // Alice receives the revocation of the old one, and can now assume that @@ -2939,7 +2939,9 @@ func assertNoChanSyncNeeded(t *testing.T, aliceChannel *LightningChannel, } } - bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg(aliceChanSyncMsg) + bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg( + ctxb, aliceChanSyncMsg, + ) if err != nil { t.Fatalf("line #%v: unable to process ChannelReestablish "+ "msg: %v", line, err) @@ -2949,7 +2951,9 @@ func assertNoChanSyncNeeded(t *testing.T, aliceChannel *LightningChannel, "instead wants to send: %v", line, spew.Sdump(bobMsgsToSend)) } - aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg(bobChanSyncMsg) + aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg( + ctxb, bobChanSyncMsg, + ) if err != nil { t.Fatalf("line #%v: unable to process ChannelReestablish "+ "msg: %v", line, err) @@ -3143,7 +3147,7 @@ func testChanSyncOweCommitment(t *testing.T, chanType channeldb.ChannelType) { // Now we'll begin the core of the test itself. Alice will extend a new // commitment to Bob, but the connection drops before Bob can process // it. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // If this is a taproot channel, then we'll generate fresh verification @@ -3168,7 +3172,7 @@ func testChanSyncOweCommitment(t *testing.T, chanType channeldb.ChannelType) { // above. assertAliceCommitRetransmit := func() *lnwire.CommitSig { aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg( - bobSyncMsg, + ctxb, bobSyncMsg, ) if err != nil { t.Fatalf("unable to process chan sync msg: %v", err) @@ -3260,7 +3264,9 @@ func testChanSyncOweCommitment(t *testing.T, chanType channeldb.ChannelType) { // From Bob's Pov he has nothing else to send, so he should conclude he // has no further action remaining. - bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg(aliceSyncMsg) + bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg( + ctxb, aliceSyncMsg, + ) require.NoError(t, err, "unable to process chan sync msg") if len(bobMsgsToSend) != 0 { t.Fatalf("expected bob to send %v messages instead will "+ @@ -3288,7 +3294,7 @@ func testChanSyncOweCommitment(t *testing.T, chanType channeldb.ChannelType) { require.NoError(t, err, "bob unable to process alice's commitment") bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment() require.NoError(t, err, "unable to revoke bob commitment") - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign commitment") _, _, err = aliceChannel.ReceiveRevocation(bobRevocation) require.NoError(t, err, "alice unable to recv revocation") @@ -3478,7 +3484,7 @@ func TestChanSyncOweCommitmentAuxSigner(t *testing.T) { fn.Ok(fn.Some(sigBlobBuf.Bytes())), nil, ) - _, err = aliceChannel.SignNextCommitment() + _, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") _, err = aliceChannel.GenMusigNonces() @@ -3490,7 +3496,7 @@ func TestChanSyncOweCommitmentAuxSigner(t *testing.T) { require.NoError(t, err, "unable to produce chan sync msg") aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg( - bobSyncMsg, + ctxb, bobSyncMsg, ) require.NoError(t, err) require.Len(t, aliceMsgsToSend, 2) @@ -3582,7 +3588,7 @@ func TestAuxSignerShutdown(t *testing.T) { fn.Some(sigBlobBuf.Bytes()), nil, ) - _, err = aliceChannel.SignNextCommitment() + _, err = aliceChannel.SignNextCommitment(ctxb) require.ErrorIs(t, err, auxSignerShutdownErr) } @@ -3648,7 +3654,9 @@ func testChanSyncOweCommitmentPendingRemote(t *testing.T, t.Fatalf("unable to settle htlc: %v", err) } - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment( + ctxb, + ) if err != nil { t.Fatalf("unable to sign commitment: %v", err) } @@ -3686,7 +3694,7 @@ func testChanSyncOweCommitmentPendingRemote(t *testing.T, } // Bob signs the commitment he owes. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // This commitment is expected to contain no htlcs anymore. @@ -3795,14 +3803,14 @@ func testChanSyncOweRevocation(t *testing.T, chanType channeldb.ChannelType) { // // Alice signs the next state, then Bob receives and sends his // revocation message. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err, "bob unable to process alice's commitment") bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment() require.NoError(t, err, "unable to revoke bob commitment") - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign commitment") _, _, err = aliceChannel.ReceiveRevocation(bobRevocation) @@ -3838,7 +3846,7 @@ func testChanSyncOweRevocation(t *testing.T, chanType channeldb.ChannelType) { t.Helper() aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg( - bobSyncMsg, + ctxb, bobSyncMsg, ) if err != nil { t.Fatalf("unable to process chan sync msg: %v", err) @@ -3869,7 +3877,9 @@ func testChanSyncOweRevocation(t *testing.T, chanType channeldb.ChannelType) { } // From Bob's PoV he shouldn't think that he owes Alice any messages. - bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg(aliceSyncMsg) + bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg( + ctxb, aliceSyncMsg, + ) require.NoError(t, err, "unable to process chan sync msg") if len(bobMsgsToSend) != 0 { t.Fatalf("expected bob to not retransmit, instead has: %v", @@ -3990,7 +4000,7 @@ func testChanSyncOweRevocationAndCommit(t *testing.T, // Progressing the exchange: Alice will send her signature, Bob will // receive, send a revocation and also a signature for Alice's state. - aliceNewCommits, err := aliceChannel.SignNextCommitment() + aliceNewCommits, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") err = bobChannel.ReceiveNewCommitment(aliceNewCommits.CommitSigs) require.NoError(t, err, "bob unable to process alice's commitment") @@ -3999,7 +4009,7 @@ func testChanSyncOweRevocationAndCommit(t *testing.T, // reach Alice before the connection dies. bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment() require.NoError(t, err, "unable to revoke bob commitment") - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign commitment") // If we now attempt to resync, then Alice should conclude that she @@ -4021,7 +4031,9 @@ func testChanSyncOweRevocationAndCommit(t *testing.T, } } - aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg(bobSyncMsg) + aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg( + ctxb, bobSyncMsg, + ) require.NoError(t, err, "unable to process chan sync msg") if len(aliceMsgsToSend) != 0 { t.Fatalf("expected alice to not retransmit, instead she's "+ @@ -4032,7 +4044,7 @@ func testChanSyncOweRevocationAndCommit(t *testing.T, t.Helper() bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg( - aliceSyncMsg, + ctxb, aliceSyncMsg, ) if err != nil { t.Fatalf("unable to process chan sync msg: %v", err) @@ -4198,7 +4210,7 @@ func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T, addAndReceiveHTLC(t, bobChannel, aliceChannel, bobHtlc[1], nil) // Bob signs the new state update, and sends the signature to Alice. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign commitment") err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) @@ -4222,7 +4234,7 @@ func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T, // Progressing the exchange: Alice will send her signature, with Bob // processing the new state locally. - aliceNewCommits, err := aliceChannel.SignNextCommitment() + aliceNewCommits, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") err = bobChannel.ReceiveNewCommitment(aliceNewCommits.CommitSigs) require.NoError(t, err, "bob unable to process alice's commitment") @@ -4252,7 +4264,9 @@ func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T, } } - aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg(bobSyncMsg) + aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg( + ctxb, bobSyncMsg, + ) require.NoError(t, err, "unable to process chan sync msg") if len(aliceMsgsToSend) != 0 { t.Fatalf("expected alice to not retransmit, instead she's "+ @@ -4263,7 +4277,9 @@ func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T, // send his RevokeAndAck message again. Additionally, the CommitSig // message that he sends should be sufficient to finalize the state // transition. - bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg(aliceSyncMsg) + bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg( + ctxb, aliceSyncMsg, + ) require.NoError(t, err, "unable to process chan sync msg") if len(bobMsgsToSend) != 2 { t.Fatalf("expected bob to send %v messages, instead "+ @@ -4456,7 +4472,9 @@ func TestChanSyncFailure(t *testing.T) { addAndReceiveHTLC(t, bobChannel, aliceChannel, bobHtlc, nil) - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment( + ctxb, + ) if err != nil { t.Fatalf("unable to sign next commit: %v", err) } @@ -4481,7 +4499,7 @@ func TestChanSyncFailure(t *testing.T) { } // Alice should detect from Bob's message that she lost state. - _, _, _, err = aliceOld.ProcessChanSyncMsg(bobSyncMsg) + _, _, _, err = aliceOld.ProcessChanSyncMsg(ctxb, bobSyncMsg) if _, ok := err.(*ErrCommitSyncLocalDataLoss); !ok { t.Fatalf("wrong error, expected "+ "ErrCommitSyncLocalDataLoss instead got: %v", @@ -4489,7 +4507,9 @@ func TestChanSyncFailure(t *testing.T) { } // Bob should detect that Alice probably lost state. - _, _, _, err = bobChannel.ProcessChanSyncMsg(aliceSyncMsg) + _, _, _, err = bobChannel.ProcessChanSyncMsg( + ctxb, aliceSyncMsg, + ) if err != ErrCommitSyncRemoteDataLoss { t.Fatalf("wrong error, expected "+ "ErrCommitSyncRemoteDataLoss instead got: %v", @@ -4550,7 +4570,7 @@ func TestChanSyncFailure(t *testing.T) { bobSyncMsg, err := bobChannel.channelState.ChanSyncMsg() require.NoError(t, err, "unable to produce chan sync msg") bobSyncMsg.LocalUnrevokedCommitPoint = nil - _, _, _, err = aliceOld.ProcessChanSyncMsg(bobSyncMsg) + _, _, _, err = aliceOld.ProcessChanSyncMsg(ctxb, bobSyncMsg) if err != ErrCannotSyncCommitChains { t.Fatalf("wrong error, expected ErrCannotSyncCommitChains "+ "instead got: %v", err) @@ -4562,7 +4582,7 @@ func TestChanSyncFailure(t *testing.T) { bobSyncMsg, err = bobChannel.channelState.ChanSyncMsg() require.NoError(t, err, "unable to produce chan sync msg") bobSyncMsg.NextLocalCommitHeight++ - _, _, _, err = aliceChannel.ProcessChanSyncMsg(bobSyncMsg) + _, _, _, err = aliceChannel.ProcessChanSyncMsg(ctxb, bobSyncMsg) if err != ErrCannotSyncCommitChains { t.Fatalf("wrong error, expected ErrCannotSyncCommitChains "+ "instead got: %v", err) @@ -4573,7 +4593,7 @@ func TestChanSyncFailure(t *testing.T) { bobSyncMsg, err = bobChannel.channelState.ChanSyncMsg() require.NoError(t, err, "unable to produce chan sync msg") bobSyncMsg.NextLocalCommitHeight-- - _, _, _, err = aliceChannel.ProcessChanSyncMsg(bobSyncMsg) + _, _, _, err = aliceChannel.ProcessChanSyncMsg(ctxb, bobSyncMsg) if err != ErrCommitSyncRemoteDataLoss { t.Fatalf("wrong error, expected ErrCommitSyncRemoteDataLoss "+ "instead got: %v", err) @@ -4589,7 +4609,7 @@ func TestChanSyncFailure(t *testing.T) { require.NoError(t, err, "unable to parse pubkey") bobSyncMsg.LocalUnrevokedCommitPoint = modCommitPoint - _, _, _, err = aliceChannel.ProcessChanSyncMsg(bobSyncMsg) + _, _, _, err = aliceChannel.ProcessChanSyncMsg(ctxb, bobSyncMsg) if err != ErrInvalidLocalUnrevokedCommitPoint { t.Fatalf("wrong error, expected "+ "ErrInvalidLocalUnrevokedCommitPoint instead got: %v", @@ -4609,7 +4629,7 @@ func TestChanSyncFailure(t *testing.T) { bobSyncMsg, err = bobChannel.channelState.ChanSyncMsg() require.NoError(t, err, "unable to produce chan sync msg") bobSyncMsg.LocalUnrevokedCommitPoint = modCommitPoint - _, _, _, err = aliceChannel.ProcessChanSyncMsg(bobSyncMsg) + _, _, _, err = aliceChannel.ProcessChanSyncMsg(ctxb, bobSyncMsg) if err != ErrInvalidLocalUnrevokedCommitPoint { t.Fatalf("wrong error, expected "+ "ErrInvalidLocalUnrevokedCommitPoint instead got: %v", @@ -4676,7 +4696,7 @@ func TestChannelRetransmissionFeeUpdate(t *testing.T) { // Now, Alice will send a new commitment to Bob, but we'll simulate a // connection failure, so Bob doesn't get her signature. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // Restart both channels to simulate a connection restart. @@ -4694,7 +4714,9 @@ func TestChannelRetransmissionFeeUpdate(t *testing.T) { require.NoError(t, err, "unable to produce chan sync msg") // Bob should detect that he doesn't need to send anything to Alice. - bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg(aliceSyncMsg) + bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg( + ctxb, aliceSyncMsg, + ) require.NoError(t, err, "unable to process chan sync msg") if len(bobMsgsToSend) != 0 { t.Fatalf("expected bob to send %v messages instead "+ @@ -4706,7 +4728,7 @@ func TestChannelRetransmissionFeeUpdate(t *testing.T) { // that she needs to first send a new UpdateFee message, and also a // CommitSig. aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg( - bobSyncMsg, + ctxb, bobSyncMsg, ) require.NoError(t, err, "unable to process chan sync msg") if len(aliceMsgsToSend) != 2 { @@ -4762,7 +4784,7 @@ func TestChannelRetransmissionFeeUpdate(t *testing.T) { require.NoError(t, err, "bob unable to process alice's commitment") bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment() require.NoError(t, err, "unable to revoke bob commitment") - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign commitment") _, _, err = aliceChannel.ReceiveRevocation(bobRevocation) require.NoError(t, err, "alice unable to recv revocation") @@ -4893,7 +4915,7 @@ func TestFeeUpdateOldDiskFormat(t *testing.T) { // Now, Alice will send a new commitment to Bob, but we'll simulate a // connection failure, so Bob doesn't get the signature. - aliceNewCommitSig, err := aliceChannel.SignNextCommitment() + aliceNewCommitSig, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // Before restarting Alice, to mimic the old format, we fetch the @@ -4950,7 +4972,7 @@ func TestFeeUpdateOldDiskFormat(t *testing.T) { require.NoError(t, err, "bob unable to process alice's commitment") bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment() require.NoError(t, err, "unable to revoke bob commitment") - bobNewCommitSigs, err := bobChannel.SignNextCommitment() + bobNewCommitSigs, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "bob unable to sign commitment") _, _, err = aliceChannel.ReceiveRevocation(bobRevocation) require.NoError(t, err, "alice unable to recv revocation") @@ -5026,11 +5048,11 @@ func TestChanSyncUnableToSync(t *testing.T) { NextLocalCommitHeight: 1000, RemoteCommitTailHeight: 9000, } - _, _, _, err = bobChannel.ProcessChanSyncMsg(badChanSync) + _, _, _, err = bobChannel.ProcessChanSyncMsg(ctxb, badChanSync) if err != ErrCannotSyncCommitChains { t.Fatalf("expected error instead have: %v", err) } - _, _, _, err = aliceChannel.ProcessChanSyncMsg(badChanSync) + _, _, _, err = aliceChannel.ProcessChanSyncMsg(ctxb, badChanSync) if err != ErrCannotSyncCommitChains { t.Fatalf("expected error instead have: %v", err) } @@ -5098,7 +5120,7 @@ func TestChanSyncInvalidLastSecret(t *testing.T) { // Alice's former self should conclude that she possibly lost data as // Bob is sending a valid commit secret for the latest state. - _, _, _, err = aliceOld.ProcessChanSyncMsg(bobChanSync) + _, _, _, err = aliceOld.ProcessChanSyncMsg(ctxb, bobChanSync) if _, ok := err.(*ErrCommitSyncLocalDataLoss); !ok { t.Fatalf("wrong error, expected ErrCommitSyncLocalDataLoss "+ "instead got: %v", err) @@ -5106,7 +5128,7 @@ func TestChanSyncInvalidLastSecret(t *testing.T) { // Bob should conclude that he should force close the channel, as Alice // cannot continue operation. - _, _, _, err = bobChannel.ProcessChanSyncMsg(aliceChanSync) + _, _, _, err = bobChannel.ProcessChanSyncMsg(ctxb, aliceChanSync) if err != ErrInvalidLastCommitSecret { t.Fatalf("wrong error, expected ErrInvalidLastCommitSecret, "+ "instead got: %v", err) @@ -5589,7 +5611,7 @@ func TestSignCommitmentFailNotLockedIn(t *testing.T) { // If we now try to initiate a state update, then it should fail as // Alice is unable to actually create a new state. - _, err = aliceChannel.SignNextCommitment() + _, err = aliceChannel.SignNextCommitment(ctxb) if err != ErrNoWindow { t.Fatalf("expected ErrNoWindow, instead have: %v", err) } @@ -5618,7 +5640,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) { // We'll now manually initiate a state transition between Alice and // bob. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) if err != nil { t.Fatal(err) } @@ -5647,7 +5669,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) { // Now, have Bob initiate a transition to lock in the Adds sent by // Alice. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) if err != nil { t.Fatal(err) } @@ -5692,7 +5714,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) { // We'll now initiate another state transition, but this time Bob will // lead. - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) if err != nil { t.Fatal(err) } @@ -5727,7 +5749,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) { // Now, begin another state transition led by Alice, and fail the second // HTLC part-way through the dance. - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) if err != nil { t.Fatal(err) } @@ -5800,7 +5822,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) { // Have Alice initiate a state transition, which does not include the // HTLCs just re-added to the channel state. - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) if err != nil { t.Fatal(err) } @@ -5829,7 +5851,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) { } // Now initiate a final update from Bob to lock in the final Fail. - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) if err != nil { t.Fatal(err) } @@ -5861,7 +5883,7 @@ func TestLockedInHtlcForwardingSkipAfterRestart(t *testing.T) { // Finally, have Bob initiate a state transition that locks in the Fail // added after the restart. - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) if err != nil { t.Fatal(err) } @@ -5923,7 +5945,7 @@ func TestInvalidCommitSigError(t *testing.T) { addAndReceiveHTLC(t, aliceChannel, bobChannel, htlc, nil) // Alice will now attempt to initiate a state transition. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign new commit") // Before the signature gets to Bob, we'll mutate it, such that the @@ -6116,7 +6138,7 @@ func TestChannelUnilateralClosePendingCommit(t *testing.T) { // With the HTLC added, we'll now manually initiate a state transition // from Alice to Bob. - _, err = aliceChannel.SignNextCommitment() + _, err = aliceChannel.SignNextCommitment(ctxb) if err != nil { t.Fatal(err) } @@ -6350,7 +6372,7 @@ func TestMaxAcceptedHTLCs(t *testing.T) { addAndReceiveHTLC(t, aliceChannel, bobChannel, htlc, nil) // Add a commitment to Bob's commitment chain. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign next commitment") err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err, "unable to recv new commitment") @@ -6445,7 +6467,7 @@ func TestMaxAsynchronousHtlcs(t *testing.T) { t.Fatalf("unable to receive fail htlc: %v", err) } - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign next commitment") err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) @@ -6453,7 +6475,7 @@ func TestMaxAsynchronousHtlcs(t *testing.T) { // Cover the HTLC referenced with id equal to numHTLCs-1 with a new // signature (step 3). - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign next commitment") err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) @@ -6478,7 +6500,7 @@ func TestMaxAsynchronousHtlcs(t *testing.T) { // Receiving the commitment should succeed as in step 7 since space was // made. - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign next commitment") err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) @@ -7103,7 +7125,7 @@ func TestChannelRestoreUpdateLogs(t *testing.T) { addAndReceiveHTLC(t, aliceChannel, bobChannel, htlcAlice, nil) // Let Alice sign a new state, which will include the HTLC just sent. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // Bob receives this commitment signature, and revokes his old state. @@ -7133,7 +7155,7 @@ func TestChannelRestoreUpdateLogs(t *testing.T) { // and remote commit chains are updated in an async fashion. Since the // remote chain was updated with the latest state (since Bob sent the // revocation earlier) we can keep advancing the remote commit chain. - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // After Alice has signed this commitment, her local commitment will @@ -7280,7 +7302,7 @@ func TestChannelRestoreUpdateLogsFailedHTLC(t *testing.T) { restoreAndAssert(t, aliceChannel, 1, 0, 0, 0) // Bob sends a signature. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err, "unable to receive commitment") @@ -7307,7 +7329,7 @@ func TestChannelRestoreUpdateLogsFailedHTLC(t *testing.T) { // Now send a signature from Alice. This will give Bob a new commitment // where the HTLC is removed. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err, "unable to receive commitment") @@ -7370,7 +7392,7 @@ func TestDuplicateFailRejection(t *testing.T) { // We'll now have Bob sign a new commitment to lock in the HTLC fail // for Alice. - _, err = bobChannel.SignNextCommitment() + _, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commit") // We'll now force a restart for Bob and Alice, so we can test the @@ -7433,7 +7455,7 @@ func TestDuplicateSettleRejection(t *testing.T) { // We'll now have Bob sign a new commitment to lock in the HTLC fail // for Alice. - _, err = bobChannel.SignNextCommitment() + _, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commit") // We'll now force a restart for Bob and Alice, so we can test the @@ -7514,7 +7536,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) { addAndReceiveHTLC(t, aliceChannel, bobChannel, htlcAlice, nil) // Let Alice sign a new state, which will include the HTLC just sent. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // The HTLC should only be on the pending remote commitment, so the @@ -7546,7 +7568,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) { // Now let Bob send the commitment signature making the HTLC lock in on // Alice's commitment. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // At this stage Bob has a pending remote commitment. Make sure @@ -7579,7 +7601,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) { // Send a new signature from Alice to Bob, making Alice have a pending // remote commitment. - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // A restoration should keep the add heights iof the first HTLC, and @@ -7618,7 +7640,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) { // Sign a new state for Alice, making Bob have a pending remote // commitment. - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // The signing of a new commitment for Alice should have given the new @@ -7655,7 +7677,7 @@ func TestChannelRestoreCommitHeight(t *testing.T) { require.NoError(t, err, "unable to recv htlc cancel") // Now Bob signs for the fail update. - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // Bob has a pending commitment for Alice, it shouldn't affect the add @@ -7713,13 +7735,13 @@ func TestForceCloseBorkedState(t *testing.T) { // Do the commitment dance until Bob sends a revocation so Alice is // able to receive the revocation, and then also make a new state // herself. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commit") err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err, "unable to receive commitment") revokeMsg, _, _, err := bobChannel.RevokeCurrentCommitment() require.NoError(t, err, "unable to revoke bob commitment") - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commit") err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err, "unable to receive commitment") @@ -7753,7 +7775,7 @@ func TestForceCloseBorkedState(t *testing.T) { // We manually advance the commitment tail here since the above // ReceiveRevocation call will fail before it's actually advanced. aliceChannel.commitChains.Remote.advanceTail() - _, err = aliceChannel.SignNextCommitment() + _, err = aliceChannel.SignNextCommitment(ctxb) if err != channeldb.ErrChanBorked { t.Fatalf("sign commitment should have failed: %v", err) } @@ -8220,7 +8242,7 @@ func TestChannelFeeRateFloor(t *testing.T) { } // Check that alice can still sign commitments. - aliceNewCommit, err := alice.SignNextCommitment() + aliceNewCommit, err := alice.SignNextCommitment(ctxb) require.NoError(t, err, "alice unable to sign commitment") // Check that bob can still receive commitments. @@ -8979,7 +9001,7 @@ func TestChannelUnsignedAckedFailure(t *testing.T) { // Bob should send a commitment signature to Alice. // <----sig------ - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err) @@ -8994,7 +9016,7 @@ func TestChannelUnsignedAckedFailure(t *testing.T) { // Alice should sign the next commitment and go down before // sending it. // -----sig-----X - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err) newAliceChannel, err := NewLightningChannel( @@ -9025,7 +9047,7 @@ func TestChannelUnsignedAckedFailure(t *testing.T) { // Bob sends the final signature to Alice and Alice should not // reject it, given that we properly restore the unsigned acked // updates and therefore our update log is structured correctly. - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = newAliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err) @@ -9083,7 +9105,7 @@ func TestChannelLocalUnsignedUpdatesFailure(t *testing.T) { // Alice should send a commitment signature to Bob. // -----sig----> - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err) @@ -9107,7 +9129,7 @@ func TestChannelLocalUnsignedUpdatesFailure(t *testing.T) { // Bob sends the final signature and Alice should not reject it. // <----sig----- - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = newAliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err) @@ -9166,7 +9188,7 @@ func TestChannelSignedAckRegression(t *testing.T) { require.NoError(t, err) // -----sig----> - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err) @@ -9178,7 +9200,7 @@ func TestChannelSignedAckRegression(t *testing.T) { require.NoError(t, err) // <----sig----- - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err) @@ -9190,7 +9212,7 @@ func TestChannelSignedAckRegression(t *testing.T) { addAndReceiveHTLC(t, aliceChannel, bobChannel, htlc2, nil) // -----sig----> - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err) @@ -9220,7 +9242,7 @@ func TestChannelSignedAckRegression(t *testing.T) { // Bob should no longer fail to sign this commitment due to faulty // update logs. // <----sig----- - bobNewCommit, err = newBobChannel.SignNextCommitment() + bobNewCommit, err = newBobChannel.SignNextCommitment(ctxb) require.NoError(t, err) // Alice should receive the new commitment without hiccups. @@ -9291,7 +9313,7 @@ func TestIsChannelClean(t *testing.T) { // removed from both commitments. // ---sig---> - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err) @@ -9305,7 +9327,7 @@ func TestIsChannelClean(t *testing.T) { assertCleanOrDirty(false, aliceChannel, bobChannel, t) // <---sig--- - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err) @@ -9326,7 +9348,7 @@ func TestIsChannelClean(t *testing.T) { assertCleanOrDirty(false, aliceChannel, bobChannel, t) // <---sig--- - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err) @@ -9340,7 +9362,7 @@ func TestIsChannelClean(t *testing.T) { assertCleanOrDirty(false, aliceChannel, bobChannel, t) // ---sig---> - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err) @@ -9364,7 +9386,7 @@ func TestIsChannelClean(t *testing.T) { assertCleanOrDirty(false, aliceChannel, bobChannel, t) // ---sig---> - aliceNewCommit, err = aliceChannel.SignNextCommitment() + aliceNewCommit, err = aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err) @@ -9378,7 +9400,7 @@ func TestIsChannelClean(t *testing.T) { assertCleanOrDirty(false, aliceChannel, bobChannel, t) // <---sig--- - bobNewCommit, err = bobChannel.SignNextCommitment() + bobNewCommit, err = bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err) @@ -9513,7 +9535,7 @@ func testGetDustSum(t *testing.T, chantype channeldb.ChannelType) { checkDust(bobChannel, htlc2Amt, htlc2Amt) // Alice signs for this HTLC and neither perspective should change. - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err) @@ -9532,7 +9554,7 @@ func testGetDustSum(t *testing.T, chantype channeldb.ChannelType) { // The rest of the dance is completed and neither perspective should // change. - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) require.NoError(t, err) @@ -10353,7 +10375,7 @@ func TestAsynchronousSendingContraint(t *testing.T) { // Bob signs the new state for alice, which ONLY has his htlc on it // because he only includes acked updates of alice. // <----sig-------|--------------- - bobNewCommit, err := bobChannel.SignNextCommitment() + bobNewCommit, err := bobChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = aliceChannel.ReceiveNewCommitment(bobNewCommit.CommitSigs) @@ -10369,7 +10391,7 @@ func TestAsynchronousSendingContraint(t *testing.T) { // incoming htlc in her commitment sig to bob, but this will dip her // local balance below her reserve because she already used everything // up when adding her htlc. - _, err = aliceChannel.SignNextCommitment() + _, err = aliceChannel.SignNextCommitment(ctxb) require.ErrorIs(t, err, ErrBelowChanReserve) } @@ -10494,7 +10516,7 @@ func TestAsynchronousSendingWithFeeBuffer(t *testing.T) { // Force a state transition, this will lock-in the htlc of bob. // ------sig-----> (includes bob's htlc) // <----rev------ (locks in bob's htlc for alice) - aliceNewCommit, err := aliceChannel.SignNextCommitment() + aliceNewCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err) err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs) require.NoError(t, err) @@ -10736,7 +10758,7 @@ func TestBlindingPointPersistence(t *testing.T) { // Now, Alice will send a new commitment to Bob, which will persist our // pending HTLC to disk. - aliceCommit, err := aliceChannel.SignNextCommitment() + aliceCommit, err := aliceChannel.SignNextCommitment(ctxb) require.NoError(t, err, "unable to sign commitment") // Restart alice to force fetching state from disk. diff --git a/lnwallet/test_utils.go b/lnwallet/test_utils.go index b450b3b30..225323296 100644 --- a/lnwallet/test_utils.go +++ b/lnwallet/test_utils.go @@ -2,6 +2,7 @@ package lnwallet import ( "bytes" + "context" "crypto/rand" "encoding/binary" "encoding/hex" @@ -103,6 +104,10 @@ var ( bobDustLimit = btcutil.Amount(1300) testChannelCapacity float64 = 10 + + // ctxb is a context that will never be cancelled, that is used in + // place of a real quit context. + ctxb = context.Background() ) // CreateTestChannels creates to fully populated channels to be used within @@ -557,7 +562,7 @@ func calcStaticFee(chanType channeldb.ChannelType, numHTLCs int) btcutil.Amount // pending updates. This method is useful when testing interactions between two // live state machines. func ForceStateTransition(chanA, chanB *LightningChannel) error { - aliceNewCommit, err := chanA.SignNextCommitment() + aliceNewCommit, err := chanA.SignNextCommitment(ctxb) if err != nil { return err } @@ -570,7 +575,7 @@ func ForceStateTransition(chanA, chanB *LightningChannel) error { if err != nil { return err } - bobNewCommit, err := chanB.SignNextCommitment() + bobNewCommit, err := chanB.SignNextCommitment(ctxb) if err != nil { return err } diff --git a/lnwallet/transactions_test.go b/lnwallet/transactions_test.go index 8786c2d5d..0f7988a32 100644 --- a/lnwallet/transactions_test.go +++ b/lnwallet/transactions_test.go @@ -357,7 +357,7 @@ func testVectors(t *testing.T, chanType channeldb.ChannelType, test testCase) { // Execute commit dance to arrive at the point where the local node has // received the test commitment and the remote signature. - localNewCommit, err := localChannel.SignNextCommitment() + localNewCommit, err := localChannel.SignNextCommitment(ctxb) require.NoError(t, err, "local unable to sign commitment") err = remoteChannel.ReceiveNewCommitment(localNewCommit.CommitSigs) @@ -369,7 +369,7 @@ func testVectors(t *testing.T, chanType channeldb.ChannelType, test testCase) { _, _, err = localChannel.ReceiveRevocation(revMsg) require.NoError(t, err) - remoteNewCommit, err := remoteChannel.SignNextCommitment() + remoteNewCommit, err := remoteChannel.SignNextCommitment(ctxb) require.NoError(t, err) require.Equal(