diff --git a/itest/lnd_channel_balance_test.go b/itest/lnd_channel_balance_test.go index 9f4d5715b..d54258e11 100644 --- a/itest/lnd_channel_balance_test.go +++ b/itest/lnd_channel_balance_test.go @@ -58,10 +58,10 @@ func testChannelBalance(ht *lntemp.HarnessTest) { // As this is a single funder channel, Alice's balance should be // exactly 0.5 BTC since now state transitions have taken place yet. - checkChannelBalance(alice, amount-calcStaticFee(cType, 0), 0) + checkChannelBalance(alice, amount-lntemp.CalcStaticFee(cType, 0), 0) // Ensure Bob currently has no available balance within the channel. - checkChannelBalance(bob, 0, amount-calcStaticFee(cType, 0)) + checkChannelBalance(bob, 0, amount-lntemp.CalcStaticFee(cType, 0)) // Finally close the channel between Alice and Bob, asserting that the // channel has been properly closed on-chain. @@ -129,11 +129,15 @@ func testChannelUnsettledBalance(ht *lntemp.HarnessTest) { // Check alice's channel balance, which should have zero remote and zero // pending balance. - checkChannelBalance(alice, chanAmt-calcStaticFee(cType, 0), 0, 0, 0) + checkChannelBalance( + alice, chanAmt-lntemp.CalcStaticFee(cType, 0), 0, 0, 0, + ) // Check carol's channel balance, which should have zero local and zero // pending balance. - checkChannelBalance(carol, 0, chanAmt-calcStaticFee(cType, 0), 0, 0) + checkChannelBalance( + carol, 0, chanAmt-lntemp.CalcStaticFee(cType, 0), 0, 0, + ) // Channel should be ready for payments. const ( @@ -195,7 +199,8 @@ func testChannelUnsettledBalance(ht *lntemp.HarnessTest) { // Check alice's channel balance, which should have a remote unsettled // balance that equals to the amount of invoices * payAmt. The remote // balance remains zero. - aliceLocal := chanAmt - calcStaticFee(cType, 0) - numInvoices*payAmt + fee := lntemp.CalcStaticFee(cType, 0) + aliceLocal := chanAmt - fee - numInvoices*payAmt checkChannelBalance(alice, aliceLocal, 0, 0, numInvoices*payAmt) // Check carol's channel balance, which should have a local unsettled diff --git a/itest/lnd_channel_graph_test.go b/itest/lnd_channel_graph_test.go index e9e7ae648..0bfc31b7c 100644 --- a/itest/lnd_channel_graph_test.go +++ b/itest/lnd_channel_graph_test.go @@ -141,7 +141,7 @@ func testUpdateChanStatus(ht *lntemp.HarnessTest) { FeeRateMilliMsat: int64(chainreg.DefaultBitcoinFeeRate), TimeLockDelta: chainreg.DefaultBitcoinTimeLockDelta, MinHtlc: 1000, // default value - MaxHtlcMsat: calculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntemp.CalculateMaxHtlc(chanAmt), } // Manually disable the channel and ensure that a "Disabled = true" diff --git a/itest/lnd_channel_policy_test.go b/itest/lnd_channel_policy_test.go index b605ea8b7..1d2f75e1e 100644 --- a/itest/lnd_channel_policy_test.go +++ b/itest/lnd_channel_policy_test.go @@ -25,7 +25,7 @@ func testUpdateChannelPolicy(ht *lntemp.HarnessTest) { defaultTimeLockDelta = chainreg.DefaultBitcoinTimeLockDelta defaultMinHtlc = 1000 ) - defaultMaxHtlc := calculateMaxHtlc(funding.MaxBtcFundingAmount) + defaultMaxHtlc := lntemp.CalculateMaxHtlc(funding.MaxBtcFundingAmount) chanAmt := funding.MaxBtcFundingAmount pushAmt := chanAmt / 2 @@ -513,7 +513,7 @@ func testSendUpdateDisableChannel(ht *lntemp.HarnessTest) { FeeRateMilliMsat: int64(chainreg.DefaultBitcoinFeeRate), TimeLockDelta: chainreg.DefaultBitcoinTimeLockDelta, MinHtlc: 1000, // default value - MaxHtlcMsat: calculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntemp.CalculateMaxHtlc(chanAmt), Disabled: true, } diff --git a/itest/lnd_funding_test.go b/itest/lnd_funding_test.go index b4d3271e7..1bfb733af 100644 --- a/itest/lnd_funding_test.go +++ b/itest/lnd_funding_test.go @@ -193,7 +193,7 @@ func basicChannelFundingTest(ht *lntemp.HarnessTest, // With the channel open, ensure that the amount specified above has // properly been pushed to Bob. - aliceLocalBalance := chanAmt - pushAmt - calcStaticFee(cType, 0) + aliceLocalBalance := chanAmt - pushAmt - lntemp.CalcStaticFee(cType, 0) checkChannelBalance( alice, aliceChannelBalance, aliceLocalBalance, pushAmt, ) @@ -289,7 +289,7 @@ func testUnconfirmedChannelFunding(ht *lntemp.HarnessTest) { // Note that atm we haven't obtained the chanPoint yet, so we use the // type directly. cType := lnrpc.CommitmentType_STATIC_REMOTE_KEY - carolLocalBalance := chanAmt - pushAmt - calcStaticFee(cType, 0) + carolLocalBalance := chanAmt - pushAmt - lntemp.CalcStaticFee(cType, 0) checkChannelBalance(carol, 0, 0, carolLocalBalance, pushAmt) // For Alice, her local/remote balances should be zero, and the @@ -423,7 +423,7 @@ func runChannelFundingInputTypes(ht *lntemp.HarnessTest, alice, // Note that atm we haven't obtained the chanPoint yet, so we // use the type directly. cType := lnrpc.CommitmentType_STATIC_REMOTE_KEY - carolLocalBalance := chanAmt - calcStaticFee(cType, 0) + carolLocalBalance := chanAmt - lntemp.CalcStaticFee(cType, 0) checkChannelBalance(carol, 0, 0, carolLocalBalance, 0) // For Alice, her local/remote balances should be zero, and the diff --git a/itest/lnd_multi-hop-error-propagation_test.go b/itest/lnd_multi-hop-error-propagation_test.go index a5cca06aa..009c9769c 100644 --- a/itest/lnd_multi-hop-error-propagation_test.go +++ b/itest/lnd_multi-hop-error-propagation_test.go @@ -55,7 +55,7 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { ht.AssertTopologyChannelOpen(alice, chanPointBob) cType := ht.GetChannelCommitType(alice, chanPointAlice) - commitFee := calcStaticFee(cType, 0) + commitFee := lntemp.CalcStaticFee(cType, 0) assertBaseBalance := func() { // Alice has opened a channel with Bob with zero push amount, diff --git a/itest/lnd_multi-hop-payments_test.go b/itest/lnd_multi-hop-payments_test.go index 28c032061..3baec46af 100644 --- a/itest/lnd_multi-hop-payments_test.go +++ b/itest/lnd_multi-hop-payments_test.go @@ -69,7 +69,7 @@ func testMultiHopPayments(ht *lntemp.HarnessTest) { // Set the fee policies of the Alice -> Bob and the Dave -> Alice // channel edges to relatively large non default values. This makes it // possible to pick up more subtle fee calculation errors. - maxHtlc := calculateMaxHtlc(chanAmt) + maxHtlc := lntemp.CalculateMaxHtlc(chanAmt) const aliceBaseFeeSat = 1 const aliceFeeRatePPM = 100000 updateChannelPolicy( diff --git a/itest/lnd_open_channel_test.go b/itest/lnd_open_channel_test.go index b3c4a4aca..06f8817e1 100644 --- a/itest/lnd_open_channel_test.go +++ b/itest/lnd_open_channel_test.go @@ -182,7 +182,7 @@ func testOpenChannelUpdateFeePolicy(ht *lntemp.HarnessTest) { optionalFeeRate = 1337 ) - defaultMaxHtlc := calculateMaxHtlc(funding.MaxBtcFundingAmount) + defaultMaxHtlc := lntemp.CalculateMaxHtlc(funding.MaxBtcFundingAmount) chanAmt := funding.MaxBtcFundingAmount pushAmt := chanAmt / 2 diff --git a/itest/lnd_routing_test.go b/itest/lnd_routing_test.go index 53d9f2b97..7dd9ef299 100644 --- a/itest/lnd_routing_test.go +++ b/itest/lnd_routing_test.go @@ -1203,7 +1203,7 @@ func testRouteFeeCutoff(ht *lntemp.HarnessTest) { baseFee := int64(10000) feeRate := int64(5) timeLockDelta := uint32(chainreg.DefaultBitcoinTimeLockDelta) - maxHtlc := calculateMaxHtlc(chanAmt) + maxHtlc := lntemp.CalculateMaxHtlc(chanAmt) expectedPolicy := &lnrpc.RoutingPolicy{ FeeBaseMsat: baseFee, diff --git a/itest/lnd_test.go b/itest/lnd_test.go index 5aa39f059..0ff7294e2 100644 --- a/itest/lnd_test.go +++ b/itest/lnd_test.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "io" + "math" "os" "path/filepath" "runtime" @@ -11,9 +12,12 @@ import ( "testing" "time" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/integration/rpctest" + "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lntemp" "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" "google.golang.org/grpc/grpclog" ) @@ -26,9 +30,25 @@ const ( // defaultRunTranche is the default index of the test cases tranche that // we run. defaultRunTranche uint = 0 + + defaultTimeout = wait.DefaultTimeout + itestLndBinary = "../lnd-itest" + + // TODO(yy): remove the following defined constants and put them in the + // specific tests where they are used? + testFeeBase = 1e+6 + anchorSize = 330 + defaultCSV = node.DefaultCSV + noFeeLimitMsat = math.MaxInt64 + + AddrTypeWitnessPubkeyHash = lnrpc.AddressType_WITNESS_PUBKEY_HASH + AddrTypeNestedPubkeyHash = lnrpc.AddressType_NESTED_PUBKEY_HASH + AddrTypeTaprootPubkey = lnrpc.AddressType_TAPROOT_PUBKEY ) var ( + harnessNetParams = &chaincfg.RegressionNetParams + // testCasesSplitParts is the number of tranches the test cases should // be split into. By default this is set to 1, so no splitting happens. // If this value is increased, then the -runtranche flag must be @@ -50,6 +70,11 @@ var ( // dbBackendFlag specifies the backend to use. dbBackendFlag = flag.String("dbbackend", "bbolt", "Database backend "+ "(bbolt, etcd, postgres)") + + // lndExecutable is the full path to the lnd binary. + lndExecutable = flag.String( + "lndexec", itestLndBinary, "full path to lnd binary", + ) ) // TestLightningNetworkDaemon performs a series of integration tests amongst a diff --git a/itest/lnd_zero_conf_test.go b/itest/lnd_zero_conf_test.go index 61aadb708..4482874e3 100644 --- a/itest/lnd_zero_conf_test.go +++ b/itest/lnd_zero_conf_test.go @@ -541,7 +541,7 @@ func testPrivateUpdateAlias(ht *lntemp.HarnessTest, FeeRateMilliMsat: testFeeBase * feeRate, TimeLockDelta: timeLockDelta, MinHtlc: 1000, // default value - MaxHtlcMsat: calculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntemp.CalculateMaxHtlc(chanAmt), } // Assert that Dave receives Carol's policy update. @@ -567,7 +567,7 @@ func testPrivateUpdateAlias(ht *lntemp.HarnessTest, FeeRateMilliMsat: testFeeBase * feeRate, TimeLockDelta: timeLockDelta, MinHtlc: 1000, - MaxHtlcMsat: calculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntemp.CalculateMaxHtlc(chanAmt), } // Assert that Carol receives Dave's policy update. @@ -654,7 +654,7 @@ func testPrivateUpdateAlias(ht *lntemp.HarnessTest, FeeRateMilliMsat: testFeeBase * feeRate, TimeLockDelta: timeLockDelta, MinHtlc: 1000, - MaxHtlcMsat: calculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntemp.CalculateMaxHtlc(chanAmt), } // Assert Dave receives Carol's policy update. @@ -743,7 +743,7 @@ func testPrivateUpdateAlias(ht *lntemp.HarnessTest, FeeRateMilliMsat: testFeeBase * feeRate, TimeLockDelta: timeLockDelta, MinHtlc: 1000, - MaxHtlcMsat: calculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntemp.CalculateMaxHtlc(chanAmt), } // Assert Dave and optionally Eve receives Carol's update. diff --git a/itest/utils.go b/itest/utils.go deleted file mode 100644 index 9ab8706f4..000000000 --- a/itest/utils.go +++ /dev/null @@ -1,77 +0,0 @@ -package itest - -import ( - "flag" - "math" - - "github.com/btcsuite/btcd/btcutil" - "github.com/btcsuite/btcd/chaincfg" - "github.com/lightningnetwork/lnd/input" - "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntest/wait" - "github.com/lightningnetwork/lnd/lnwallet" - "github.com/lightningnetwork/lnd/lnwallet/chainfee" - "github.com/lightningnetwork/lnd/lnwire" -) - -const ( - testFeeBase = 1e+6 - defaultCSV = node.DefaultCSV - defaultTimeout = wait.DefaultTimeout - itestLndBinary = "../../lnd-itest" - anchorSize = 330 - noFeeLimitMsat = math.MaxInt64 - - AddrTypeWitnessPubkeyHash = lnrpc.AddressType_WITNESS_PUBKEY_HASH - AddrTypeNestedPubkeyHash = lnrpc.AddressType_NESTED_PUBKEY_HASH - AddrTypeTaprootPubkey = lnrpc.AddressType_TAPROOT_PUBKEY -) - -var ( - harnessNetParams = &chaincfg.RegressionNetParams - - // lndExecutable is the full path to the lnd binary. - lndExecutable = flag.String( - "lndexec", itestLndBinary, "full path to lnd binary", - ) -) - -// calcStaticFee calculates appropriate fees for commitment transactions. This -// function provides a simple way to allow test balance assertions to take fee -// calculations into account. -func calcStaticFee(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { - const htlcWeight = input.HTLCWeight - var ( - feePerKw = chainfee.SatPerKWeight( - lntemp.DefaultFeeRateSatPerKw, - ) - commitWeight = input.CommitWeight - anchors = btcutil.Amount(0) - defaultSatPerVByte = lnwallet.DefaultAnchorsCommitMaxFeeRateSatPerVByte - ) - - // The anchor commitment type is slightly heavier, and we must also add - // the value of the two anchors to the resulting fee the initiator - // pays. In addition the fee rate is capped at 10 sat/vbyte for anchor - // channels. - if lntemp.CommitTypeHasAnchors(c) { - feePerKw = chainfee.SatPerKVByte( - defaultSatPerVByte * 1000).FeePerKWeight() - commitWeight = input.AnchorCommitWeight - anchors = 2 * anchorSize - } - - return feePerKw.FeeForWeight(int64(commitWeight+htlcWeight*numHTLCs)) + - anchors -} - -// calculateMaxHtlc re-implements the RequiredRemoteChannelReserve of the -// funding manager's config, which corresponds to the maximum MaxHTLC value we -// allow users to set when updating a channel policy. -func calculateMaxHtlc(chanCap btcutil.Amount) uint64 { - reserve := lnwire.NewMSatFromSatoshis(chanCap / 100) - max := lnwire.NewMSatFromSatoshis(chanCap) - reserve - return uint64(max) -} diff --git a/lntemp/utils.go b/lntemp/utils.go index ecf460fc6..acb5b77e5 100644 --- a/lntemp/utils.go +++ b/lntemp/utils.go @@ -8,9 +8,14 @@ import ( "strconv" "strings" + "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/wire" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lntest/wait" + "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/lnwallet/chainfee" + "github.com/lightningnetwork/lnd/lnwire" ) const ( @@ -152,3 +157,44 @@ func NodeArgsForCommitType(commitType lnrpc.CommitmentType) []string { return nil } + +// CalcStaticFee calculates appropriate fees for commitment transactions. This +// function provides a simple way to allow test balance assertions to take fee +// calculations into account. +func CalcStaticFee(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { + const ( + htlcWeight = input.HTLCWeight + anchorSize = 330 + defaultSatPerVByte = lnwallet.DefaultAnchorsCommitMaxFeeRateSatPerVByte + ) + + var ( + anchors = btcutil.Amount(0) + commitWeight = input.CommitWeight + feePerKw = chainfee.SatPerKWeight(DefaultFeeRateSatPerKw) + ) + + // The anchor commitment type is slightly heavier, and we must also add + // the value of the two anchors to the resulting fee the initiator + // pays. In addition the fee rate is capped at 10 sat/vbyte for anchor + // channels. + if CommitTypeHasAnchors(c) { + feePerKw = chainfee.SatPerKVByte( + defaultSatPerVByte * 1000, + ).FeePerKWeight() + commitWeight = input.AnchorCommitWeight + anchors = 2 * anchorSize + } + + return feePerKw.FeeForWeight(int64(commitWeight+htlcWeight*numHTLCs)) + + anchors +} + +// CalculateMaxHtlc re-implements the RequiredRemoteChannelReserve of the +// funding manager's config, which corresponds to the maximum MaxHTLC value we +// allow users to set when updating a channel policy. +func CalculateMaxHtlc(chanCap btcutil.Amount) uint64 { + reserve := lnwire.NewMSatFromSatoshis(chanCap / 100) + max := lnwire.NewMSatFromSatoshis(chanCap) - reserve + return uint64(max) +}