From 890636a1312602a1184bdf1418e2eea85ef8d2c0 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 31 Mar 2026 17:07:04 -0700 Subject: [PATCH] multi: fix linter issues Fix gci (extra blank lines) and ll (line length > 80 chars) issues across contractcourt, input, and watchtower packages. --- contractcourt/channel_arbitrator.go | 7 -- contractcourt/utxonursery.go | 2 +- contractcourt/utxonursery_test.go | 48 ++++---- input/size_test.go | 119 ++++++++++++++++++-- lnwallet/channel_test.go | 167 ++++++++++++++++------------ watchtower/blob/type.go | 3 +- 6 files changed, 234 insertions(+), 112 deletions(-) diff --git a/contractcourt/channel_arbitrator.go b/contractcourt/channel_arbitrator.go index a1b6f649b..458a8a0d2 100644 --- a/contractcourt/channel_arbitrator.go +++ b/contractcourt/channel_arbitrator.go @@ -2466,8 +2466,6 @@ func (c *ChannelArbitrator) prepContractResolutions( continue } - - resolver := newSuccessResolver( resolution, height, htlc, chanType, resolverCfg, @@ -2497,8 +2495,6 @@ func (c *ChannelArbitrator) prepContractResolutions( continue } - - resolver := newTimeoutResolver( resolution, height, htlc, chanType, resolverCfg, @@ -2540,8 +2536,6 @@ func (c *ChannelArbitrator) prepContractResolutions( continue } - - resolver := newIncomingContestResolver( resolution, height, htlc, chanType, resolverCfg, @@ -2574,7 +2568,6 @@ func (c *ChannelArbitrator) prepContractResolutions( continue } - resolver := newOutgoingContestResolver( resolution, height, htlc, chanType, resolverCfg, diff --git a/contractcourt/utxonursery.go b/contractcourt/utxonursery.go index 815ac3017..2f534ecf4 100644 --- a/contractcourt/utxonursery.go +++ b/contractcourt/utxonursery.go @@ -604,7 +604,6 @@ func (u *UtxoNursery) IncubateOutputs(chanPoint wire.OutPoint, return nil } - // NurseryReport attempts to return a nursery report stored for the target // outpoint. A nursery report details the maturity/sweeping progress for a // contract that was previously force closed. If a report entry for the target @@ -1543,6 +1542,7 @@ func makeKidOutput(outpoint, originChanPoint *wire.OutPoint, // This is an HTLC either if it's an incoming HTLC on our commitment // transaction, or is an outgoing HTLC on the commitment transaction of // the remote peer. + //nolint:ll isHtlc := (witnessType == input.HtlcAcceptedSuccessSecondLevel || witnessType == input.TaprootHtlcAcceptedSuccessSecondLevel || witnessType == input.TaprootHtlcAcceptedSuccessSecondLevelFinal || diff --git a/contractcourt/utxonursery_test.go b/contractcourt/utxonursery_test.go index 7ca984df1..f9dd302c9 100644 --- a/contractcourt/utxonursery_test.go +++ b/contractcourt/utxonursery_test.go @@ -1492,12 +1492,12 @@ func TestMakeBabyOutputWitnessType(t *testing.T) { name: "staging taproot", pkScript: taprootPkScript, isFinalTaproot: false, - expectedWitType: input.TaprootHtlcOfferedTimeoutSecondLevel, + expectedWitType: input.TaprootHtlcOfferedTimeoutSecondLevel, //nolint:ll }, { - name: "production taproot final", - pkScript: taprootPkScript, - isFinalTaproot: true, + name: "production taproot final", + pkScript: taprootPkScript, + isFinalTaproot: true, expectedWitType: input.TaprootHtlcOfferedTimeoutSecondLevelFinal, //nolint:ll }, } @@ -1571,8 +1571,8 @@ func TestIncubateConfigWitnessTypeSelection(t *testing.T) { expectedOutgoing: input.HtlcOfferedRemoteTimeout, }, { - name: "staging taproot incoming+outgoing", - pkScript: taprootPkScript, + name: "staging taproot incoming+outgoing", + pkScript: taprootPkScript, expectedIncoming: input.TaprootHtlcAcceptedSuccessSecondLevel, //nolint:ll expectedOutgoing: input.TaprootHtlcOfferedRemoteTimeout, }, @@ -1598,33 +1598,37 @@ func TestIncubateConfigWitnessTypeSelection(t *testing.T) { opt(&cfg) } - isFinalTaproot := cfg.chanType.UnwrapOr(0).IsTaprootFinal() + isFinal := cfg.chanType.UnwrapOr( + 0, + ).IsTaprootFinal() - // Verify incoming HTLC witness type selection. - isTaproot := txscript.IsPayToTaproot(tc.pkScript) + // Verify incoming HTLC witness type. + isTaproot := txscript.IsPayToTaproot( + tc.pkScript, + ) - var incomingWit input.StandardWitnessType + var inWit input.StandardWitnessType switch { - case isFinalTaproot: - incomingWit = input.TaprootHtlcAcceptedSuccessSecondLevelFinal //nolint:ll + case isFinal: + inWit = input.TaprootHtlcAcceptedSuccessSecondLevelFinal //nolint:ll case isTaproot: - incomingWit = input.TaprootHtlcAcceptedSuccessSecondLevel //nolint:ll + inWit = input.TaprootHtlcAcceptedSuccessSecondLevel //nolint:ll default: - incomingWit = input.HtlcAcceptedSuccessSecondLevel + inWit = input.HtlcAcceptedSuccessSecondLevel //nolint:ll } - require.Equal(t, tc.expectedIncoming, incomingWit) + require.Equal(t, tc.expectedIncoming, inWit) - // Verify outgoing remote HTLC witness type selection. - var outgoingWit input.StandardWitnessType + // Verify outgoing remote HTLC witness type. + var outWit input.StandardWitnessType switch { - case isFinalTaproot: - outgoingWit = input.TaprootHtlcOfferedRemoteTimeoutFinal //nolint:ll + case isFinal: + outWit = input.TaprootHtlcOfferedRemoteTimeoutFinal //nolint:ll case isTaproot: - outgoingWit = input.TaprootHtlcOfferedRemoteTimeout + outWit = input.TaprootHtlcOfferedRemoteTimeout //nolint:ll default: - outgoingWit = input.HtlcOfferedRemoteTimeout + outWit = input.HtlcOfferedRemoteTimeout } - require.Equal(t, tc.expectedOutgoing, outgoingWit) + require.Equal(t, tc.expectedOutgoing, outWit) }) } } diff --git a/input/size_test.go b/input/size_test.go index b089a832b..88a66c75a 100644 --- a/input/size_test.go +++ b/input/size_test.go @@ -1421,10 +1421,12 @@ var witnessSizeTests = []witnessSizeTest{ KeyDesc: keychain.KeyDescriptor{ PubKey: testKey.PubKey(), }, - WitnessScript: commitScriptTree.SettleLeaf.Script, - HashType: txscript.SigHashAll, - InputIndex: 0, - SignMethod: input.TaprootScriptSpendSignMethod, + WitnessScript: commitScriptTree. + SettleLeaf.Script, + HashType: txscript.SigHashAll, + InputIndex: 0, + SignMethod: input. + TaprootScriptSpendSignMethod, } witness, err := input.TaprootCommitSpendSuccess( @@ -1444,8 +1446,9 @@ var witnessSizeTests = []witnessSizeTest{ require.NoError(t, err) signer := &dummySigner{} - commitScriptTree, err := input.NewRemoteCommitScriptTree( - testKey.PubKey(), input.NoneTapLeaf(), + cst, err := input.NewRemoteCommitScriptTree( + testKey.PubKey(), + input.NoneTapLeaf(), input.WithProdScripts(), ) require.NoError(t, err) @@ -1454,15 +1457,113 @@ var witnessSizeTests = []witnessSizeTest{ KeyDesc: keychain.KeyDescriptor{ PubKey: testKey.PubKey(), }, - WitnessScript: commitScriptTree.SettleLeaf.Script, + WitnessScript: cst.SettleLeaf.Script, HashType: txscript.SigHashAll, InputIndex: 0, - SignMethod: input.TaprootScriptSpendSignMethod, + SignMethod: input. + TaprootScriptSpendSignMethod, } witness, err := input.TaprootCommitRemoteSpend( signer, signDesc, testTx, - commitScriptTree.TapscriptTree, + cst.TapscriptTree, + ) + require.NoError(t, err) + + return witness + }, + }, + { + name: "taproot offered remote timeout final", + expSize: input.TaprootHtlcOfferedRemoteTimeoutWitnessSizeFinal, + genWitness: func(t *testing.T) wire.TxWitness { + senderKey, err := btcec.NewPrivateKey() + require.NoError(t, err) + + receiverKey, err := btcec.NewPrivateKey() + require.NoError(t, err) + + revokeKey, err := btcec.NewPrivateKey() + require.NoError(t, err) + + var payHash [32]byte + + signer := &dummySigner{} + + htlcScriptTree, err := input.ReceiverHTLCScriptTaproot( + testCLTVExpiry, senderKey.PubKey(), + receiverKey.PubKey(), revokeKey.PubKey(), + payHash[:], lntypes.Remote, + input.NoneTapLeaf(), + input.WithProdScripts(), + ) + require.NoError(t, err) + + timeoutLeaf := htlcScriptTree.TimeoutTapLeaf + + signDesc := &input.SignDescriptor{ + KeyDesc: keychain.KeyDescriptor{ + PubKey: senderKey.PubKey(), + }, + WitnessScript: timeoutLeaf.Script, + HashType: txscript.SigHashAll, + InputIndex: 0, + SignMethod: input. + TaprootScriptSpendSignMethod, + } + + witness, err := input.ReceiverHTLCScriptTaprootTimeout( + signer, signDesc, testTx, testCLTVExpiry, + revokeKey.PubKey(), + htlcScriptTree.TapscriptTree, + ) + require.NoError(t, err) + + return witness + }, + }, + { + name: "taproot accepted remote success final", + expSize: input.TaprootHtlcAcceptedRemoteSuccessWitnessSizeFinal, + genWitness: func(t *testing.T) wire.TxWitness { + senderKey, err := btcec.NewPrivateKey() + require.NoError(t, err) + + receiverKey, err := btcec.NewPrivateKey() + require.NoError(t, err) + + revokeKey, err := btcec.NewPrivateKey() + require.NoError(t, err) + + var payHash [32]byte + + signer := &dummySigner{} + + htlcScriptTree, err := input.SenderHTLCScriptTaproot( + senderKey.PubKey(), receiverKey.PubKey(), + revokeKey.PubKey(), payHash[:], + lntypes.Remote, input.NoneTapLeaf(), + input.WithProdScripts(), + ) + require.NoError(t, err) + + successLeaf := htlcScriptTree.SuccessTapLeaf + scriptTree := htlcScriptTree.TapscriptTree + + signDesc := &input.SignDescriptor{ + KeyDesc: keychain.KeyDescriptor{ + PubKey: receiverKey.PubKey(), + }, + WitnessScript: successLeaf.Script, + HashType: txscript.SigHashAll, + InputIndex: 0, + SignMethod: input. + TaprootScriptSpendSignMethod, + } + + witness, err := input.SenderHTLCScriptTaprootRedeem( + signer, signDesc, testTx, testPreimage, + revokeKey.PubKey(), scriptTree, ) require.NoError(t, err) diff --git a/lnwallet/channel_test.go b/lnwallet/channel_test.go index 7afe2af54..ab96d3397 100644 --- a/lnwallet/channel_test.go +++ b/lnwallet/channel_test.go @@ -3587,52 +3587,49 @@ func testChanSyncOweCommitment(t *testing.T, } // TestChanSyncTaprootLocalNonces tests the nonce synchronization behavior for -// taproot channels. The nonce field populated depends on the channel type: -// - Staging taproot (SimpleTaprootFeatureBit): only LocalNonce is populated. -// - Final taproot (TaprootFinalBit): only LocalNonces is populated. +// taproot channels. The nonce field populated is auto-detected from the +// channel type: +// - Staging taproot: only LocalNonce is populated (legacy format). +// - Final taproot: only LocalNonces map is populated (map format). func TestChanSyncTaprootLocalNonces(t *testing.T) { t.Parallel() - chanType := channeldb.SimpleTaprootFeatureBit - aliceChannel, bobChannel, err := CreateTestChannels(t, chanType) - require.NoError(t, err) + // Staging taproot channels use the legacy single nonce field. + t.Run( + "staging channel populates LocalNonce", + func(t *testing.T) { + chanType := channeldb.SimpleTaprootFeatureBit + aliceChannel, bobChannel, err := CreateTestChannels( + t, chanType, + ) + require.NoError(t, err) - // Also create a pair of final taproot channels. Final taproot channels - // populate the map-based LocalNonces field instead of the legacy - // LocalNonce field. - finalChanType := channeldb.SimpleTaprootFeatureBit | - channeldb.TaprootFinalBit - aliceFinalChan, bobFinalChan, err := CreateTestChannels( - t, finalChanType, + assertNoChanSyncNeeded(t, aliceChannel, bobChannel) + + aliceChanSyncMsg, err := + aliceChannel.channelState.ChanSyncMsg() + require.NoError(t, err) + bobChanSyncMsg, err := + bobChannel.channelState.ChanSyncMsg() + require.NoError(t, err) + + // Only LocalNonce should be populated. + require.True(t, aliceChanSyncMsg.LocalNonce.IsSome()) + require.True(t, aliceChanSyncMsg.LocalNonces.IsNone()) + require.True(t, bobChanSyncMsg.LocalNonce.IsSome()) + require.True(t, bobChanSyncMsg.LocalNonces.IsNone()) + }, ) - require.NoError(t, err) - fundingTxid := aliceChannel.channelState.FundingOutpoint.Hash - finalFundingTxid := aliceFinalChan.channelState.FundingOutpoint.Hash + // Final taproot channels use the map-based nonce field. + t.Run("final channel populates LocalNonces", func(t *testing.T) { + chanType := channeldb.SimpleTaprootFeatureBit | + channeldb.TaprootFinalBit + aliceChannel, _, err := CreateTestChannels(t, chanType) + require.NoError(t, err) - t.Run("staging taproot only populates LocalNonce", func(t *testing.T) { - assertNoChanSyncNeeded(t, aliceChannel, bobChannel) - - // Staging taproot channels populate only the legacy - // LocalNonce field. aliceChanSyncMsg, err := aliceChannel.channelState.ChanSyncMsg() require.NoError(t, err) - bobChanSyncMsg, err := bobChannel.channelState.ChanSyncMsg() - require.NoError(t, err) - - // Only LocalNonce should be populated. - require.True(t, aliceChanSyncMsg.LocalNonce.IsSome()) - require.True(t, aliceChanSyncMsg.LocalNonces.IsNone()) - require.True(t, bobChanSyncMsg.LocalNonce.IsSome()) - require.True(t, bobChanSyncMsg.LocalNonces.IsNone()) - }) - - t.Run("final taproot only populates LocalNonces", func(t *testing.T) { - // Final taproot channels populate only the map-based - // LocalNonces field. - aliceFinalState := aliceFinalChan.channelState - aliceChanSyncMsg, err := aliceFinalState.ChanSyncMsg() - require.NoError(t, err) // Only LocalNonces should be populated. require.True(t, aliceChanSyncMsg.LocalNonce.IsNone()) @@ -3642,48 +3639,60 @@ func TestChanSyncTaprootLocalNonces(t *testing.T) { require.Len(t, noncesData.NoncesMap, 1) }) - t.Run("sync with only LocalNonces field", func(t *testing.T) { - // Final taproot channels send messages with only the - // LocalNonces field populated. Verify that the receiving side - // can process such a message. - aliceFinalState := aliceFinalChan.channelState - aliceChanSyncMsg, err := aliceFinalState.ChanSyncMsg() - require.NoError(t, err) - bobChanSyncMsg, err := bobFinalChan.channelState.ChanSyncMsg() - require.NoError(t, err) - - bobFinalChan.pendingVerificationNonce = &musig2.Nonces{ - PubNonce: extractCommitmentNonce( - t, bobChanSyncMsg, finalFundingTxid, - ), - } - - // Bob should be able to process Alice's message which has - // only the LocalNonces field populated. - bobMsgsToSend, _, _, err := bobFinalChan.ProcessChanSyncMsg( - ctxb, aliceChanSyncMsg, + t.Run("sync with final channel LocalNonces", func(t *testing.T) { + chanType := channeldb.SimpleTaprootFeatureBit | + channeldb.TaprootFinalBit + aliceChannel, bobChannel, err := CreateTestChannels( + t, chanType, ) require.NoError(t, err) - require.Empty(t, bobMsgsToSend) - }) - t.Run("sync with only legacy LocalNonce field", func(t *testing.T) { + fundingTxid := aliceChannel.channelState.FundingOutpoint.Hash + + // Both channels are final, so both use map nonces. aliceChanSyncMsg, err := aliceChannel.channelState.ChanSyncMsg() require.NoError(t, err) bobChanSyncMsg, err := bobChannel.channelState.ChanSyncMsg() require.NoError(t, err) - // Simulate an older peer that only sends LocalNonce. - aliceModifiedMsg := *aliceChanSyncMsg - aliceModifiedMsg.LocalNonces = lnwire.OptLocalNonces{} - bobChannel.pendingVerificationNonce = &musig2.Nonces{ PubNonce: extractCommitmentNonce( t, bobChanSyncMsg, fundingTxid, ), } + // Bob should be able to process Alice's message with only + // LocalNonces. bobMsgsToSend, _, _, err := bobChannel.ProcessChanSyncMsg( + ctxb, aliceChanSyncMsg, + ) + require.NoError(t, err) + require.Empty(t, bobMsgsToSend) + }) + + t.Run("sync with only legacy LocalNonce field", func(t *testing.T) { + chanType := channeldb.SimpleTaprootFeatureBit + aliceChan, bobChan, err := CreateTestChannels(t, chanType) + require.NoError(t, err) + + fundTxid := aliceChan.channelState.FundingOutpoint.Hash + + aliceChanSyncMsg, err := aliceChan.channelState.ChanSyncMsg() + require.NoError(t, err) + bobChanSyncMsg, err := bobChan.channelState.ChanSyncMsg() + require.NoError(t, err) + + // Simulate an older peer that only sends LocalNonce. + aliceModifiedMsg := *aliceChanSyncMsg + aliceModifiedMsg.LocalNonces = lnwire.OptLocalNonces{} + + bobChan.pendingVerificationNonce = &musig2.Nonces{ + PubNonce: extractCommitmentNonce( + t, bobChanSyncMsg, fundTxid, + ), + } + + bobMsgsToSend, _, _, err := bobChan.ProcessChanSyncMsg( ctxb, &aliceModifiedMsg, ) require.NoError(t, err) @@ -3691,15 +3700,21 @@ func TestChanSyncTaprootLocalNonces(t *testing.T) { }) t.Run("error when LocalNonces missing txid", func(t *testing.T) { - aliceChanSyncMsg, err := aliceChannel.channelState.ChanSyncMsg() + chanType := channeldb.SimpleTaprootFeatureBit + aliceChan, bobChan, err := CreateTestChannels(t, chanType) require.NoError(t, err) - bobChanSyncMsg, err := bobChannel.channelState.ChanSyncMsg() + + fundTxid := aliceChan.channelState.FundingOutpoint.Hash + + aliceChanSyncMsg, err := aliceChan.channelState.ChanSyncMsg() + require.NoError(t, err) + bobChanSyncMsg, err := bobChan.channelState.ChanSyncMsg() require.NoError(t, err) // Use a wrong txid in the LocalNonces map. wrongTxid := chainhash.Hash{0xff, 0xff} nonce := extractCommitmentNonce( - t, aliceChanSyncMsg, fundingTxid, + t, aliceChanSyncMsg, fundTxid, ) aliceModifiedMsg := *aliceChanSyncMsg noncesMap := map[chainhash.Hash]lnwire.Musig2Nonce{ @@ -3709,13 +3724,13 @@ func TestChanSyncTaprootLocalNonces(t *testing.T) { lnwire.LocalNoncesData{NoncesMap: noncesMap}, ) - bobChannel.pendingVerificationNonce = &musig2.Nonces{ + bobChan.pendingVerificationNonce = &musig2.Nonces{ PubNonce: extractCommitmentNonce( - t, bobChanSyncMsg, fundingTxid, + t, bobChanSyncMsg, fundTxid, ), } - _, _, _, err = bobChannel.ProcessChanSyncMsg( + _, _, _, err = bobChan.ProcessChanSyncMsg( ctxb, &aliceModifiedMsg, ) require.Error(t, err) @@ -3726,14 +3741,22 @@ func TestChanSyncTaprootLocalNonces(t *testing.T) { }) t.Run("error when both fields missing", func(t *testing.T) { - aliceChanSyncMsg, err := aliceChannel.channelState.ChanSyncMsg() + chanType := channeldb.SimpleTaprootFeatureBit + aliceChan, _, err := CreateTestChannels(t, chanType) + require.NoError(t, err) + + aliceChanSyncMsg, err := aliceChan.channelState.ChanSyncMsg() require.NoError(t, err) aliceEmptyMsg := *aliceChanSyncMsg aliceEmptyMsg.LocalNonce = lnwire.OptMusig2NonceTLV{} aliceEmptyMsg.LocalNonces = lnwire.OptLocalNonces{} - _, _, _, err = bobChannel.ProcessChanSyncMsg( + // Create a bob to process against. + _, bobChan, err := CreateTestChannels(t, chanType) + require.NoError(t, err) + + _, _, _, err = bobChan.ProcessChanSyncMsg( ctxb, &aliceEmptyMsg, ) require.Error(t, err) diff --git a/watchtower/blob/type.go b/watchtower/blob/type.go index 9c0fbb113..00415afc9 100644 --- a/watchtower/blob/type.go +++ b/watchtower/blob/type.go @@ -90,7 +90,8 @@ const ( // production taproot channel using final scripts with // OP_CHECKSIGVERIFY optimizations. TypeAltruistTaprootFinalCommit = Type( - FlagCommitOutputs | FlagTaprootChannel | FlagTaprootFinalChannel, + FlagCommitOutputs | FlagTaprootChannel | + FlagTaprootFinalChannel, ) )