From 6618ab493aa6298a936c341257b98fbed5d89799 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Sun, 20 Nov 2022 11:14:05 +0800 Subject: [PATCH 01/45] multi: enhance loggings and fix logging format Also adds TODO for a possible bug. --- contractcourt/chain_watcher.go | 6 +++--- netann/chan_status_manager.go | 1 + peer/brontide.go | 2 +- routing/payment_lifecycle.go | 2 ++ routing/unified_edges.go | 33 +++++++++++++++++++++++++++++++++ routing/validation_barrier.go | 4 ++-- server.go | 11 ++++++----- 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/contractcourt/chain_watcher.go b/contractcourt/chain_watcher.go index 3939fef0b..99472e0c1 100644 --- a/contractcourt/chain_watcher.go +++ b/contractcourt/chain_watcher.go @@ -497,10 +497,10 @@ func newChainSet(chanState *channeldb.OpenChannel) (*chainSet, error) { "chan_point=%v", chanState.FundingOutpoint) } - log.Debugf("ChannelPoint(%v): local_commit_type=%v, local_commit=%v", + log.Tracef("ChannelPoint(%v): local_commit_type=%v, local_commit=%v", chanState.FundingOutpoint, chanState.ChanType, spew.Sdump(localCommit)) - log.Debugf("ChannelPoint(%v): remote_commit_type=%v, remote_commit=%v", + log.Tracef("ChannelPoint(%v): remote_commit_type=%v, remote_commit=%v", chanState.FundingOutpoint, chanState.ChanType, spew.Sdump(remoteCommit)) @@ -527,7 +527,7 @@ func newChainSet(chanState *channeldb.OpenChannel) (*chainSet, error) { var remotePendingCommit *channeldb.ChannelCommitment if remoteChainTip != nil { remotePendingCommit = &remoteChainTip.Commitment - log.Debugf("ChannelPoint(%v): remote_pending_commit_type=%v, "+ + log.Tracef("ChannelPoint(%v): remote_pending_commit_type=%v, "+ "remote_pending_commit=%v", chanState.FundingOutpoint, chanState.ChanType, spew.Sdump(remoteChainTip.Commitment)) diff --git a/netann/chan_status_manager.go b/netann/chan_status_manager.go index d37ebed08..8f29888e5 100644 --- a/netann/chan_status_manager.go +++ b/netann/chan_status_manager.go @@ -398,6 +398,7 @@ func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint, // Channel is already enabled, nothing to do. case ChanStatusEnabled: + log.Debugf("Channel(%v) already enabled, skipped announcement") return nil // The channel is enabled, though we are now canceling the scheduled diff --git a/peer/brontide.go b/peer/brontide.go index 4c56626ea..9ea85edd1 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -1898,7 +1898,7 @@ func messageSummary(msg lnwire.Message) string { return fmt.Sprintf("type=%d", msg.Type) } - return "" + return fmt.Sprintf("unknown msg type=%T", msg) } // logWireMessage logs the receipt or sending of particular wire message. This diff --git a/routing/payment_lifecycle.go b/routing/payment_lifecycle.go index 32f0d811d..c6bd7e08e 100644 --- a/routing/payment_lifecycle.go +++ b/routing/payment_lifecycle.go @@ -291,6 +291,8 @@ lifecycle: continue lifecycle } + log.Tracef("Found route: %s", spew.Sdump(rt.Hops)) + // If this route will consume the last remaining amount to send // to the receiver, this will be our last shard (for now). lastShard := rt.ReceiverAmt() == currentState.remainingAmt diff --git a/routing/unified_edges.go b/routing/unified_edges.go index a96a5ffbe..89aaf94ac 100644 --- a/routing/unified_edges.go +++ b/routing/unified_edges.go @@ -105,6 +105,8 @@ func (u *unifiedEdge) amtInRange(amt lnwire.MilliSatoshi) bool { if u.capacity > 0 && amt > lnwire.NewMSatFromSatoshis(u.capacity) { + log.Tracef("Not enough capacity: amt=%v, capacity=%v", + amt, u.capacity) return false } @@ -112,11 +114,15 @@ func (u *unifiedEdge) amtInRange(amt lnwire.MilliSatoshi) bool { if u.policy.MessageFlags.HasMaxHtlc() && amt > u.policy.MaxHTLC { + log.Tracef("Exceeds policy's MaxHTLC: amt=%v, MaxHTLC=%v", + amt, u.policy.MaxHTLC) return false } // Skip channels for which this htlc is too small. if amt < u.policy.MinHTLC { + log.Tracef("below policy's MinHTLC: amt=%v, MinHTLC=%v", + amt, u.policy.MinHTLC) return false } @@ -155,6 +161,8 @@ func (u *edgeUnifier) getEdgeLocal(amt lnwire.MilliSatoshi, for _, edge := range u.edges { // Check valid amount range for the channel. if !edge.amtInRange(amt) { + log.Debugf("Amount %v not in range for edge %v", + amt, edge.policy.ChannelID) continue } @@ -173,11 +181,26 @@ func (u *edgeUnifier) getEdgeLocal(amt lnwire.MilliSatoshi, edge.policy.ChannelID, amt, ) if !ok { + log.Debugf("Cannot get bandwidth for edge %v, use max "+ + "instead", edge.policy.ChannelID) bandwidth = lnwire.MaxMilliSatoshi } + // TODO(yy): if the above `!ok` is chosen, we'd have + // `bandwidth` to be the max value, which will end up having + // the `maxBandwidth` to be have the largest value and this + // edge will be the chosen one. This is wrong in two ways, + // 1. we need to understand why `availableChanBandwidth` cannot + // find bandwidth for this edge as something is wrong with this + // channel, and, + // 2. this edge is likely NOT the local channel with the + // highest available bandwidth. + // // Skip channels that can't carry the payment. if amt > bandwidth { + log.Debugf("Skipped edge %v: not enough bandwidth, "+ + "bandwidth=%v, amt=%v", edge.policy.ChannelID, + bandwidth, amt) continue } @@ -187,6 +210,9 @@ func (u *edgeUnifier) getEdgeLocal(amt lnwire.MilliSatoshi, // querying the bandwidth hints and sending out the // htlc. if bandwidth < maxBandwidth { + log.Debugf("Skipped edge %v: not max bandwidth, "+ + "bandwidth=%v, maxBandwidth=%v", + bandwidth, maxBandwidth) continue } maxBandwidth = bandwidth @@ -213,6 +239,8 @@ func (u *edgeUnifier) getEdgeNetwork(amt lnwire.MilliSatoshi) *unifiedEdge { for _, edge := range u.edges { // Check valid amount range for the channel. if !edge.amtInRange(amt) { + log.Debugf("Amount %v not in range for edge %v", + amt, edge.policy.ChannelID) continue } @@ -220,6 +248,8 @@ func (u *edgeUnifier) getEdgeNetwork(amt lnwire.MilliSatoshi) *unifiedEdge { edgeFlags := edge.policy.ChannelFlags isDisabled := edgeFlags&lnwire.ChanUpdateDisabled != 0 if isDisabled { + log.Debugf("Skipped edge %v due to it being disabled", + edge.policy.ChannelID) continue } @@ -245,6 +275,9 @@ func (u *edgeUnifier) getEdgeNetwork(amt lnwire.MilliSatoshi) *unifiedEdge { // specific amount. fee := edge.policy.ComputeFee(amt) if fee < maxFee { + log.Debugf("Skipped edge %v due to it produces less "+ + "fee: fee=%v, maxFee=%v", + edge.policy.ChannelID, fee, maxFee) continue } maxFee = fee diff --git a/routing/validation_barrier.go b/routing/validation_barrier.go index ed1ac71f0..a7c6561ac 100644 --- a/routing/validation_barrier.go +++ b/routing/validation_barrier.go @@ -198,7 +198,7 @@ func (v *ValidationBarrier) WaitForDependants(job interface{}) error { vertex := route.Vertex(msg.PubKeyBytes) signals, ok = v.nodeAnnDependencies[vertex] - jobDesc = fmt.Sprintf("job=channeldb.LightningNode, pub=%x", + jobDesc = fmt.Sprintf("job=channeldb.LightningNode, pub=%s", vertex) case *lnwire.ChannelUpdate: @@ -210,7 +210,7 @@ func (v *ValidationBarrier) WaitForDependants(job interface{}) error { case *lnwire.NodeAnnouncement: vertex := route.Vertex(msg.NodeID) signals, ok = v.nodeAnnDependencies[vertex] - jobDesc = fmt.Sprintf("job=lnwire.NodeAnnouncement, pub=%x", + jobDesc = fmt.Sprintf("job=lnwire.NodeAnnouncement, pub=%s", vertex) // Other types of jobs can be executed immediately, so we'll just diff --git a/server.go b/server.go index 211955423..0f9e9d43e 100644 --- a/server.go +++ b/server.go @@ -3188,18 +3188,16 @@ func (s *server) prunePersistentPeerConnection(compressedPubKey [33]byte) { func (s *server) BroadcastMessage(skips map[route.Vertex]struct{}, msgs ...lnwire.Message) error { - srvrLog.Debugf("Broadcasting %v messages", len(msgs)) - // Filter out peers found in the skips map. We synchronize access to // peersByPub throughout this process to ensure we deliver messages to // exact set of peers present at the time of invocation. s.mu.RLock() peers := make([]*peer.Brontide, 0, len(s.peersByPub)) - for _, sPeer := range s.peersByPub { + for pubStr, sPeer := range s.peersByPub { if skips != nil { if _, ok := skips[sPeer.PubKey()]; ok { - srvrLog.Tracef("Skipping %x in broadcast", - sPeer.PubKey()) + srvrLog.Debugf("Skipping %x in broadcast with "+ + "pubStr=%x", sPeer.PubKey(), pubStr) continue } } @@ -3212,6 +3210,9 @@ func (s *server) BroadcastMessage(skips map[route.Vertex]struct{}, // all messages to each of peers. var wg sync.WaitGroup for _, sPeer := range peers { + srvrLog.Debugf("Sending %v messages to peer %x", len(msgs), + sPeer.PubKey()) + // Dispatch a go routine to enqueue all messages to this peer. wg.Add(1) s.wg.Add(1) From e50007401780fc944be41ed18c9414096fcbf07f Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Thu, 11 Aug 2022 19:08:25 +0800 Subject: [PATCH 02/45] itest: refactor `testBidirectionalAsyncPayments` --- lntest/itest/list_on_test.go | 4 + lntest/itest/lnd_payment_test.go | 238 ++++++++------------------ lntest/itest/lnd_test_list_on_test.go | 7 +- 3 files changed, 78 insertions(+), 171 deletions(-) diff --git a/lntest/itest/list_on_test.go b/lntest/itest/list_on_test.go index f2531203f..dcf85817c 100644 --- a/lntest/itest/list_on_test.go +++ b/lntest/itest/list_on_test.go @@ -509,4 +509,8 @@ var allTestCasesTemp = []*lntemp.TestCase{ Name: "zero conf reorg edge existence", TestFunc: testZeroConfReorg, }, + { + Name: "async bidirectional payments", + TestFunc: testBidirectionalAsyncPayments, + }, } diff --git a/lntest/itest/lnd_payment_test.go b/lntest/itest/lnd_payment_test.go index 590870285..e9005e6e9 100644 --- a/lntest/itest/lnd_payment_test.go +++ b/lntest/itest/lnd_payment_test.go @@ -1,7 +1,6 @@ package itest import ( - "context" "crypto/sha256" "encoding/hex" "fmt" @@ -304,46 +303,13 @@ func runAsyncPayments(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode) { // All payments have been sent, mark the finish time. timeTaken := time.Since(now) - // assertChannelState asserts the channel state by checking the values - // in fields, LocalBalance, RemoteBalance and num of PendingHtlcs. - assertChannelState := func(hn *node.HarnessNode, cp *lnrpc.ChannelPoint, - localBalance, remoteBalance int64, numPendingHtlcs int) { - - // Get the funding point. - err := wait.NoError(func() error { - // Find the target channel first. - target := ht.GetChannelByChanPoint(hn, cp) - - if len(target.PendingHtlcs) != numPendingHtlcs { - return fmt.Errorf("pending htlcs is "+ - "incorrect, got %v, expected %v", - len(target.PendingHtlcs), 0) - } - - if target.LocalBalance != localBalance { - return fmt.Errorf("local balance is "+ - "incorrect, got %v, expected %v", - target.LocalBalance, localBalance) - } - - if target.RemoteBalance != remoteBalance { - return fmt.Errorf("remote balance is "+ - "incorrect, got %v, expected %v", - target.RemoteBalance, remoteBalance) - } - - return nil - }, lntemp.DefaultTimeout) - require.NoError(ht, err, "timeout while chekcing for balance") - } - // Wait for the revocation to be received so alice no longer has // pending htlcs listed and has correct balances. This is needed due to // the fact that we now pipeline the settles. - assertChannelState(alice, chanPoint, aliceAmt, bobAmt, 0) + assertChannelState(ht, alice, chanPoint, aliceAmt, bobAmt) // Wait for Bob to receive revocation from Alice. - assertChannelState(bob, chanPoint, bobAmt, aliceAmt, 0) + assertChannelState(ht, bob, chanPoint, bobAmt, aliceAmt) ht.Log("\tBenchmark info: Elapsed time: ", timeTaken) ht.Log("\tBenchmark info: TPS: ", @@ -357,28 +323,28 @@ func runAsyncPayments(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode) { // testBidirectionalAsyncPayments tests that nodes are able to send the // payments to each other in async manner without blocking. -func testBidirectionalAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { - ctxb := context.Background() +func testBidirectionalAsyncPayments(ht *lntemp.HarnessTest) { + const paymentAmt = 1000 - const ( - paymentAmt = 1000 - ) + // We use new nodes here as the benchmark test creates lots of data + // which can be costly to be carried on. + alice := ht.NewNode("Alice", []string{"--pending-commit-interval=3m"}) + bob := ht.NewNode("Bob", []string{"--pending-commit-interval=3m"}) + + ht.EnsureConnected(alice, bob) + ht.FundCoins(btcutil.SatoshiPerBitcoin, alice) // First establish a channel with a capacity equals to the overall // amount of payments, between Alice and Bob, at the end of the test // Alice should send all money from her side to Bob. - chanPoint := openChannelAndAssert( - t, net, net.Alice, net.Bob, - lntest.OpenChannelParams{ + chanPoint := ht.OpenChannel( + alice, bob, lntemp.OpenChannelParams{ Amt: paymentAmt * 2000, PushAmt: paymentAmt * 1000, }, ) - info, err := getChanInfo(net.Alice) - if err != nil { - t.Fatalf("unable to get alice channel info: %v", err) - } + info := ht.QueryChannelByChanPoint(alice, chanPoint) // We'll create a number of invoices equal the max number of HTLCs that // can be carried in one direction. The number on the commitment will @@ -394,155 +360,64 @@ func testBidirectionalAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) // With the channel open, we'll create invoices for Bob that Alice // will pay to in order to advance the state of the channel. - bobPayReqs, _, _, err := createPayReqs( - net.Bob, paymentAmt, numInvoices, - ) - if err != nil { - t.Fatalf("unable to create pay reqs: %v", err) - } + bobPayReqs, _, _ := ht.CreatePayReqs(bob, paymentAmt, numInvoices) // With the channel open, we'll create invoices for Alice that Bob // will pay to in order to advance the state of the channel. - alicePayReqs, _, _, err := createPayReqs( - net.Alice, paymentAmt, numInvoices, - ) - if err != nil { - t.Fatalf("unable to create pay reqs: %v", err) - } - - // Wait for Alice to receive the channel edge from the funding manager. - if err = net.Alice.WaitForNetworkChannelOpen(chanPoint); err != nil { - t.Fatalf("alice didn't see the alice->bob channel before "+ - "timeout: %v", err) - } - if err = net.Bob.WaitForNetworkChannelOpen(chanPoint); err != nil { - t.Fatalf("bob didn't see the bob->alice channel before "+ - "timeout: %v", err) - } + alicePayReqs, _, _ := ht.CreatePayReqs(alice, paymentAmt, numInvoices) // Reset mission control to prevent previous payment results from // interfering with this test. A new channel has been opened, but // mission control operates on node pairs. - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - _, err = net.Alice.RouterClient.ResetMissionControl( - ctxt, &routerrpc.ResetMissionControlRequest{}, - ) - if err != nil { - t.Fatalf("unable to reset mc for alice: %v", err) - } + alice.RPC.ResetMissionControl() // Send payments from Alice to Bob and from Bob to Alice in async // manner. - errChan := make(chan error) - statusChan := make(chan *lnrpc.Payment) + settled := make(chan struct{}) + defer close(settled) - send := func(node *lntest.HarnessNode, payReq string) { - go func() { - ctxt, _ = context.WithTimeout( - ctxb, lntest.AsyncBenchmarkTimeout, - ) - stream, err := node.RouterClient.SendPaymentV2( - ctxt, - &routerrpc.SendPaymentRequest{ - PaymentRequest: payReq, - TimeoutSeconds: 60, - FeeLimitMsat: noFeeLimitMsat, - }, - ) - if err != nil { - errChan <- err - } - result, err := getPaymentResult(stream) - if err != nil { - errChan <- err - } + timeout := lntest.AsyncBenchmarkTimeout * 4 + send := func(node *node.HarnessNode, payReq string) { + req := &routerrpc.SendPaymentRequest{ + PaymentRequest: payReq, + TimeoutSeconds: int32(timeout.Seconds()), + FeeLimitMsat: noFeeLimitMsat, + } + // AssertPaymentStatusWithTimeout will assert that the + // payment is settled. + stream := node.RPC.SendPayment(req) + ht.AssertPaymentSucceedWithTimeout(stream, timeout) - statusChan <- result - }() + settled <- struct{}{} } for i := 0; i < numInvoices; i++ { - send(net.Bob, alicePayReqs[i]) - send(net.Alice, bobPayReqs[i]) + go send(bob, alicePayReqs[i]) + go send(alice, bobPayReqs[i]) } // Expect all payments to succeed. + timer := time.After(timeout) for i := 0; i < 2*numInvoices; i++ { select { - case result := <-statusChan: - if result.Status != lnrpc.Payment_SUCCEEDED { - t.Fatalf("payment error: %v", result.Status) - } - - case err := <-errChan: - t.Fatalf("payment error: %v", err) + case <-settled: + case <-timer: + require.Fail(ht, "timeout", "wait payment failed") } } // Wait for Alice and Bob to receive revocations messages, and update // states, i.e. balance info. - err = wait.NoError(func() error { - aliceInfo, err := getChanInfo(net.Alice) - if err != nil { - t.Fatalf("unable to get alice's channel info: %v", err) - } - - if aliceInfo.RemoteBalance != bobAmt { - return fmt.Errorf("alice's remote balance is incorrect, "+ - "got %v, expected %v", aliceInfo.RemoteBalance, - bobAmt) - } - - if aliceInfo.LocalBalance != aliceAmt { - return fmt.Errorf("alice's local balance is incorrect, "+ - "got %v, expected %v", aliceInfo.LocalBalance, - aliceAmt) - } - - if len(aliceInfo.PendingHtlcs) != 0 { - return fmt.Errorf("alice's pending htlcs is incorrect, "+ - "got %v expected %v", - len(aliceInfo.PendingHtlcs), 0) - } - - return nil - }, defaultTimeout) - require.NoError(t.t, err) + assertChannelState(ht, alice, chanPoint, aliceAmt, bobAmt) // Next query for Bob's and Alice's channel states, in order to confirm // that all payment have been successful transmitted. - err = wait.NoError(func() error { - bobInfo, err := getChanInfo(net.Bob) - if err != nil { - t.Fatalf("unable to get bob's channel info: %v", err) - } - - if bobInfo.LocalBalance != bobAmt { - return fmt.Errorf("bob's local balance is incorrect, "+ - "got %v, expected %v", bobInfo.LocalBalance, - bobAmt) - } - - if bobInfo.RemoteBalance != aliceAmt { - return fmt.Errorf("bob's remote balance is incorrect, "+ - "got %v, expected %v", bobInfo.RemoteBalance, - aliceAmt) - } - - if len(bobInfo.PendingHtlcs) != 0 { - return fmt.Errorf("bob's pending htlcs is incorrect, "+ - "got %v, expected %v", - len(bobInfo.PendingHtlcs), 0) - } - - return nil - }, defaultTimeout) - require.NoError(t.t, err) + assertChannelState(ht, bob, chanPoint, bobAmt, aliceAmt) // Finally, immediately close the channel. This function will also // block until the channel is closed and will additionally assert the // relevant channel closing post conditions. - closeChannelAndAssert(t, net, net.Alice, chanPoint, false) + ht.CloseChannel(alice, chanPoint) } func testInvoiceSubscriptions(ht *lntemp.HarnessTest) { @@ -672,3 +547,36 @@ func testInvoiceSubscriptions(ht *lntemp.HarnessTest) { ht.CloseChannel(alice, chanPoint) } + +// assertChannelState asserts the channel state by checking the values in +// fields, LocalBalance, RemoteBalance and num of PendingHtlcs. +func assertChannelState(ht *lntemp.HarnessTest, hn *node.HarnessNode, + cp *lnrpc.ChannelPoint, localBalance, remoteBalance int64) { + + // Get the funding point. + err := wait.NoError(func() error { + // Find the target channel first. + target := ht.GetChannelByChanPoint(hn, cp) + + if len(target.PendingHtlcs) != 0 { + return fmt.Errorf("pending htlcs is "+ + "incorrect, got %v, expected %v", + len(target.PendingHtlcs), 0) + } + + if target.LocalBalance != localBalance { + return fmt.Errorf("local balance is "+ + "incorrect, got %v, expected %v", + target.LocalBalance, localBalance) + } + + if target.RemoteBalance != remoteBalance { + return fmt.Errorf("remote balance is "+ + "incorrect, got %v, expected %v", + target.RemoteBalance, remoteBalance) + } + + return nil + }, lntemp.DefaultTimeout) + require.NoError(ht, err, "timeout while chekcing for balance") +} diff --git a/lntest/itest/lnd_test_list_on_test.go b/lntest/itest/lnd_test_list_on_test.go index 0783688bd..d760ec2ce 100644 --- a/lntest/itest/lnd_test_list_on_test.go +++ b/lntest/itest/lnd_test_list_on_test.go @@ -3,9 +3,4 @@ package itest -var allTestCases = []*testCase{ - { - name: "async bidirectional payments", - test: testBidirectionalAsyncPayments, - }, -} +var allTestCases = []*testCase{} From 142b00711fb040ce89bc6eb07eb91ba05c224116 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Mon, 14 Nov 2022 16:55:08 +0800 Subject: [PATCH 03/45] itest+github: remove flag temptest This commit removes flag `temptest` and all its usage, marking the start of promoting our `lntemp` to be `lntest`! --- .github/workflows/main.yml | 91 +------ lntest/itest/list_off_test.go | 3 +- lntest/itest/list_on_test.go | 3 +- lntest/itest/lnd_test.go | 326 +++++++++++-------------- lntest/itest/lnd_test_list_off_test.go | 6 - lntest/itest/lnd_test_list_on_test.go | 6 - lntest/itest/temp_lnd_test.go | 197 --------------- make/testing_flags.mk | 5 - 8 files changed, 145 insertions(+), 492 deletions(-) delete mode 100644 lntest/itest/lnd_test_list_off_test.go delete mode 100644 lntest/itest/lnd_test_list_on_test.go delete mode 100644 lntest/itest/temp_lnd_test.go diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f93a18912..d42c02003 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -231,7 +231,7 @@ jobs: - name: Zip log files on failure if: ${{ failure() }} timeout-minutes: 1 # timeout after 1 minute - run: 7z a logs-itest-${{ matrix.name }}.zip lntest/itest/**/*.log + run: 7z a logs-itest-${{ matrix.name }}.zip itest/**/*.log - name: Upload log files on failure uses: actions/upload-artifact@v2.2.4 @@ -260,97 +260,10 @@ jobs: - name: run itest run: make itest-parallel windows=1 tranches=2 parallel=2 - - name: Zip log files on failure - if: ${{ failure() }} - run: 7z a logs-itest-windows.zip lntest/itest/**/*.log - - - name: Upload log files on failure - uses: actions/upload-artifact@v2 - if: ${{ failure() }} - with: - name: logs-itest-windows - path: logs-itest-windows.zip - retention-days: 5 - - ######################## - # run new integration tests - ######################## - new-integration-test: - name: run new itests - runs-on: ubuntu-latest - if: '!contains(github.event.pull_request.labels.*.name, ''no-itest'')' - strategy: - # Allow other tests in the matrix to continue if one fails. - fail-fast: false - matrix: - include: - - name: btcd - args: backend=btcd - - name: bitcoind - args: backend=bitcoind - - name: bitcoind-notxindex - args: backend="bitcoind notxindex" - - name: bitcoind-rpcpolling - args: backend="bitcoind rpcpolling" - - name: bitcoind-etcd - args: backend=bitcoind dbbackend=etcd - - name: bitcoind-postgres - args: backend=bitcoind dbbackend=postgres - - name: bitcoind-sqlite - args: backend=bitcoind dbbackend=sqlite - - name: neutrino - args: backend=neutrino - steps: - - name: git checkout - uses: actions/checkout@v3 - - - name: setup go ${{ env.GO_VERSION }} - uses: ./.github/actions/setup-go - with: - go-version: '${{ env.GO_VERSION }}' - - - name: install bitcoind - run: ./scripts/install_bitcoind.sh - - - name: run new ${{ matrix.name }} - run: make itest-parallel temptest=true ${{ matrix.args }} - - name: Zip log files on failure if: ${{ failure() }} timeout-minutes: 1 # timeout after 1 minute - run: 7z a logs-itest-${{ matrix.name }}.zip lntest/itest/**/*.log - - - name: Upload log files on failure - uses: actions/upload-artifact@v2.2.4 - if: ${{ failure() }} - with: - name: logs-itest-${{ matrix.name }} - path: logs-itest-${{ matrix.name }}.zip - retention-days: 5 - - ######################## - # run new windows integration test - ######################## - new-windows-integration-test: - name: run new windows itest - runs-on: windows-latest - if: '!contains(github.event.pull_request.labels.*.name, ''no-itest'')' - steps: - - name: git checkout - uses: actions/checkout@v3 - - - name: setup go ${{ env.GO_VERSION }} - uses: ./.github/actions/setup-go - with: - go-version: '${{ env.GO_VERSION }}' - - - name: run new itest - run: make itest-parallel temptest=true windows=1 tranches=2 parallel=2 - - - name: Zip log files on failure - if: ${{ failure() }} - timeout-minutes: 1 # timeout after 1 minute - run: 7z a logs-itest-windows.zip lntest/itest/**/*.log + run: 7z a logs-itest-windows.zip itest/**/*.log - name: Upload log files on failure uses: actions/upload-artifact@v2 diff --git a/lntest/itest/list_off_test.go b/lntest/itest/list_off_test.go index e34443092..c2e2f67aa 100644 --- a/lntest/itest/list_off_test.go +++ b/lntest/itest/list_off_test.go @@ -5,5 +5,4 @@ package itest import "github.com/lightningnetwork/lnd/lntemp" -// TODO(yy): remove the temp. -var allTestCasesTemp = []*lntemp.TestCase{} +var allTestCases = []*lntemp.TestCase{} diff --git a/lntest/itest/list_on_test.go b/lntest/itest/list_on_test.go index dcf85817c..7f2ed6f0d 100644 --- a/lntest/itest/list_on_test.go +++ b/lntest/itest/list_on_test.go @@ -5,8 +5,7 @@ package itest import "github.com/lightningnetwork/lnd/lntemp" -// TODO(yy): remove the temp. -var allTestCasesTemp = []*lntemp.TestCase{ +var allTestCases = []*lntemp.TestCase{ { Name: "update channel status", TestFunc: testUpdateChanStatus, diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index 1f0dbd4cb..fa3606d0a 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -3,29 +3,135 @@ package itest import ( "flag" "fmt" + "io" "os" + "path/filepath" + "runtime" "strings" "testing" "time" "github.com/btcsuite/btcd/integration/rpctest" + "github.com/lightningnetwork/lnd/lntemp" "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" + "google.golang.org/grpc/grpclog" +) + +const ( + // defaultSplitTranches is the default number of tranches we split the + // test cases into. + defaultSplitTranches uint = 1 + + // defaultRunTranche is the default index of the test cases tranche that + // we run. + defaultRunTranche uint = 0 ) var ( - // tempTest is a flag used to mark whether we should run the old or the - // new test cases. Used here so we can transit smoothly during our new - // itest construction. - // - // TODO(yy): remove temp flag. - tempTest = flag.Bool("temptest", false, "run the new tests(temp)") + // 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 + // specified as well to indicate which part should be run in the current + // invocation. + testCasesSplitTranches = flag.Uint( + "splittranches", defaultSplitTranches, "split the test cases "+ + "in this many tranches and run the tranche at "+ + "0-based index specified by the -runtranche flag", + ) + + // testCasesRunTranche is the 0-based index of the split test cases + // tranche to run in the current invocation. + testCasesRunTranche = flag.Uint( + "runtranche", defaultRunTranche, "run the tranche of the "+ + "split test cases with the given (0-based) index", + ) + + // dbBackendFlag specifies the backend to use. + dbBackendFlag = flag.String("dbbackend", "bbolt", "Database backend "+ + "(bbolt, etcd, postgres)") ) +// TestLightningNetworkDaemon performs a series of integration tests amongst a +// programmatically driven network of lnd nodes. +func TestLightningNetworkDaemon(t *testing.T) { + // If no tests are registered, then we can exit early. + if len(allTestCases) == 0 { + t.Skip("integration tests not selected with flag 'rpctest'") + } + + // Get the test cases to be run in this tranche. + testCases, trancheIndex, trancheOffset := getTestCaseSplitTranche() + lntest.ApplyPortOffset(uint32(trancheIndex) * 1000) + + // Create a simple fee service. + feeService := lntemp.NewFeeService(t) + + // Get the binary path and setup the harness test. + binary := getLndBinary(t) + harnessTest := lntemp.SetupHarness( + t, binary, *dbBackendFlag, feeService, + ) + defer harnessTest.Stop() + + // Setup standby nodes, Alice and Bob, which will be alive and shared + // among all the test cases. + harnessTest.SetupStandbyNodes() + + // Run the subset of the test cases selected in this tranche. + for idx, testCase := range testCases { + testCase := testCase + name := fmt.Sprintf("tranche%02d/%02d-of-%d/%s/%s", + trancheIndex, trancheOffset+uint(idx)+1, + len(allTestCases), harnessTest.ChainBackendName(), + testCase.Name) + + success := t.Run(name, func(t1 *testing.T) { + // Create a separate harness test for the testcase to + // avoid overwriting the external harness test that is + // tied to the parent test. + ht := harnessTest.Subtest(t1) + + // TODO(yy): split log files. + cleanTestCaseName := strings.ReplaceAll( + testCase.Name, " ", "_", + ) + ht.SetTestName(cleanTestCaseName) + + logLine := fmt.Sprintf( + "STARTING ============ %v ============\n", + testCase.Name, + ) + + ht.Alice.AddToLogf(logLine) + ht.Bob.AddToLogf(logLine) + + ht.EnsureConnected(ht.Alice, ht.Bob) + + ht.RunTestCase(testCase) + }) + + // Stop at the first failure. Mimic behavior of original test + // framework. + if !success { + // Log failure time to help relate the lnd logs to the + // failure. + t.Logf("Failure time: %v", time.Now().Format( + "2006-01-02 15:04:05.000", + )) + break + } + } + + _, height := harnessTest.Miner.GetBestBlock() + t.Logf("=========> tests finished for tranche: %v, tested %d "+ + "cases, end height: %d\n", trancheIndex, len(testCases), height) +} + // getTestCaseSplitTranche returns the sub slice of the test cases that should // be run as the current split tranche as well as the index and slice offset of // the tranche. -func getTestCaseSplitTrancheOld() ([]*testCase, uint, uint) { +func getTestCaseSplitTranche() ([]*lntemp.TestCase, uint, uint) { numTranches := defaultSplitTranches if testCasesSplitTranches != nil { numTranches = *testCasesSplitTranches @@ -52,190 +158,40 @@ func getTestCaseSplitTrancheOld() ([]*testCase, uint, uint) { trancheEnd = numCases } - return allTestCases[trancheOffset:trancheEnd], threadID, trancheOffset + return allTestCases[trancheOffset:trancheEnd], threadID, + trancheOffset } -// TestLightningNetworkDaemon performs a series of integration tests amongst a -// programmatically driven network of lnd nodes. -func TestLightningNetworkDaemon(t *testing.T) { - if *tempTest { - t.Skip("Running new tests, old tests are skipped") +func getLndBinary(t *testing.T) string { + binary := itestLndBinary + lndExec := "" + if lndExecutable != nil && *lndExecutable != "" { + lndExec = *lndExecutable + } + if lndExec == "" && runtime.GOOS == "windows" { + // Windows (even in a bash like environment like git bash as on + // Travis) doesn't seem to like relative paths to exe files... + currentDir, err := os.Getwd() + require.NoError(t, err, "unable to get working directory") + + targetPath := filepath.Join(currentDir, "../../lnd-itest.exe") + binary, err = filepath.Abs(targetPath) + require.NoError(t, err, "unable to get absolute path") + } else if lndExec != "" { + binary = lndExec } - // If no tests are registered, then we can exit early. - if len(allTestCases) == 0 { - t.Skip("integration tests not selected with flag 'rpctest'") - } - - // Parse testing flags that influence our test execution. - logDir := lntest.GetLogDir() - require.NoError(t, os.MkdirAll(logDir, 0700)) - testCases, trancheIndex, trancheOffset := getTestCaseSplitTrancheOld() - lntest.ApplyPortOffset(uint32(trancheIndex) * 1000) + return binary +} +func init() { // Before we start any node, we need to make sure that any btcd node - // that is started through the RPC harness uses a unique port as well to - // avoid any port collisions. + // that is started through the RPC harness uses a unique port as well + // to avoid any port collisions. rpctest.ListenAddressGenerator = lntest.GenerateBtcdListenerAddresses - // Declare the network harness here to gain access to its - // 'OnTxAccepted' call back. - var lndHarness *lntest.NetworkHarness - - // Create an instance of the btcd's rpctest.Harness that will act as - // the miner for all tests. This will be used to fund the wallets of - // the nodes within the test network and to drive blockchain related - // events within the network. Revert the default setting of accepting - // non-standard transactions on simnet to reject them. Transactions on - // the lightning network should always be standard to get better - // guarantees of getting included in to blocks. - // - // We will also connect it to our chain backend. - miner, err := lntest.NewMiner() - require.NoError(t, err, "failed to create new miner") - defer func() { - require.NoError(t, miner.Stop(), "failed to stop miner") - }() - - // Start a chain backend. - chainBackend, cleanUp, err := lntest.NewBackend( - miner.P2PAddress(), harnessNetParams, - ) - require.NoError(t, err, "new backend") - defer func() { - require.NoError(t, cleanUp(), "cleanup") - }() - - // Before we start anything, we want to overwrite some of the connection - // settings to make the tests more robust. We might need to restart the - // miner while there are already blocks present, which will take a bit - // longer than the 1 second the default settings amount to. Doubling - // both values will give us retries up to 4 seconds. - miner.MaxConnRetries = rpctest.DefaultMaxConnectionRetries * 2 - miner.ConnectionRetryTimeout = rpctest.DefaultConnectionRetryTimeout * 2 - - // Set up miner and connect chain backend to it. - require.NoError(t, miner.SetUp(true, 50)) - require.NoError(t, miner.Client.NotifyNewTransactions(false)) - require.NoError(t, chainBackend.ConnectMiner(), "connect miner") - - // Parse database backend - var dbBackend lntest.DatabaseBackend - switch *dbBackendFlag { - case "bbolt": - dbBackend = lntest.BackendBbolt - - case "etcd": - dbBackend = lntest.BackendEtcd - - case "postgres": - dbBackend = lntest.BackendPostgres - - case "sqlite": - dbBackend = lntest.BackendSqlite - - default: - require.Fail(t, "unknown db backend") - } - - // Now we can set up our test harness (LND instance), with the chain - // backend we just created. - ht := newHarnessTest(t, nil) - binary := ht.getLndBinary() - lndHarness, err = lntest.NewNetworkHarness( - miner, chainBackend, binary, dbBackend, - ) - if err != nil { - ht.Fatalf("unable to create lightning network harness: %v", err) - } - defer lndHarness.Stop() - - // Spawn a new goroutine to watch for any fatal errors that any of the - // running lnd processes encounter. If an error occurs, then the test - // case should naturally as a result and we log the server error here to - // help debug. - go func() { - for { - select { - case err, more := <-lndHarness.ProcessErrors(): - if !more { - return - } - ht.Logf("lnd finished with error (stderr):\n%v", - err) - } - } - }() - - // Next mine enough blocks in order for segwit and the CSV package - // soft-fork to activate on SimNet. - numBlocks := harnessNetParams.MinerConfirmationWindow * 2 - if _, err := miner.Client.Generate(numBlocks); err != nil { - ht.Fatalf("unable to generate blocks: %v", err) - } - - // With the btcd harness created, we can now complete the - // initialization of the network. args - list of lnd arguments, - // example: "--debuglevel=debug" - // TODO(roasbeef): create master balanced channel with all the monies? - aliceBobArgs := []string{ - "--default-remote-max-htlcs=483", - "--dust-threshold=5000000", - } - - // Run the subset of the test cases selected in this tranche. - for idx, testCase := range testCases { - testCase := testCase - name := fmt.Sprintf("tranche%02d/%02d-of-%d/%s/%s", - trancheIndex, trancheOffset+uint(idx)+1, - len(allTestCases), chainBackend.Name(), testCase.name) - - success := t.Run(name, func(t1 *testing.T) { - cleanTestCaseName := strings.ReplaceAll( - testCase.name, " ", "_", - ) - - err = lndHarness.SetUp( - t1, cleanTestCaseName, aliceBobArgs, - ) - require.NoError(t1, - err, "unable to set up test lightning network", - ) - defer func() { - require.NoError(t1, lndHarness.TearDown()) - }() - - lndHarness.EnsureConnected( - t1, lndHarness.Alice, lndHarness.Bob, - ) - - logLine := fmt.Sprintf( - "STARTING ============ %v ============\n", - testCase.name, - ) - - lndHarness.Alice.AddToLogf(logLine) - lndHarness.Bob.AddToLogf(logLine) - - // Start every test with the default static fee estimate. - lndHarness.SetFeeEstimate(12500) - - // Create a separate harness test for the testcase to - // avoid overwriting the external harness test that is - // tied to the parent test. - ht := newHarnessTest(t1, lndHarness) - ht.RunTestCase(testCase) - }) - - // Stop at the first failure. Mimic behavior of original test - // framework. - if !success { - // Log failure time to help relate the lnd logs to the - // failure. - t.Logf("Failure time: %v", time.Now().Format( - "2006-01-02 15:04:05.000", - )) - break - } - } + // Swap out grpc's default logger with out fake logger which drops the + // statements on the floor. + fakeLogger := grpclog.NewLoggerV2(io.Discard, io.Discard, io.Discard) + grpclog.SetLoggerV2(fakeLogger) } diff --git a/lntest/itest/lnd_test_list_off_test.go b/lntest/itest/lnd_test_list_off_test.go deleted file mode 100644 index bf21584f3..000000000 --- a/lntest/itest/lnd_test_list_off_test.go +++ /dev/null @@ -1,6 +0,0 @@ -//go:build !rpctest -// +build !rpctest - -package itest - -var allTestCases = []*testCase{} diff --git a/lntest/itest/lnd_test_list_on_test.go b/lntest/itest/lnd_test_list_on_test.go deleted file mode 100644 index d760ec2ce..000000000 --- a/lntest/itest/lnd_test_list_on_test.go +++ /dev/null @@ -1,6 +0,0 @@ -//go:build rpctest -// +build rpctest - -package itest - -var allTestCases = []*testCase{} diff --git a/lntest/itest/temp_lnd_test.go b/lntest/itest/temp_lnd_test.go deleted file mode 100644 index 4b816b93b..000000000 --- a/lntest/itest/temp_lnd_test.go +++ /dev/null @@ -1,197 +0,0 @@ -package itest - -import ( - "flag" - "fmt" - "io" - "os" - "path/filepath" - "runtime" - "strings" - "testing" - "time" - - "github.com/btcsuite/btcd/integration/rpctest" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntest" - "github.com/stretchr/testify/require" - "google.golang.org/grpc/grpclog" -) - -const ( - // defaultSplitTranches is the default number of tranches we split the - // test cases into. - defaultSplitTranches uint = 1 - - // defaultRunTranche is the default index of the test cases tranche that - // we run. - defaultRunTranche uint = 0 -) - -var ( - // 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 - // specified as well to indicate which part should be run in the current - // invocation. - testCasesSplitTranches = flag.Uint( - "splittranches", defaultSplitTranches, "split the test cases "+ - "in this many tranches and run the tranche at "+ - "0-based index specified by the -runtranche flag", - ) - - // testCasesRunTranche is the 0-based index of the split test cases - // tranche to run in the current invocation. - testCasesRunTranche = flag.Uint( - "runtranche", defaultRunTranche, "run the tranche of the "+ - "split test cases with the given (0-based) index", - ) - - // dbBackendFlag specifies the backend to use. - dbBackendFlag = flag.String("dbbackend", "bbolt", "Database backend "+ - "(bbolt, etcd, postgres, sqlite)") -) - -// TestLightningNetworkDaemonTemp performs a series of integration tests -// amongst a programmatically driven network of lnd nodes. -func TestLightningNetworkDaemonTemp(t *testing.T) { - if !*tempTest { - t.Skip("Running old tests, new tests are skipped") - } - - // If no tests are registered, then we can exit early. - if len(allTestCasesTemp) == 0 { - t.Skip("integration tests not selected with flag 'rpctest'") - } - - // Get the test cases to be run in this tranche. - testCases, trancheIndex, trancheOffset := getTestCaseSplitTranche() - lntest.ApplyPortOffset(uint32(trancheIndex) * 1000) - - // Create a simple fee service. - feeService := lntemp.NewFeeService(t) - - // Get the binary path and setup the harness test. - binary := getLndBinary(t) - harnessTest := lntemp.SetupHarness( - t, binary, *dbBackendFlag, feeService, - ) - defer harnessTest.Stop() - - // Setup standby nodes, Alice and Bob, which will be alive and shared - // among all the test cases. - harnessTest.SetupStandbyNodes() - - // Run the subset of the test cases selected in this tranche. - for idx, testCase := range testCases { - testCase := testCase - name := fmt.Sprintf("tranche%02d/%02d-of-%d/%s/%s", - trancheIndex, trancheOffset+uint(idx)+1, - len(allTestCases), harnessTest.ChainBackendName(), - testCase.Name) - - success := t.Run(name, func(t1 *testing.T) { - // Create a separate harness test for the testcase to - // avoid overwriting the external harness test that is - // tied to the parent test. - ht := harnessTest.Subtest(t1) - - // TODO(yy): split log files. - cleanTestCaseName := strings.ReplaceAll( - testCase.Name, " ", "_", - ) - ht.SetTestName(cleanTestCaseName) - - logLine := fmt.Sprintf( - "STARTING ============ %v ============\n", - testCase.Name, - ) - - ht.Alice.AddToLogf(logLine) - ht.Bob.AddToLogf(logLine) - - ht.EnsureConnected(ht.Alice, ht.Bob) - - ht.RunTestCase(testCase) - }) - - // Stop at the first failure. Mimic behavior of original test - // framework. - if !success { - // Log failure time to help relate the lnd logs to the - // failure. - t.Logf("Failure time: %v", time.Now().Format( - "2006-01-02 15:04:05.000", - )) - break - } - } -} - -// getTestCaseSplitTranche returns the sub slice of the test cases that should -// be run as the current split tranche as well as the index and slice offset of -// the tranche. -func getTestCaseSplitTranche() ([]*lntemp.TestCase, uint, uint) { - numTranches := defaultSplitTranches - if testCasesSplitTranches != nil { - numTranches = *testCasesSplitTranches - } - runTranche := defaultRunTranche - if testCasesRunTranche != nil { - runTranche = *testCasesRunTranche - } - - // There's a special flake-hunt mode where we run the same test multiple - // times in parallel. In that case the tranche index is equal to the - // thread ID, but we need to actually run all tests for the regex - // selection to work. - threadID := runTranche - if numTranches == 1 { - runTranche = 0 - } - - numCases := uint(len(allTestCasesTemp)) - testsPerTranche := numCases / numTranches - trancheOffset := runTranche * testsPerTranche - trancheEnd := trancheOffset + testsPerTranche - if trancheEnd > numCases || runTranche == numTranches-1 { - trancheEnd = numCases - } - - return allTestCasesTemp[trancheOffset:trancheEnd], threadID, - trancheOffset -} - -func getLndBinary(t *testing.T) string { - binary := itestLndBinary - lndExec := "" - if lndExecutable != nil && *lndExecutable != "" { - lndExec = *lndExecutable - } - if lndExec == "" && runtime.GOOS == "windows" { - // Windows (even in a bash like environment like git bash as on - // Travis) doesn't seem to like relative paths to exe files... - currentDir, err := os.Getwd() - require.NoError(t, err, "unable to get working directory") - - targetPath := filepath.Join(currentDir, "../../lnd-itest.exe") - binary, err = filepath.Abs(targetPath) - require.NoError(t, err, "unable to get absolute path") - } else if lndExec != "" { - binary = lndExec - } - - return binary -} - -func init() { - // Before we start any node, we need to make sure that any btcd node - // that is started through the RPC harness uses a unique port as well - // to avoid any port collisions. - rpctest.ListenAddressGenerator = lntest.GenerateBtcdListenerAddresses - - // Swap out grpc's default logger with out fake logger which drops the - // statements on the floor. - fakeLogger := grpclog.NewLoggerV2(io.Discard, io.Discard, io.Discard) - grpclog.SetLoggerV2(fakeLogger) -} diff --git a/make/testing_flags.mk b/make/testing_flags.mk index dda519925..d18a04881 100644 --- a/make/testing_flags.mk +++ b/make/testing_flags.mk @@ -9,11 +9,6 @@ NUM_ITEST_TRANCHES = 4 ITEST_PARALLELISM = $(NUM_ITEST_TRANCHES) POSTGRES_START_DELAY = 5 -# Build temp tests only. TODO(yy): remove. -ifneq ($(temptest),) -ITEST_FLAGS += -temptest=$(temptest) -endif - # If rpc option is set also add all extra RPC tags to DEV_TAGS ifneq ($(with-rpc),) DEV_TAGS += $(RPC_TAGS) From 0bc86a3b4bb49b7c5e57152438e19c61edca2e9d Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Thu, 11 Aug 2022 19:39:40 +0800 Subject: [PATCH 04/45] multi: move `itest` out of `lntest` This commit moves all the test cases living in `itest` out of `lntest`, further making `lntest` an independent package for general testing. --- .gitignore | 12 ++++++------ Makefile | 16 ++++++++-------- docs/code_contribution_guidelines.md | 2 +- docs/musig2.md | 6 +++--- {lntest/itest => itest}/assertions.go | 0 {lntest/itest => itest}/list_off_test.go | 0 {lntest/itest => itest}/list_on_test.go | 0 {lntest/itest => itest}/lnd_amp_test.go | 0 .../itest => itest}/lnd_channel_backup_test.go | 0 .../itest => itest}/lnd_channel_balance_test.go | 0 .../lnd_channel_force_close_test.go | 0 .../itest => itest}/lnd_channel_graph_test.go | 0 .../itest => itest}/lnd_channel_policy_test.go | 0 {lntest/itest => itest}/lnd_custom_message.go | 0 .../itest => itest}/lnd_etcd_failover_test.go | 0 .../lnd_forward_interceptor_test.go | 0 {lntest/itest => itest}/lnd_funding_test.go | 0 .../lnd_hold_invoice_force_test.go | 0 .../itest => itest}/lnd_hold_persistence_test.go | 0 {lntest/itest => itest}/lnd_macaroons_test.go | 0 .../itest => itest}/lnd_max_channel_size_test.go | 0 {lntest/itest => itest}/lnd_max_htlcs_test.go | 0 {lntest/itest => itest}/lnd_misc_test.go | 0 {lntest/itest => itest}/lnd_mpp_test.go | 0 .../lnd_multi-hop-error-propagation_test.go | 0 .../lnd_multi-hop-payments_test.go | 0 {lntest/itest => itest}/lnd_multi-hop_test.go | 0 {lntest/itest => itest}/lnd_network_test.go | 0 {lntest/itest => itest}/lnd_neutrino_test.go | 0 .../lnd_no_etcd_dummy_failover_test.go | 0 {lntest/itest => itest}/lnd_nonstd_sweep_test.go | 0 {lntest/itest => itest}/lnd_onchain_test.go | 0 {lntest/itest => itest}/lnd_open_channel_test.go | 0 {lntest/itest => itest}/lnd_payment_test.go | 0 {lntest/itest => itest}/lnd_psbt_test.go | 0 {lntest/itest => itest}/lnd_recovery_test.go | 0 .../itest => itest}/lnd_remote_signer_test.go | 0 {lntest/itest => itest}/lnd_res_handoff_test.go | 0 {lntest/itest => itest}/lnd_rest_api_test.go | 0 {lntest/itest => itest}/lnd_revocation_test.go | 0 {lntest/itest => itest}/lnd_routing_test.go | 0 .../lnd_rpc_middleware_interceptor_test.go | 0 .../lnd_send_multi_path_payment_test.go | 0 {lntest/itest => itest}/lnd_signer_test.go | 0 .../lnd_single_hop_invoice_test.go | 0 {lntest/itest => itest}/lnd_switch_test.go | 0 {lntest/itest => itest}/lnd_taproot_test.go | 0 {lntest/itest => itest}/lnd_test.go | 0 .../itest => itest}/lnd_trackpayments_test.go | 0 .../itest => itest}/lnd_wallet_import_test.go | 0 {lntest/itest => itest}/lnd_wipe_fwdpkgs_test.go | 0 .../itest => itest}/lnd_wumbo_channels_test.go | 0 {lntest/itest => itest}/lnd_zero_conf_test.go | 0 {lntest/itest => itest}/log_check_errors.sh | 0 {lntest/itest => itest}/log_error_whitelist.txt | 0 {lntest/itest => itest}/log_substitutions.txt | 0 {lntest/itest => itest}/test_harness.go | 0 {lntest/itest => itest}/utils.go | 0 scripts/itest_part.sh | 2 +- 59 files changed, 19 insertions(+), 19 deletions(-) rename {lntest/itest => itest}/assertions.go (100%) rename {lntest/itest => itest}/list_off_test.go (100%) rename {lntest/itest => itest}/list_on_test.go (100%) rename {lntest/itest => itest}/lnd_amp_test.go (100%) rename {lntest/itest => itest}/lnd_channel_backup_test.go (100%) rename {lntest/itest => itest}/lnd_channel_balance_test.go (100%) rename {lntest/itest => itest}/lnd_channel_force_close_test.go (100%) rename {lntest/itest => itest}/lnd_channel_graph_test.go (100%) rename {lntest/itest => itest}/lnd_channel_policy_test.go (100%) rename {lntest/itest => itest}/lnd_custom_message.go (100%) rename {lntest/itest => itest}/lnd_etcd_failover_test.go (100%) rename {lntest/itest => itest}/lnd_forward_interceptor_test.go (100%) rename {lntest/itest => itest}/lnd_funding_test.go (100%) rename {lntest/itest => itest}/lnd_hold_invoice_force_test.go (100%) rename {lntest/itest => itest}/lnd_hold_persistence_test.go (100%) rename {lntest/itest => itest}/lnd_macaroons_test.go (100%) rename {lntest/itest => itest}/lnd_max_channel_size_test.go (100%) rename {lntest/itest => itest}/lnd_max_htlcs_test.go (100%) rename {lntest/itest => itest}/lnd_misc_test.go (100%) rename {lntest/itest => itest}/lnd_mpp_test.go (100%) rename {lntest/itest => itest}/lnd_multi-hop-error-propagation_test.go (100%) rename {lntest/itest => itest}/lnd_multi-hop-payments_test.go (100%) rename {lntest/itest => itest}/lnd_multi-hop_test.go (100%) rename {lntest/itest => itest}/lnd_network_test.go (100%) rename {lntest/itest => itest}/lnd_neutrino_test.go (100%) rename {lntest/itest => itest}/lnd_no_etcd_dummy_failover_test.go (100%) rename {lntest/itest => itest}/lnd_nonstd_sweep_test.go (100%) rename {lntest/itest => itest}/lnd_onchain_test.go (100%) rename {lntest/itest => itest}/lnd_open_channel_test.go (100%) rename {lntest/itest => itest}/lnd_payment_test.go (100%) rename {lntest/itest => itest}/lnd_psbt_test.go (100%) rename {lntest/itest => itest}/lnd_recovery_test.go (100%) rename {lntest/itest => itest}/lnd_remote_signer_test.go (100%) rename {lntest/itest => itest}/lnd_res_handoff_test.go (100%) rename {lntest/itest => itest}/lnd_rest_api_test.go (100%) rename {lntest/itest => itest}/lnd_revocation_test.go (100%) rename {lntest/itest => itest}/lnd_routing_test.go (100%) rename {lntest/itest => itest}/lnd_rpc_middleware_interceptor_test.go (100%) rename {lntest/itest => itest}/lnd_send_multi_path_payment_test.go (100%) rename {lntest/itest => itest}/lnd_signer_test.go (100%) rename {lntest/itest => itest}/lnd_single_hop_invoice_test.go (100%) rename {lntest/itest => itest}/lnd_switch_test.go (100%) rename {lntest/itest => itest}/lnd_taproot_test.go (100%) rename {lntest/itest => itest}/lnd_test.go (100%) rename {lntest/itest => itest}/lnd_trackpayments_test.go (100%) rename {lntest/itest => itest}/lnd_wallet_import_test.go (100%) rename {lntest/itest => itest}/lnd_wipe_fwdpkgs_test.go (100%) rename {lntest/itest => itest}/lnd_wumbo_channels_test.go (100%) rename {lntest/itest => itest}/lnd_zero_conf_test.go (100%) rename {lntest/itest => itest}/log_check_errors.sh (100%) rename {lntest/itest => itest}/log_error_whitelist.txt (100%) rename {lntest/itest => itest}/log_substitutions.txt (100%) rename {lntest/itest => itest}/test_harness.go (100%) rename {lntest/itest => itest}/utils.go (100%) diff --git a/.gitignore b/.gitignore index 106af84c2..16d33c142 100644 --- a/.gitignore +++ b/.gitignore @@ -32,12 +32,12 @@ _testmain.go /lncli-itest # Integration test log files -lntest/itest/*.log -lntest/itest/.backendlogs -lntest/itest/.minerlogs -lntest/itest/lnd-itest -lntest/itest/btcd-itest -lntest/itest/.logs-* +itest/*.log +itest/.backendlogs +itest/.minerlogs +itest/lnd-itest +itest/btcd-itest +itest/.logs-* cmd/cmd *.key diff --git a/Makefile b/Makefile index 174fe0f03..9e4b174dc 100644 --- a/Makefile +++ b/Makefile @@ -93,19 +93,19 @@ build: build-itest: @$(call print, "Building itest btcd and lnd.") - CGO_ENABLED=0 $(GOBUILD) -tags="rpctest" -o lntest/itest/btcd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(BTCD_PKG) - CGO_ENABLED=0 $(GOBUILD) -tags="$(ITEST_TAGS)" -o lntest/itest/lnd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(PKG)/cmd/lnd + CGO_ENABLED=0 $(GOBUILD) -tags="rpctest" -o itest/btcd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(BTCD_PKG) + CGO_ENABLED=0 $(GOBUILD) -tags="$(ITEST_TAGS)" -o itest/lnd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(PKG)/cmd/lnd @$(call print, "Building itest binary for ${backend} backend.") - CGO_ENABLED=0 $(GOTEST) -v ./lntest/itest -tags="$(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)" -c -o lntest/itest/itest.test$(EXEC_SUFFIX) + CGO_ENABLED=0 $(GOTEST) -v ./itest -tags="$(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)" -c -o itest/itest.test$(EXEC_SUFFIX) build-itest-race: @$(call print, "Building itest btcd and lnd with race detector.") - CGO_ENABLED=0 $(GOBUILD) -tags="rpctest" -o lntest/itest/btcd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(BTCD_PKG) - CGO_ENABLED=1 $(GOBUILD) -race -tags="$(ITEST_TAGS)" -o lntest/itest/lnd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(PKG)/cmd/lnd + CGO_ENABLED=0 $(GOBUILD) -tags="rpctest" -o itest/btcd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(BTCD_PKG) + CGO_ENABLED=1 $(GOBUILD) -race -tags="$(ITEST_TAGS)" -o itest/lnd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(PKG)/cmd/lnd @$(call print, "Building itest binary for ${backend} backend.") - CGO_ENABLED=0 $(GOTEST) -v ./lntest/itest -tags="$(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)" -c -o lntest/itest/itest.test$(EXEC_SUFFIX) + CGO_ENABLED=0 $(GOTEST) -v ./itest -tags="$(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)" -c -o itest/itest.test$(EXEC_SUFFIX) install: @$(call print, "Installing lnd and lncli.") @@ -164,7 +164,7 @@ endif itest-only: db-instance @$(call print, "Running integration tests with ${backend} backend.") - rm -rf lntest/itest/*.log lntest/itest/.logs-*; date + rm -rf itest/*.log itest/.logs-*; date EXEC_SUFFIX=$(EXEC_SUFFIX) scripts/itest_part.sh 0 1 $(TEST_FLAGS) $(ITEST_FLAGS) itest: build-itest itest-only @@ -173,7 +173,7 @@ itest-race: build-itest-race itest-only itest-parallel: build-itest db-instance @$(call print, "Running tests") - rm -rf lntest/itest/*.log lntest/itest/.logs-*; date + rm -rf itest/*.log itest/.logs-*; date EXEC_SUFFIX=$(EXEC_SUFFIX) echo "$$(seq 0 $$(expr $(ITEST_PARALLELISM) - 1))" | xargs -P $(ITEST_PARALLELISM) -n 1 -I {} scripts/itest_part.sh {} $(NUM_ITEST_TRANCHES) $(TEST_FLAGS) $(ITEST_FLAGS) itest-clean: diff --git a/docs/code_contribution_guidelines.md b/docs/code_contribution_guidelines.md index 8a13d371d..79f03df65 100644 --- a/docs/code_contribution_guidelines.md +++ b/docs/code_contribution_guidelines.md @@ -155,7 +155,7 @@ A quick summary of test practices follows: or RPC's will need to be accompanied by integration tests which use the [`networkHarness`framework](https://github.com/lightningnetwork/lnd/blob/master/lntest/harness.go) contained within `lnd`. For example integration tests, see - [`lnd_test.go`](https://github.com/lightningnetwork/lnd/blob/master/lntest/itest/lnd_test.go). + [`lnd_test.go`](https://github.com/lightningnetwork/lnd/blob/master/itest/lnd_test.go). - The itest log files are automatically scanned for `[ERR]` lines. There shouldn't be any of those in the logs, see [Use of Log Levels](#use-of-log-levels). diff --git a/docs/musig2.md b/docs/musig2.md index e46398832..555dfd7ec 100644 --- a/docs/musig2.md +++ b/docs/musig2.md @@ -44,7 +44,7 @@ to test the RPCs and to showcase the different use cases. ### 3-of-3 Taproot key spend path (BIP-0086) See `testTaprootMuSig2KeySpendBip86` in -[`lntest/itest/lnd_taproot_test.go`](../lntest/itest/lnd_taproot_test.go) to see +[`itest/lnd_taproot_test.go`](../itest/lnd_taproot_test.go) to see the full code. This example uses combines the public keys of 3 participants into a shared @@ -73,7 +73,7 @@ the `MuSig2CreateSession` RPC call: ### 3-of-3 Taproot key spend path with root hash commitment See `testTaprootMuSig2KeySpendRootHash` in -[`lntest/itest/lnd_taproot_test.go`](../lntest/itest/lnd_taproot_test.go) to see +[`itest/lnd_taproot_test.go`](../itest/lnd_taproot_test.go) to see the full code. This is very similar to the above example but with the main difference that the @@ -101,7 +101,7 @@ the `MuSig2CreateSession` RPC call: ### 3-of-3 `OP_CHECKSIG` in Taproot script spend path See `testTaprootMuSig2CombinedLeafKeySpend` in -[`lntest/itest/lnd_taproot_test.go`](../lntest/itest/lnd_taproot_test.go) to see +[`itest/lnd_taproot_test.go`](../itest/lnd_taproot_test.go) to see the full code. This example is definitely the most involved one. To be able to use a MuSig2 diff --git a/lntest/itest/assertions.go b/itest/assertions.go similarity index 100% rename from lntest/itest/assertions.go rename to itest/assertions.go diff --git a/lntest/itest/list_off_test.go b/itest/list_off_test.go similarity index 100% rename from lntest/itest/list_off_test.go rename to itest/list_off_test.go diff --git a/lntest/itest/list_on_test.go b/itest/list_on_test.go similarity index 100% rename from lntest/itest/list_on_test.go rename to itest/list_on_test.go diff --git a/lntest/itest/lnd_amp_test.go b/itest/lnd_amp_test.go similarity index 100% rename from lntest/itest/lnd_amp_test.go rename to itest/lnd_amp_test.go diff --git a/lntest/itest/lnd_channel_backup_test.go b/itest/lnd_channel_backup_test.go similarity index 100% rename from lntest/itest/lnd_channel_backup_test.go rename to itest/lnd_channel_backup_test.go diff --git a/lntest/itest/lnd_channel_balance_test.go b/itest/lnd_channel_balance_test.go similarity index 100% rename from lntest/itest/lnd_channel_balance_test.go rename to itest/lnd_channel_balance_test.go diff --git a/lntest/itest/lnd_channel_force_close_test.go b/itest/lnd_channel_force_close_test.go similarity index 100% rename from lntest/itest/lnd_channel_force_close_test.go rename to itest/lnd_channel_force_close_test.go diff --git a/lntest/itest/lnd_channel_graph_test.go b/itest/lnd_channel_graph_test.go similarity index 100% rename from lntest/itest/lnd_channel_graph_test.go rename to itest/lnd_channel_graph_test.go diff --git a/lntest/itest/lnd_channel_policy_test.go b/itest/lnd_channel_policy_test.go similarity index 100% rename from lntest/itest/lnd_channel_policy_test.go rename to itest/lnd_channel_policy_test.go diff --git a/lntest/itest/lnd_custom_message.go b/itest/lnd_custom_message.go similarity index 100% rename from lntest/itest/lnd_custom_message.go rename to itest/lnd_custom_message.go diff --git a/lntest/itest/lnd_etcd_failover_test.go b/itest/lnd_etcd_failover_test.go similarity index 100% rename from lntest/itest/lnd_etcd_failover_test.go rename to itest/lnd_etcd_failover_test.go diff --git a/lntest/itest/lnd_forward_interceptor_test.go b/itest/lnd_forward_interceptor_test.go similarity index 100% rename from lntest/itest/lnd_forward_interceptor_test.go rename to itest/lnd_forward_interceptor_test.go diff --git a/lntest/itest/lnd_funding_test.go b/itest/lnd_funding_test.go similarity index 100% rename from lntest/itest/lnd_funding_test.go rename to itest/lnd_funding_test.go diff --git a/lntest/itest/lnd_hold_invoice_force_test.go b/itest/lnd_hold_invoice_force_test.go similarity index 100% rename from lntest/itest/lnd_hold_invoice_force_test.go rename to itest/lnd_hold_invoice_force_test.go diff --git a/lntest/itest/lnd_hold_persistence_test.go b/itest/lnd_hold_persistence_test.go similarity index 100% rename from lntest/itest/lnd_hold_persistence_test.go rename to itest/lnd_hold_persistence_test.go diff --git a/lntest/itest/lnd_macaroons_test.go b/itest/lnd_macaroons_test.go similarity index 100% rename from lntest/itest/lnd_macaroons_test.go rename to itest/lnd_macaroons_test.go diff --git a/lntest/itest/lnd_max_channel_size_test.go b/itest/lnd_max_channel_size_test.go similarity index 100% rename from lntest/itest/lnd_max_channel_size_test.go rename to itest/lnd_max_channel_size_test.go diff --git a/lntest/itest/lnd_max_htlcs_test.go b/itest/lnd_max_htlcs_test.go similarity index 100% rename from lntest/itest/lnd_max_htlcs_test.go rename to itest/lnd_max_htlcs_test.go diff --git a/lntest/itest/lnd_misc_test.go b/itest/lnd_misc_test.go similarity index 100% rename from lntest/itest/lnd_misc_test.go rename to itest/lnd_misc_test.go diff --git a/lntest/itest/lnd_mpp_test.go b/itest/lnd_mpp_test.go similarity index 100% rename from lntest/itest/lnd_mpp_test.go rename to itest/lnd_mpp_test.go diff --git a/lntest/itest/lnd_multi-hop-error-propagation_test.go b/itest/lnd_multi-hop-error-propagation_test.go similarity index 100% rename from lntest/itest/lnd_multi-hop-error-propagation_test.go rename to itest/lnd_multi-hop-error-propagation_test.go diff --git a/lntest/itest/lnd_multi-hop-payments_test.go b/itest/lnd_multi-hop-payments_test.go similarity index 100% rename from lntest/itest/lnd_multi-hop-payments_test.go rename to itest/lnd_multi-hop-payments_test.go diff --git a/lntest/itest/lnd_multi-hop_test.go b/itest/lnd_multi-hop_test.go similarity index 100% rename from lntest/itest/lnd_multi-hop_test.go rename to itest/lnd_multi-hop_test.go diff --git a/lntest/itest/lnd_network_test.go b/itest/lnd_network_test.go similarity index 100% rename from lntest/itest/lnd_network_test.go rename to itest/lnd_network_test.go diff --git a/lntest/itest/lnd_neutrino_test.go b/itest/lnd_neutrino_test.go similarity index 100% rename from lntest/itest/lnd_neutrino_test.go rename to itest/lnd_neutrino_test.go diff --git a/lntest/itest/lnd_no_etcd_dummy_failover_test.go b/itest/lnd_no_etcd_dummy_failover_test.go similarity index 100% rename from lntest/itest/lnd_no_etcd_dummy_failover_test.go rename to itest/lnd_no_etcd_dummy_failover_test.go diff --git a/lntest/itest/lnd_nonstd_sweep_test.go b/itest/lnd_nonstd_sweep_test.go similarity index 100% rename from lntest/itest/lnd_nonstd_sweep_test.go rename to itest/lnd_nonstd_sweep_test.go diff --git a/lntest/itest/lnd_onchain_test.go b/itest/lnd_onchain_test.go similarity index 100% rename from lntest/itest/lnd_onchain_test.go rename to itest/lnd_onchain_test.go diff --git a/lntest/itest/lnd_open_channel_test.go b/itest/lnd_open_channel_test.go similarity index 100% rename from lntest/itest/lnd_open_channel_test.go rename to itest/lnd_open_channel_test.go diff --git a/lntest/itest/lnd_payment_test.go b/itest/lnd_payment_test.go similarity index 100% rename from lntest/itest/lnd_payment_test.go rename to itest/lnd_payment_test.go diff --git a/lntest/itest/lnd_psbt_test.go b/itest/lnd_psbt_test.go similarity index 100% rename from lntest/itest/lnd_psbt_test.go rename to itest/lnd_psbt_test.go diff --git a/lntest/itest/lnd_recovery_test.go b/itest/lnd_recovery_test.go similarity index 100% rename from lntest/itest/lnd_recovery_test.go rename to itest/lnd_recovery_test.go diff --git a/lntest/itest/lnd_remote_signer_test.go b/itest/lnd_remote_signer_test.go similarity index 100% rename from lntest/itest/lnd_remote_signer_test.go rename to itest/lnd_remote_signer_test.go diff --git a/lntest/itest/lnd_res_handoff_test.go b/itest/lnd_res_handoff_test.go similarity index 100% rename from lntest/itest/lnd_res_handoff_test.go rename to itest/lnd_res_handoff_test.go diff --git a/lntest/itest/lnd_rest_api_test.go b/itest/lnd_rest_api_test.go similarity index 100% rename from lntest/itest/lnd_rest_api_test.go rename to itest/lnd_rest_api_test.go diff --git a/lntest/itest/lnd_revocation_test.go b/itest/lnd_revocation_test.go similarity index 100% rename from lntest/itest/lnd_revocation_test.go rename to itest/lnd_revocation_test.go diff --git a/lntest/itest/lnd_routing_test.go b/itest/lnd_routing_test.go similarity index 100% rename from lntest/itest/lnd_routing_test.go rename to itest/lnd_routing_test.go diff --git a/lntest/itest/lnd_rpc_middleware_interceptor_test.go b/itest/lnd_rpc_middleware_interceptor_test.go similarity index 100% rename from lntest/itest/lnd_rpc_middleware_interceptor_test.go rename to itest/lnd_rpc_middleware_interceptor_test.go diff --git a/lntest/itest/lnd_send_multi_path_payment_test.go b/itest/lnd_send_multi_path_payment_test.go similarity index 100% rename from lntest/itest/lnd_send_multi_path_payment_test.go rename to itest/lnd_send_multi_path_payment_test.go diff --git a/lntest/itest/lnd_signer_test.go b/itest/lnd_signer_test.go similarity index 100% rename from lntest/itest/lnd_signer_test.go rename to itest/lnd_signer_test.go diff --git a/lntest/itest/lnd_single_hop_invoice_test.go b/itest/lnd_single_hop_invoice_test.go similarity index 100% rename from lntest/itest/lnd_single_hop_invoice_test.go rename to itest/lnd_single_hop_invoice_test.go diff --git a/lntest/itest/lnd_switch_test.go b/itest/lnd_switch_test.go similarity index 100% rename from lntest/itest/lnd_switch_test.go rename to itest/lnd_switch_test.go diff --git a/lntest/itest/lnd_taproot_test.go b/itest/lnd_taproot_test.go similarity index 100% rename from lntest/itest/lnd_taproot_test.go rename to itest/lnd_taproot_test.go diff --git a/lntest/itest/lnd_test.go b/itest/lnd_test.go similarity index 100% rename from lntest/itest/lnd_test.go rename to itest/lnd_test.go diff --git a/lntest/itest/lnd_trackpayments_test.go b/itest/lnd_trackpayments_test.go similarity index 100% rename from lntest/itest/lnd_trackpayments_test.go rename to itest/lnd_trackpayments_test.go diff --git a/lntest/itest/lnd_wallet_import_test.go b/itest/lnd_wallet_import_test.go similarity index 100% rename from lntest/itest/lnd_wallet_import_test.go rename to itest/lnd_wallet_import_test.go diff --git a/lntest/itest/lnd_wipe_fwdpkgs_test.go b/itest/lnd_wipe_fwdpkgs_test.go similarity index 100% rename from lntest/itest/lnd_wipe_fwdpkgs_test.go rename to itest/lnd_wipe_fwdpkgs_test.go diff --git a/lntest/itest/lnd_wumbo_channels_test.go b/itest/lnd_wumbo_channels_test.go similarity index 100% rename from lntest/itest/lnd_wumbo_channels_test.go rename to itest/lnd_wumbo_channels_test.go diff --git a/lntest/itest/lnd_zero_conf_test.go b/itest/lnd_zero_conf_test.go similarity index 100% rename from lntest/itest/lnd_zero_conf_test.go rename to itest/lnd_zero_conf_test.go diff --git a/lntest/itest/log_check_errors.sh b/itest/log_check_errors.sh similarity index 100% rename from lntest/itest/log_check_errors.sh rename to itest/log_check_errors.sh diff --git a/lntest/itest/log_error_whitelist.txt b/itest/log_error_whitelist.txt similarity index 100% rename from lntest/itest/log_error_whitelist.txt rename to itest/log_error_whitelist.txt diff --git a/lntest/itest/log_substitutions.txt b/itest/log_substitutions.txt similarity index 100% rename from lntest/itest/log_substitutions.txt rename to itest/log_substitutions.txt diff --git a/lntest/itest/test_harness.go b/itest/test_harness.go similarity index 100% rename from lntest/itest/test_harness.go rename to itest/test_harness.go diff --git a/lntest/itest/utils.go b/itest/utils.go similarity index 100% rename from lntest/itest/utils.go rename to itest/utils.go diff --git a/scripts/itest_part.sh b/scripts/itest_part.sh index c086c9af0..37a8a4659 100755 --- a/scripts/itest_part.sh +++ b/scripts/itest_part.sh @@ -1,7 +1,7 @@ #!/bin/bash # Let's work with absolute paths only, we run in the itest directory itself. -WORKDIR=$(pwd)/lntest/itest +WORKDIR=$(pwd)/itest TRANCHE=$1 NUM_TRANCHES=$2 From 106fbeae859b471f11eb35c2792eb9d2db59c6b4 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 12 Aug 2022 11:19:18 +0800 Subject: [PATCH 05/45] multi: move timeouts into package `wait` This commit moves the definition of timeout values into package `wait`, preparing the incoming merging of `lntemp` and `lntest`. --- itest/lnd_payment_test.go | 5 ++--- itest/test_harness.go | 6 +++--- lntemp/harness.go | 2 +- lntemp/harness_miner.go | 6 +++--- lntemp/node/config.go | 3 ++- lntemp/node/harness_node.go | 16 ++++++++-------- lntemp/node/watcher.go | 15 +++++---------- lntemp/rpc/harness_rpc.go | 5 ++--- lntest/harness_node.go | 7 ++++++- lntest/{ => wait}/timeouts.go | 2 +- lntest/{ => wait}/timeouts_darwin.go | 2 +- lntest/{ => wait}/timeouts_remote_db.go | 2 +- 12 files changed, 35 insertions(+), 36 deletions(-) rename lntest/{ => wait}/timeouts.go (98%) rename lntest/{ => wait}/timeouts_darwin.go (98%) rename lntest/{ => wait}/timeouts_remote_db.go (98%) diff --git a/itest/lnd_payment_test.go b/itest/lnd_payment_test.go index e9005e6e9..754c7e937 100644 --- a/itest/lnd_payment_test.go +++ b/itest/lnd_payment_test.go @@ -12,7 +12,6 @@ import ( "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lntemp" "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) @@ -272,7 +271,7 @@ func runAsyncPayments(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode) { settled := make(chan struct{}) defer close(settled) - timeout := lntest.AsyncBenchmarkTimeout * 2 + timeout := wait.AsyncBenchmarkTimeout * 2 for i := 0; i < numInvoices; i++ { payReq := bobPayReqs[i] go func() { @@ -376,7 +375,7 @@ func testBidirectionalAsyncPayments(ht *lntemp.HarnessTest) { settled := make(chan struct{}) defer close(settled) - timeout := lntest.AsyncBenchmarkTimeout * 4 + timeout := wait.AsyncBenchmarkTimeout * 4 send := func(node *node.HarnessNode, payReq string) { req := &routerrpc.SendPaymentRequest{ PaymentRequest: payReq, diff --git a/itest/test_harness.go b/itest/test_harness.go index a5450026f..88f11ba08 100644 --- a/itest/test_harness.go +++ b/itest/test_harness.go @@ -38,9 +38,9 @@ var ( const ( testFeeBase = 1e+6 defaultCSV = lntest.DefaultCSV - defaultTimeout = lntest.DefaultTimeout - minerMempoolTimeout = lntest.MinerMempoolTimeout - channelCloseTimeout = lntest.ChannelCloseTimeout + defaultTimeout = wait.DefaultTimeout + minerMempoolTimeout = wait.MinerMempoolTimeout + channelCloseTimeout = wait.ChannelCloseTimeout itestLndBinary = "../../lnd-itest" anchorSize = 330 noFeeLimitMsat = math.MaxInt64 diff --git a/lntemp/harness.go b/lntemp/harness.go index 781a5ccf3..cc11ec9ae 100644 --- a/lntemp/harness.go +++ b/lntemp/harness.go @@ -1686,7 +1686,7 @@ func (h *HarnessTest) OpenMultiChannelsAsync( case cp := <-r.result: channelPoints = append(channelPoints, cp) - case <-time.After(lntest.ChannelOpenTimeout): + case <-time.After(wait.ChannelOpenTimeout): require.Failf(h, "timeout", "wait channel point "+ "timeout for channel %s=>%s", r.Local.Name(), r.Remote.Name()) diff --git a/lntemp/harness_miner.go b/lntemp/harness_miner.go index 9c9b758f2..9568a2c86 100644 --- a/lntemp/harness_miner.go +++ b/lntemp/harness_miner.go @@ -198,7 +198,7 @@ func (h *HarnessMiner) AssertNumTxsInMempool(n int) []*chainhash.Hash { return fmt.Errorf("want %v, got %v in mempool: %v", n, len(mem), mem) - }, lntest.MinerMempoolTimeout) + }, wait.MinerMempoolTimeout) require.NoError(h, err, "assert tx in mempool timeout") return mem @@ -286,7 +286,7 @@ func (h *HarnessMiner) AssertTxInMempool(txid *chainhash.Hash) *wire.MsgTx { return fmt.Errorf("txid %v not found in mempool: %v", txid, mempool) - }, lntest.MinerMempoolTimeout) + }, wait.MinerMempoolTimeout) require.NoError(h, err, "timeout checking mempool") return msgTx @@ -377,7 +377,7 @@ func (h *HarnessMiner) AssertOutpointInMempool(op wire.OutPoint) *wire.MsgTx { } return fmt.Errorf("outpoint %v not found in mempool", op) - }, lntest.MinerMempoolTimeout) + }, wait.MinerMempoolTimeout) require.NoError(h, err, "timeout checking mempool") diff --git a/lntemp/node/config.go b/lntemp/node/config.go index 00b183354..ef00d1bfa 100644 --- a/lntemp/node/config.go +++ b/lntemp/node/config.go @@ -9,6 +9,7 @@ import ( "github.com/lightningnetwork/lnd/chanbackup" "github.com/lightningnetwork/lnd/kvdb/etcd" "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/wait" ) const ( @@ -228,7 +229,7 @@ func (cfg *BaseNodeConfig) GenArgs() []string { case lntest.BackendSqlite: args = append(args, "--db.backend=sqlite") args = append(args, fmt.Sprintf("--db.sqlite.busytimeout=%v", - lntest.SqliteBusyTimeout)) + wait.SqliteBusyTimeout)) } if cfg.FeeURL != "" { diff --git a/lntemp/node/harness_node.go b/lntemp/node/harness_node.go index 069d23ec8..c86e30af8 100644 --- a/lntemp/node/harness_node.go +++ b/lntemp/node/harness_node.go @@ -324,7 +324,7 @@ func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) ( hn.Cfg.TLSCertPath, "", ) return err - }, DefaultTimeout) + }, wait.DefaultTimeout) if err != nil { return nil, fmt.Errorf("error reading TLS cert: %v", err) } @@ -334,7 +334,7 @@ func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) ( grpc.WithTransportCredentials(tlsCreds), } - ctx, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) + ctx, cancel := context.WithTimeout(hn.runCtx, wait.DefaultTimeout) defer cancel() if mac == nil { @@ -354,7 +354,7 @@ func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) ( func (hn *HarnessNode) ConnectRPC() (*grpc.ClientConn, error) { // If we should use a macaroon, always take the admin macaroon as a // default. - mac, err := hn.ReadMacaroon(hn.Cfg.AdminMacPath, DefaultTimeout) + mac, err := hn.ReadMacaroon(hn.Cfg.AdminMacPath, wait.DefaultTimeout) if err != nil { return nil, err } @@ -540,7 +540,7 @@ func (hn *HarnessNode) waitTillServerState( for { select { - case <-time.After(lntest.NodeStartTimeout): + case <-time.After(wait.NodeStartTimeout): return fmt.Errorf("timeout waiting for server state") case err := <-errChan: return fmt.Errorf("receive server state err: %v", err) @@ -581,7 +581,7 @@ func (hn *HarnessNode) initLightningClient() error { "got err: %v", err) } - case <-time.After(DefaultTimeout): + case <-time.After(wait.DefaultTimeout): return fmt.Errorf("timeout creating topology client stream") } @@ -652,7 +652,7 @@ func (hn *HarnessNode) waitForProcessExit() { hn.printErrf("wait process exit got err: %v", err) break - case <-time.After(DefaultTimeout * 2): + case <-time.After(wait.DefaultTimeout * 2): hn.printErrf("timeout waiting for process to exit") } @@ -705,7 +705,7 @@ func (hn *HarnessNode) Stop() error { default: return nil } - }, DefaultTimeout) + }, wait.DefaultTimeout) if err != nil { return err } @@ -720,7 +720,7 @@ func (hn *HarnessNode) Stop() error { // If the goroutines fail to finish before timeout, we'll print // the error to console and continue. select { - case <-time.After(DefaultTimeout): + case <-time.After(wait.DefaultTimeout): hn.printErrf("timeout on wait group") case <-done: } diff --git a/lntemp/node/watcher.go b/lntemp/node/watcher.go index af0bf66cb..dd36e3202 100644 --- a/lntemp/node/watcher.go +++ b/lntemp/node/watcher.go @@ -12,7 +12,6 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lntemp/rpc" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnutils" ) @@ -31,9 +30,6 @@ const ( // watchPolicyUpdate specifies that this is a request to watch a policy // update event. watchPolicyUpdate - - // TODO(yy): remove once temp tests is finished. - DefaultTimeout = lntest.DefaultTimeout ) // chanWatchRequest is a request to the lightningNetworkWatcher to be notified @@ -123,7 +119,7 @@ func (nw *nodeWatcher) WaitForNumChannelUpdates(op wire.OutPoint, "want %d, got %d", expected, num) } - return wait.NoError(checkNumUpdates, DefaultTimeout) + return wait.NoError(checkNumUpdates, wait.DefaultTimeout) } // WaitForNumNodeUpdates will block until a given number of node updates has @@ -142,8 +138,7 @@ func (nw *nodeWatcher) WaitForNumNodeUpdates(pubkey string, return fmt.Errorf("timeout waiting for num node updates, "+ "want %d, got %d", expected, num) } - - err := wait.NoError(checkNumUpdates, DefaultTimeout) + err := wait.NoError(checkNumUpdates, wait.DefaultTimeout) return updates, err } @@ -161,7 +156,7 @@ func (nw *nodeWatcher) WaitForChannelOpen(chanPoint *lnrpc.ChannelPoint) error { chanWatchType: watchOpenChannel, } - timer := time.After(DefaultTimeout) + timer := time.After(wait.DefaultTimeout) select { case <-eventChan: return nil @@ -192,7 +187,7 @@ func (nw *nodeWatcher) WaitForChannelClose( chanWatchType: watchCloseChannel, } - timer := time.After(DefaultTimeout) + timer := time.After(wait.DefaultTimeout) select { case <-eventChan: closedChan, ok := nw.state.closedChans.Load(op) @@ -218,7 +213,7 @@ func (nw *nodeWatcher) WaitForChannelPolicyUpdate( op := nw.rpc.MakeOutpoint(chanPoint) ticker := time.NewTicker(wait.PollInterval) - timer := time.After(DefaultTimeout) + timer := time.After(wait.DefaultTimeout) defer ticker.Stop() eventChan := make(chan struct{}) diff --git a/lntemp/rpc/harness_rpc.go b/lntemp/rpc/harness_rpc.go index 549d2dc76..9de698536 100644 --- a/lntemp/rpc/harness_rpc.go +++ b/lntemp/rpc/harness_rpc.go @@ -15,14 +15,13 @@ import ( "github.com/lightningnetwork/lnd/lnrpc/walletrpc" "github.com/lightningnetwork/lnd/lnrpc/watchtowerrpc" "github.com/lightningnetwork/lnd/lnrpc/wtclientrpc" - "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" "google.golang.org/grpc" ) const ( - // TODO(yy): remove once temp tests is finished. - DefaultTimeout = lntest.DefaultTimeout + DefaultTimeout = wait.DefaultTimeout ) // HarnessRPC wraps all lnd's RPC clients into a single struct for easier diff --git a/lntest/harness_node.go b/lntest/harness_node.go index db9ad7fab..26dc90498 100644 --- a/lntest/harness_node.go +++ b/lntest/harness_node.go @@ -58,6 +58,11 @@ const ( // will wait between attempting to flush a batch of modifications to // disk(db.batch-commit-interval). commitInterval = 10 * time.Millisecond + + DefaultTimeout = wait.DefaultTimeout + NodeStartTimeout = wait.NodeStartTimeout + ChannelOpenTimeout = wait.ChannelOpenTimeout + ChannelCloseTimeout = wait.ChannelCloseTimeout ) var ( @@ -282,7 +287,7 @@ func (cfg *BaseNodeConfig) GenArgs() []string { case BackendSqlite: args = append(args, "--db.backend=sqlite") args = append(args, fmt.Sprintf("--db.sqlite.busytimeout=%v", - SqliteBusyTimeout)) + wait.SqliteBusyTimeout)) } if cfg.FeeURL != "" { diff --git a/lntest/timeouts.go b/lntest/wait/timeouts.go similarity index 98% rename from lntest/timeouts.go rename to lntest/wait/timeouts.go index 34418d4b5..507edd87a 100644 --- a/lntest/timeouts.go +++ b/lntest/wait/timeouts.go @@ -1,7 +1,7 @@ //go:build !darwin && !kvdb_etcd && !kvdb_postgres // +build !darwin,!kvdb_etcd,!kvdb_postgres -package lntest +package wait import "time" diff --git a/lntest/timeouts_darwin.go b/lntest/wait/timeouts_darwin.go similarity index 98% rename from lntest/timeouts_darwin.go rename to lntest/wait/timeouts_darwin.go index 3d61e3b0a..f08cd215a 100644 --- a/lntest/timeouts_darwin.go +++ b/lntest/wait/timeouts_darwin.go @@ -1,7 +1,7 @@ //go:build darwin && !kvdb_etcd && !kvdb_postgres // +build darwin,!kvdb_etcd,!kvdb_postgres -package lntest +package wait import "time" diff --git a/lntest/timeouts_remote_db.go b/lntest/wait/timeouts_remote_db.go similarity index 98% rename from lntest/timeouts_remote_db.go rename to lntest/wait/timeouts_remote_db.go index 300a8cf1c..c6805118b 100644 --- a/lntest/timeouts_remote_db.go +++ b/lntest/wait/timeouts_remote_db.go @@ -1,7 +1,7 @@ //go:build kvdb_etcd || kvdb_postgres // +build kvdb_etcd kvdb_postgres -package lntest +package wait import "time" From 94c64a886ef77ba658e41034d978151f0f094f99 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 12 Aug 2022 13:07:16 +0800 Subject: [PATCH 06/45] lntemp+itest: remove unused code to prepare `lntemp`'s takeover This commit removes the old code living in `lntest` to prepare `lntemp`'s takeover. --- itest/assertions.go | 1357 ----------------- itest/lnd_channel_force_close_test.go | 68 + itest/lnd_channel_policy_test.go | 15 - itest/lnd_etcd_failover_test.go | 6 +- itest/lnd_multi-hop_test.go | 97 -- itest/lnd_network_test.go | 5 +- itest/lnd_neutrino_test.go | 3 +- itest/lnd_psbt_test.go | 55 - itest/lnd_revocation_test.go | 3 +- itest/lnd_test.go | 6 +- itest/lnd_zero_conf_test.go | 3 +- itest/test_harness.go | 351 ----- itest/utils.go | 412 +----- lntemp/fee_service.go | 4 +- lntemp/harness.go | 9 +- lntemp/harness_miner.go | 6 +- lntemp/harness_node_manager.go | 5 +- lntemp/harness_setup.go | 17 +- lntemp/node/config.go | 154 +- lntemp/node/harness_node.go | 19 +- lntemp/utils.go | 5 +- lntest/bitcoind_common.go | 19 +- lntest/btcd.go | 25 +- lntest/fee_service.go | 114 -- lntest/fee_service_test.go | 39 - lntest/harness_miner.go | 161 --- lntest/harness_net.go | 1759 ---------------------- lntest/harness_node.go | 1928 ------------------------- lntest/neutrino.go | 3 +- lntest/test_common.go | 190 --- 30 files changed, 305 insertions(+), 6533 deletions(-) delete mode 100644 itest/assertions.go delete mode 100644 itest/test_harness.go delete mode 100644 lntest/fee_service.go delete mode 100644 lntest/fee_service_test.go delete mode 100644 lntest/harness_miner.go delete mode 100644 lntest/harness_net.go delete mode 100644 lntest/harness_node.go delete mode 100644 lntest/test_common.go diff --git a/itest/assertions.go b/itest/assertions.go deleted file mode 100644 index a917c2c1a..000000000 --- a/itest/assertions.go +++ /dev/null @@ -1,1357 +0,0 @@ -package itest - -import ( - "context" - "encoding/hex" - "fmt" - "math" - "sync/atomic" - "testing" - "time" - - "github.com/btcsuite/btcd/btcutil" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/wire" - "github.com/go-errors/errors" - "github.com/lightningnetwork/lnd/channeldb" - "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntest" - "github.com/lightningnetwork/lnd/lntest/wait" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" -) - -// openChannelStream blocks until an OpenChannel request for a channel funding -// by alice succeeds. If it does, a stream client is returned to receive events -// about the opening channel. -func openChannelStream(t *harnessTest, net *lntest.NetworkHarness, - alice, bob *lntest.HarnessNode, - p lntest.OpenChannelParams) lnrpc.Lightning_OpenChannelClient { - - t.t.Helper() - - // Wait until we are able to fund a channel successfully. This wait - // prevents us from erroring out when trying to create a channel while - // the node is starting up. - var chanOpenUpdate lnrpc.Lightning_OpenChannelClient - err := wait.NoError(func() error { - var err error - chanOpenUpdate, err = net.OpenChannel(alice, bob, p) - return err - }, defaultTimeout) - require.NoError(t.t, err, "unable to open channel") - - return chanOpenUpdate -} - -// openChannelAndAssert attempts to open a channel with the specified -// parameters extended from Alice to Bob. Additionally, two items are asserted -// after the channel is considered open: the funding transaction should be -// found within a block, and that Alice can report the status of the new -// channel. -func openChannelAndAssert(t *harnessTest, net *lntest.NetworkHarness, - alice, bob *lntest.HarnessNode, - p lntest.OpenChannelParams) *lnrpc.ChannelPoint { - - t.t.Helper() - - chanOpenUpdate := openChannelStream(t, net, alice, bob, p) - - // Mine 6 blocks, then wait for Alice's node to notify us that the - // channel has been opened. The funding transaction should be found - // within the first newly mined block. We mine 6 blocks so that in the - // case that the channel is public, it is announced to the network. - block := mineBlocks(t, net, 6, 1)[0] - - fundingChanPoint, err := net.WaitForChannelOpen(chanOpenUpdate) - require.NoError(t.t, err, "error while waiting for channel open") - - fundingTxID, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint) - require.NoError(t.t, err, "unable to get txid") - - assertTxInBlock(t, block, fundingTxID) - - // The channel should be listed in the peer information returned by - // both peers. - chanPoint := wire.OutPoint{ - Hash: *fundingTxID, - Index: fundingChanPoint.OutputIndex, - } - require.NoError( - t.t, net.AssertChannelExists(alice, &chanPoint), - "unable to assert channel existence", - ) - require.NoError( - t.t, net.AssertChannelExists(bob, &chanPoint), - "unable to assert channel existence", - ) - - // They should also notice this channel from topology subscription. - err = alice.WaitForNetworkChannelOpen(fundingChanPoint) - require.NoError(t.t, err) - - err = bob.WaitForNetworkChannelOpen(fundingChanPoint) - require.NoError(t.t, err) - - return fundingChanPoint -} - -func waitForGraphSync(t *harnessTest, node *lntest.HarnessNode) { - t.t.Helper() - - err := wait.Predicate(func() bool { - ctxb := context.Background() - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - resp, err := node.GetInfo(ctxt, &lnrpc.GetInfoRequest{}) - require.NoError(t.t, err) - - return resp.SyncedToGraph - }, defaultTimeout) - require.NoError(t.t, err) -} - -// closeChannelAndAssert attempts to close a channel identified by the passed -// channel point owned by the passed Lightning node. A fully blocking channel -// closure is attempted, therefore the passed context should be a child derived -// via timeout from a base parent. Additionally, once the channel has been -// detected as closed, an assertion checks that the transaction is found within -// a block. Finally, this assertion verifies that the node always sends out a -// disable update when closing the channel if the channel was previously -// enabled. -// -// NOTE: This method assumes that the provided funding point is confirmed -// on-chain AND that the edge exists in the node's channel graph. If the funding -// transactions was reorged out at some point, use closeReorgedChannelAndAssert. -func closeChannelAndAssert(t *harnessTest, net *lntest.NetworkHarness, - node *lntest.HarnessNode, fundingChanPoint *lnrpc.ChannelPoint, - force bool) *chainhash.Hash { - - return closeChannelAndAssertType( - t, net, node, fundingChanPoint, false, force, - ) -} - -func closeChannelAndAssertType(t *harnessTest, - net *lntest.NetworkHarness, node *lntest.HarnessNode, - fundingChanPoint *lnrpc.ChannelPoint, - anchors, force bool) *chainhash.Hash { - - ctxb := context.Background() - ctxt, cancel := context.WithTimeout(ctxb, channelCloseTimeout) - defer cancel() - - // Fetch the current channel policy. If the channel is currently - // enabled, we will register for graph notifications before closing to - // assert that the node sends out a disabling update as a result of the - // channel being closed. - curPolicy := getChannelPolicies( - t, node, node.PubKeyStr, fundingChanPoint, - )[0] - expectDisable := !curPolicy.Disabled - - closeUpdates, _, err := net.CloseChannel(node, fundingChanPoint, force) - require.NoError(t.t, err, "unable to close channel") - - // If the channel policy was enabled prior to the closure, wait until we - // received the disabled update. - if expectDisable { - curPolicy.Disabled = true - assertChannelPolicyUpdate( - t.t, node, node.PubKeyStr, - curPolicy, fundingChanPoint, false, - ) - } - - return assertChannelClosed( - ctxt, t, net, node, fundingChanPoint, anchors, closeUpdates, - ) -} - -// closeReorgedChannelAndAssert attempts to close a channel identified by the -// passed channel point owned by the passed Lightning node. A fully blocking -// channel closure is attempted, therefore the passed context should be a child -// derived via timeout from a base parent. Additionally, once the channel has -// been detected as closed, an assertion checks that the transaction is found -// within a block. -// -// NOTE: This method does not verify that the node sends a disable update for -// the closed channel. -func closeReorgedChannelAndAssert(t *harnessTest, - net *lntest.NetworkHarness, node *lntest.HarnessNode, - fundingChanPoint *lnrpc.ChannelPoint, force bool) *chainhash.Hash { - - ctxb := context.Background() - ctx, cancel := context.WithTimeout(ctxb, channelCloseTimeout) - defer cancel() - - closeUpdates, _, err := net.CloseChannel(node, fundingChanPoint, force) - require.NoError(t.t, err, "unable to close channel") - - return assertChannelClosed( - ctx, t, net, node, fundingChanPoint, false, closeUpdates, - ) -} - -// assertChannelClosed asserts that the channel is properly cleaned up after -// initiating a cooperative or local close. -func assertChannelClosed(ctx context.Context, t *harnessTest, - net *lntest.NetworkHarness, node *lntest.HarnessNode, - fundingChanPoint *lnrpc.ChannelPoint, anchors bool, - closeUpdates lnrpc.Lightning_CloseChannelClient) *chainhash.Hash { - - txid, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint) - require.NoError(t.t, err, "unable to get txid") - chanPointStr := fmt.Sprintf("%v:%v", txid, fundingChanPoint.OutputIndex) - - // If the channel appears in list channels, ensure that its state - // contains ChanStatusCoopBroadcasted. - listChansRequest := &lnrpc.ListChannelsRequest{} - listChansResp, err := node.ListChannels(ctx, listChansRequest) - require.NoError(t.t, err, "unable to query for list channels") - - for _, channel := range listChansResp.Channels { - // Skip other channels. - if channel.ChannelPoint != chanPointStr { - continue - } - - // Assert that the channel is in coop broadcasted. - require.Contains( - t.t, channel.ChanStatusFlags, - channeldb.ChanStatusCoopBroadcasted.String(), - "channel not coop broadcasted", - ) - } - - // At this point, the channel should now be marked as being in the - // state of "waiting close". - pendingChansRequest := &lnrpc.PendingChannelsRequest{} - pendingChanResp, err := node.PendingChannels(ctx, pendingChansRequest) - require.NoError(t.t, err, "unable to query for pending channels") - - var found bool - for _, pendingClose := range pendingChanResp.WaitingCloseChannels { - if pendingClose.Channel.ChannelPoint == chanPointStr { - found = true - break - } - } - require.True(t.t, found, "channel not marked as waiting close") - - // We'll now, generate a single block, wait for the final close status - // update, then ensure that the closing transaction was included in the - // block. If there are anchors, we also expect an anchor sweep. - expectedTxes := 1 - if anchors { - expectedTxes = 2 - } - - block := mineBlocks(t, net, 1, expectedTxes)[0] - - closingTxid, err := net.WaitForChannelClose(closeUpdates) - require.NoError(t.t, err, "error while waiting for channel close") - - assertTxInBlock(t, block, closingTxid) - - // Finally, the transaction should no longer be in the waiting close - // state as we've just mined a block that should include the closing - // transaction. - err = wait.Predicate(func() bool { - pendingChansRequest := &lnrpc.PendingChannelsRequest{} - pendingChanResp, err := node.PendingChannels( - ctx, pendingChansRequest, - ) - if err != nil { - return false - } - - for _, pendingClose := range pendingChanResp.WaitingCloseChannels { - if pendingClose.Channel.ChannelPoint == chanPointStr { - return false - } - } - - return true - }, defaultTimeout) - require.NoError( - t.t, err, "closing transaction not marked as fully closed", - ) - - return closingTxid -} - -// findForceClosedChannel searches a pending channel response for a particular -// channel, returning the force closed channel upon success. -func findForceClosedChannel(pendingChanResp *lnrpc.PendingChannelsResponse, - op fmt.Stringer) (*lnrpc.PendingChannelsResponse_ForceClosedChannel, - error) { - - for _, forceClose := range pendingChanResp.PendingForceClosingChannels { - if forceClose.Channel.ChannelPoint == op.String() { - return forceClose, nil - } - } - - return nil, errors.New("channel not marked as force closed") -} - -// findWaitingCloseChannel searches a pending channel response for a particular -// channel, returning the waiting close channel upon success. -func findWaitingCloseChannel(pendingChanResp *lnrpc.PendingChannelsResponse, - op fmt.Stringer) (*lnrpc.PendingChannelsResponse_WaitingCloseChannel, - error) { - - for _, waitingClose := range pendingChanResp.WaitingCloseChannels { - if waitingClose.Channel.ChannelPoint == op.String() { - return waitingClose, nil - } - } - - return nil, errors.New("channel not marked as waiting close") -} - -// waitForChannelPendingForceClose waits for the node to report that the -// channel is pending force close, and that the UTXO nursery is aware of it. -func waitForChannelPendingForceClose(node *lntest.HarnessNode, - fundingChanPoint *lnrpc.ChannelPoint) error { - - ctxb := context.Background() - ctx, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - txid, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint) - if err != nil { - return err - } - - op := wire.OutPoint{ - Hash: *txid, - Index: fundingChanPoint.OutputIndex, - } - - return wait.NoError(func() error { - pendingChansRequest := &lnrpc.PendingChannelsRequest{} - pendingChanResp, err := node.PendingChannels( - ctx, pendingChansRequest, - ) - if err != nil { - return fmt.Errorf("unable to get pending channels: %v", - err) - } - - forceClose, err := findForceClosedChannel(pendingChanResp, &op) - if err != nil { - return err - } - - // We must wait until the UTXO nursery has received the channel - // and is aware of its maturity height. - if forceClose.MaturityHeight == 0 { - return fmt.Errorf("channel had maturity height of 0") - } - - return nil - }, defaultTimeout) -} - -// lnrpcForceCloseChannel is a short type alias for a ridiculously long type -// name in the lnrpc package. -type lnrpcForceCloseChannel = lnrpc.PendingChannelsResponse_ForceClosedChannel - -// waitForNumChannelPendingForceClose waits for the node to report a certain -// number of channels in state pending force close. -func waitForNumChannelPendingForceClose(node *lntest.HarnessNode, - expectedNum int, - perChanCheck func(channel *lnrpcForceCloseChannel) error) error { - - ctxb := context.Background() - ctx, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - return wait.NoError(func() error { - resp, err := node.PendingChannels( - ctx, &lnrpc.PendingChannelsRequest{}, - ) - if err != nil { - return fmt.Errorf("unable to get pending channels: %v", - err) - } - - forceCloseChans := resp.PendingForceClosingChannels - if len(forceCloseChans) != expectedNum { - return fmt.Errorf("%v should have %d pending "+ - "force close channels but has %d", - node.Cfg.Name, expectedNum, - len(forceCloseChans)) - } - - if perChanCheck != nil { - for _, forceCloseChan := range forceCloseChans { - err := perChanCheck(forceCloseChan) - if err != nil { - return err - } - } - } - - return nil - }, defaultTimeout) -} - -// cleanupForceClose mines a force close commitment found in the mempool and -// the following sweep transaction from the force closing node. -func cleanupForceClose(t *harnessTest, net *lntest.NetworkHarness, - node *lntest.HarnessNode, chanPoint *lnrpc.ChannelPoint) { - - // Wait for the channel to be marked pending force close. - err := waitForChannelPendingForceClose(node, chanPoint) - require.NoError(t.t, err, "channel not pending force close") - - // Mine enough blocks for the node to sweep its funds from the force - // closed channel. - // - // The commit sweep resolver is able to broadcast the sweep tx up to - // one block before the CSV elapses, so wait until defaulCSV-1. - _, err = net.Miner.Client.Generate(defaultCSV - 1) - require.NoError(t.t, err, "unable to generate blocks") - - // The node should now sweep the funds, clean up by mining the sweeping - // tx. - mineBlocks(t, net, 1, 1) -} - -// numOpenChannelsPending sends an RPC request to a node to get a count of the -// node's channels that are currently in a pending state (with a broadcast, but -// not confirmed funding transaction). -func numOpenChannelsPending(ctxt context.Context, - node *lntest.HarnessNode) (int, error) { - - pendingChansRequest := &lnrpc.PendingChannelsRequest{} - resp, err := node.PendingChannels(ctxt, pendingChansRequest) - if err != nil { - return 0, err - } - return len(resp.PendingOpenChannels), nil -} - -// assertNumOpenChannelsPending asserts that a pair of nodes have the expected -// number of pending channels between them. -func assertNumOpenChannelsPending(t *harnessTest, - alice, bob *lntest.HarnessNode, expected int) { - - ctxb := context.Background() - ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - err := wait.NoError(func() error { - aliceNumChans, err := numOpenChannelsPending(ctxt, alice) - if err != nil { - return fmt.Errorf("error fetching alice's node (%v) "+ - "pending channels %v", alice.NodeID, err) - } - bobNumChans, err := numOpenChannelsPending(ctxt, bob) - if err != nil { - return fmt.Errorf("error fetching bob's node (%v) "+ - "pending channels %v", bob.NodeID, err) - } - - aliceStateCorrect := aliceNumChans == expected - if !aliceStateCorrect { - return fmt.Errorf("number of pending channels for "+ - "alice incorrect. expected %v, got %v", - expected, aliceNumChans) - } - - bobStateCorrect := bobNumChans == expected - if !bobStateCorrect { - return fmt.Errorf("number of pending channels for bob "+ - "incorrect. expected %v, got %v", expected, - bobNumChans) - } - - return nil - }, defaultTimeout) - require.NoError(t.t, err) -} - -// checkPeerInPeersList returns true if Bob appears in Alice's peer list. -func checkPeerInPeersList(ctx context.Context, alice, - bob *lntest.HarnessNode) (bool, error) { - - peers, err := alice.ListPeers(ctx, &lnrpc.ListPeersRequest{}) - if err != nil { - return false, fmt.Errorf( - "error listing %s's node (%v) peers: %v", - alice.Name(), alice.NodeID, err, - ) - } - - for _, peer := range peers.Peers { - if peer.PubKey == bob.PubKeyStr { - return true, nil - } - } - - return false, nil -} - -// assertConnected asserts that two peers are connected. -func assertConnected(t *harnessTest, alice, bob *lntest.HarnessNode) { - ctxb := context.Background() - ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - err := wait.NoError(func() error { - bobIsAlicePeer, err := checkPeerInPeersList(ctxt, alice, bob) - if err != nil { - return err - } - - if !bobIsAlicePeer { - return fmt.Errorf( - "expected %s and %s to be connected "+ - "but %s is not in %s's peer list", - alice.Name(), bob.Name(), - bob.Name(), alice.Name(), - ) - } - - aliceIsBobPeer, err := checkPeerInPeersList(ctxt, bob, alice) - if err != nil { - return err - } - - if !aliceIsBobPeer { - return fmt.Errorf( - "expected %s and %s to be connected "+ - "but %s is not in %s's peer list", - alice.Name(), bob.Name(), - alice.Name(), bob.Name(), - ) - } - - return nil - }, defaultTimeout) - require.NoError(t.t, err) -} - -// assertNotConnected asserts that two peers are not connected. -func assertNotConnected(t *harnessTest, alice, bob *lntest.HarnessNode) { - ctxb := context.Background() - ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - err := wait.NoError(func() error { - bobIsAlicePeer, err := checkPeerInPeersList(ctxt, alice, bob) - if err != nil { - return err - } - - if bobIsAlicePeer { - return fmt.Errorf( - "expected %s and %s not to be "+ - "connected but %s is in %s's "+ - "peer list", - alice.Name(), bob.Name(), - bob.Name(), alice.Name(), - ) - } - - aliceIsBobPeer, err := checkPeerInPeersList(ctxt, bob, alice) - if err != nil { - return err - } - - if aliceIsBobPeer { - return fmt.Errorf( - "expected %s and %s not to be "+ - "connected but %s is in %s's "+ - "peer list", - alice.Name(), bob.Name(), - alice.Name(), bob.Name(), - ) - } - - return nil - }, defaultTimeout) - require.NoError(t.t, err) -} - -// shutdownAndAssert shuts down the given node and asserts that no errors -// occur. -func shutdownAndAssert(net *lntest.NetworkHarness, t *harnessTest, - node *lntest.HarnessNode) { - - // The process may not be in a state to always shutdown immediately, so - // we'll retry up to a hard limit to ensure we eventually shutdown. - err := wait.NoError(func() error { - return net.ShutdownNode(node) - }, defaultTimeout) - require.NoErrorf(t.t, err, "unable to shutdown %v", node.Name()) -} - -// assertChannelBalanceResp makes a ChannelBalance request and checks the -// returned response matches the expected. -func assertChannelBalanceResp(t *harnessTest, node *lntest.HarnessNode, - expected *lnrpc.ChannelBalanceResponse) { - - resp := getChannelBalance(t, node) - require.True(t.t, proto.Equal(expected, resp), "balance is incorrect") -} - -// getChannelBalance gets the channel balance. -func getChannelBalance(t *harnessTest, - node *lntest.HarnessNode) *lnrpc.ChannelBalanceResponse { - - t.t.Helper() - - ctxt, _ := context.WithTimeout(context.Background(), defaultTimeout) - req := &lnrpc.ChannelBalanceRequest{} - resp, err := node.ChannelBalance(ctxt, req) - - require.NoError(t.t, err, "unable to get node's balance") - return resp -} - -// txStr returns the string representation of the channel's funding transaction. -func txStr(chanPoint *lnrpc.ChannelPoint) string { - fundingTxID, err := lnrpc.GetChanPointFundingTxid(chanPoint) - if err != nil { - return "" - } - cp := wire.OutPoint{ - Hash: *fundingTxID, - Index: chanPoint.OutputIndex, - } - return cp.String() -} - -// getChannelPolicies queries the channel graph and retrieves the current edge -// policies for the provided channel points. -func getChannelPolicies(t *harnessTest, node *lntest.HarnessNode, - advertisingNode string, - chanPoints ...*lnrpc.ChannelPoint) []*lnrpc.RoutingPolicy { - - ctxb := context.Background() - - descReq := &lnrpc.ChannelGraphRequest{ - IncludeUnannounced: true, - } - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - chanGraph, err := node.DescribeGraph(ctxt, descReq) - require.NoError(t.t, err, "unable to query for alice's graph") - - var policies []*lnrpc.RoutingPolicy - err = wait.NoError(func() error { - out: - for _, chanPoint := range chanPoints { - for _, e := range chanGraph.Edges { - if e.ChanPoint != txStr(chanPoint) { - continue - } - - if e.Node1Pub == advertisingNode { - policies = append(policies, - e.Node1Policy) - } else { - policies = append(policies, - e.Node2Policy) - } - - continue out - } - - // If we've iterated over all the known edges and we weren't - // able to find this specific one, then we'll fail. - return fmt.Errorf("did not find edge %v", txStr(chanPoint)) - } - - return nil - }, defaultTimeout) - require.NoError(t.t, err) - - return policies -} - -// assertChannelPolicy asserts that the passed node's known channel policy for -// the passed chanPoint is consistent with the expected policy values. -func assertChannelPolicy(t *harnessTest, node *lntest.HarnessNode, - advertisingNode string, expectedPolicy *lnrpc.RoutingPolicy, - chanPoints ...*lnrpc.ChannelPoint) { - - policies := getChannelPolicies(t, node, advertisingNode, chanPoints...) - for _, policy := range policies { - err := lntest.CheckChannelPolicy(policy, expectedPolicy) - if err != nil { - t.Fatalf(fmt.Sprintf("%v: %s", err.Error(), node)) - } - } -} - -func checkCommitmentMaturity( - forceClose *lnrpc.PendingChannelsResponse_ForceClosedChannel, - maturityHeight uint32, blocksTilMaturity int32) error { - - if forceClose.MaturityHeight != maturityHeight { - return fmt.Errorf("expected commitment maturity height to be "+ - "%d, found %d instead", maturityHeight, - forceClose.MaturityHeight) - } - if forceClose.BlocksTilMaturity != blocksTilMaturity { - return fmt.Errorf("expected commitment blocks til maturity to "+ - "be %d, found %d instead", blocksTilMaturity, - forceClose.BlocksTilMaturity) - } - - return nil -} - -// checkForceClosedChannelNumHtlcs verifies that a force closed channel has the -// proper number of htlcs. -func checkPendingChannelNumHtlcs( - forceClose *lnrpc.PendingChannelsResponse_ForceClosedChannel, - expectedNumHtlcs int) error { - - if len(forceClose.PendingHtlcs) != expectedNumHtlcs { - return fmt.Errorf("expected force closed channel to have %d "+ - "pending htlcs, found %d instead", expectedNumHtlcs, - len(forceClose.PendingHtlcs)) - } - - return nil -} - -// checkNumForceClosedChannels checks that a pending channel response has the -// expected number of force closed channels. -func checkNumForceClosedChannels(pendingChanResp *lnrpc.PendingChannelsResponse, - expectedNumChans int) error { - - if len(pendingChanResp.PendingForceClosingChannels) != expectedNumChans { - return fmt.Errorf("expected to find %d force closed channels, "+ - "got %d", expectedNumChans, - len(pendingChanResp.PendingForceClosingChannels)) - } - - return nil -} - -// checkNumWaitingCloseChannels checks that a pending channel response has the -// expected number of channels waiting for closing tx to confirm. -func checkNumWaitingCloseChannels(pendingChanResp *lnrpc.PendingChannelsResponse, - expectedNumChans int) error { - - if len(pendingChanResp.WaitingCloseChannels) != expectedNumChans { - return fmt.Errorf("expected to find %d channels waiting "+ - "closure, got %d", expectedNumChans, - len(pendingChanResp.WaitingCloseChannels)) - } - - return nil -} - -// checkPendingHtlcStageAndMaturity uniformly tests all pending htlc's belonging -// to a force closed channel, testing for the expected stage number, blocks till -// maturity, and the maturity height. -func checkPendingHtlcStageAndMaturity( - forceClose *lnrpc.PendingChannelsResponse_ForceClosedChannel, - stage, maturityHeight uint32, blocksTillMaturity int32) error { - - for _, pendingHtlc := range forceClose.PendingHtlcs { - if pendingHtlc.Stage != stage { - return fmt.Errorf("expected pending htlc to be stage "+ - "%d, found %d", stage, pendingHtlc.Stage) - } - if pendingHtlc.MaturityHeight != maturityHeight { - return fmt.Errorf("expected pending htlc maturity "+ - "height to be %d, instead has %d", - maturityHeight, pendingHtlc.MaturityHeight) - } - if pendingHtlc.BlocksTilMaturity != blocksTillMaturity { - return fmt.Errorf("expected pending htlc blocks til "+ - "maturity to be %d, instead has %d", - blocksTillMaturity, - pendingHtlc.BlocksTilMaturity) - } - } - - return nil -} - -// assertAmountSent generates a closure which queries listchannels for sndr and -// rcvr, and asserts that sndr sent amt satoshis, and that rcvr received amt -// satoshis. -// -// NOTE: This method assumes that each node only has one channel, and it is the -// channel used to send the payment. -func assertAmountSent(amt btcutil.Amount, sndr, rcvr *lntest.HarnessNode) func() error { - return func() error { - // Both channels should also have properly accounted from the - // amount that has been sent/received over the channel. - listReq := &lnrpc.ListChannelsRequest{} - ctxb := context.Background() - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - sndrListChannels, err := sndr.ListChannels(ctxt, listReq) - if err != nil { - return fmt.Errorf("unable to query for %s's channel "+ - "list: %v", sndr.Name(), err) - } - sndrSatoshisSent := sndrListChannels.Channels[0].TotalSatoshisSent - if sndrSatoshisSent != int64(amt) { - return fmt.Errorf("%s's satoshis sent is incorrect "+ - "got %v, expected %v", sndr.Name(), - sndrSatoshisSent, amt) - } - - ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - rcvrListChannels, err := rcvr.ListChannels(ctxt, listReq) - if err != nil { - return fmt.Errorf("unable to query for %s's channel "+ - "list: %v", rcvr.Name(), err) - } - rcvrSatoshisReceived := rcvrListChannels.Channels[0].TotalSatoshisReceived - if rcvrSatoshisReceived != int64(amt) { - return fmt.Errorf("%s's satoshis received is "+ - "incorrect got %v, expected %v", rcvr.Name(), - rcvrSatoshisReceived, amt) - } - - return nil - } -} - -// assertLastHTLCError checks that the last sent HTLC of the last payment sent -// by the given node failed with the expected failure code. -func assertLastHTLCError(t *harnessTest, node *lntest.HarnessNode, - code lnrpc.Failure_FailureCode) { - - req := &lnrpc.ListPaymentsRequest{ - IncludeIncomplete: true, - } - ctxt, _ := context.WithTimeout(context.Background(), defaultTimeout) - paymentsResp, err := node.ListPayments(ctxt, req) - require.NoError(t.t, err, "error when obtaining payments") - - payments := paymentsResp.Payments - require.NotZero(t.t, len(payments), "no payments found") - - payment := payments[len(payments)-1] - htlcs := payment.Htlcs - require.NotZero(t.t, len(htlcs), "no htlcs") - - htlc := htlcs[len(htlcs)-1] - require.NotNil(t.t, htlc.Failure, "expected failure") - - require.Equal(t.t, code, htlc.Failure.Code, "unexpected failure code") -} - -// assertAmountPaid checks that the ListChannels command of the provided -// node list the total amount sent and received as expected for the -// provided channel. -func assertAmountPaid(t *harnessTest, channelName string, - node *lntest.HarnessNode, chanPoint wire.OutPoint, amountSent, - amountReceived int64) { - - ctxb := context.Background() - - checkAmountPaid := func() error { - listReq := &lnrpc.ListChannelsRequest{} - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - resp, err := node.ListChannels(ctxt, listReq) - if err != nil { - return fmt.Errorf("unable to for node's "+ - "channels: %v", err) - } - for _, channel := range resp.Channels { - if channel.ChannelPoint != chanPoint.String() { - continue - } - - if channel.TotalSatoshisSent != amountSent { - return fmt.Errorf("%v: incorrect amount"+ - " sent: %v != %v", channelName, - channel.TotalSatoshisSent, - amountSent) - } - if channel.TotalSatoshisReceived != - amountReceived { - - return fmt.Errorf("%v: incorrect amount"+ - " received: %v != %v", - channelName, - channel.TotalSatoshisReceived, - amountReceived) - } - - return nil - } - return fmt.Errorf("channel not found") - } - - // As far as HTLC inclusion in commitment transaction might be - // postponed we will try to check the balance couple of times, - // and then if after some period of time we receive wrong - // balance return the error. - // TODO(roasbeef): remove sleep after invoice notification hooks - // are in place - var timeover uint32 - go func() { - <-time.After(defaultTimeout) - atomic.StoreUint32(&timeover, 1) - }() - - for { - isTimeover := atomic.LoadUint32(&timeover) == 1 - if err := checkAmountPaid(); err != nil { - require.Falsef( - t.t, isTimeover, - "Check amount Paid failed: %v", err, - ) - } else { - break - } - } -} - -// assertNumPendingChannels checks that a PendingChannels response from the -// node reports the expected number of pending channels. -func assertNumPendingChannels(t *harnessTest, node *lntest.HarnessNode, - expWaitingClose, expPendingForceClose int) { - - ctxb := context.Background() - - var predErr error - err := wait.Predicate(func() bool { - pendingChansRequest := &lnrpc.PendingChannelsRequest{} - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - pendingChanResp, err := node.PendingChannels(ctxt, - pendingChansRequest) - if err != nil { - predErr = fmt.Errorf("unable to query for pending "+ - "channels: %v", err) - return false - } - n := len(pendingChanResp.WaitingCloseChannels) - if n != expWaitingClose { - predErr = fmt.Errorf("expected to find %d channels "+ - "waiting close, found %d", expWaitingClose, n) - return false - } - n = len(pendingChanResp.PendingForceClosingChannels) - if n != expPendingForceClose { - predErr = fmt.Errorf("expected to find %d channel "+ - "pending force close, found %d", expPendingForceClose, n) - return false - } - return true - }, defaultTimeout) - require.NoErrorf(t.t, err, "got err: %v", predErr) -} - -// assertNodeNumChannels polls the provided node's list channels rpc until it -// reaches the desired number of total channels. -func assertNodeNumChannels(t *harnessTest, node *lntest.HarnessNode, - numChannels int) { - - ctxb := context.Background() - - // Poll node for its list of channels. - req := &lnrpc.ListChannelsRequest{} - - var predErr error - pred := func() bool { - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - chanInfo, err := node.ListChannels(ctxt, req) - if err != nil { - predErr = fmt.Errorf("unable to query for node's "+ - "channels: %v", err) - return false - } - - // Return true if the query returned the expected number of - // channels. - num := len(chanInfo.Channels) - if num != numChannels { - predErr = fmt.Errorf("expected %v channels, got %v", - numChannels, num) - return false - } - return true - } - - require.NoErrorf( - t.t, wait.Predicate(pred, defaultTimeout), - "node has incorrect number of channels: %v", predErr, - ) -} - -// assertActiveHtlcs makes sure all the passed nodes have the _exact_ HTLCs -// matching payHashes on _all_ their channels. -func assertActiveHtlcs(nodes []*lntest.HarnessNode, payHashes ...[]byte) error { - ctxb := context.Background() - - req := &lnrpc.ListChannelsRequest{} - for _, node := range nodes { - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - nodeChans, err := node.ListChannels(ctxt, req) - if err != nil { - return fmt.Errorf("unable to get node chans: %v", err) - } - - for _, channel := range nodeChans.Channels { - // Record all payment hashes active for this channel. - htlcHashes := make(map[string]struct{}) - for _, htlc := range channel.PendingHtlcs { - h := hex.EncodeToString(htlc.HashLock) - _, ok := htlcHashes[h] - if ok { - return fmt.Errorf("duplicate HashLock") - } - htlcHashes[h] = struct{}{} - } - - // Channel should have exactly the payHashes active. - if len(payHashes) != len(htlcHashes) { - return fmt.Errorf("node [%s:%x] had %v "+ - "htlcs active, expected %v", - node.Cfg.Name, node.PubKey[:], - len(htlcHashes), len(payHashes)) - } - - // Make sure all the payHashes are active. - for _, payHash := range payHashes { - h := hex.EncodeToString(payHash) - if _, ok := htlcHashes[h]; ok { - continue - } - return fmt.Errorf("node [%s:%x] didn't have: "+ - "the payHash %v active", node.Cfg.Name, - node.PubKey[:], h) - } - } - } - - return nil -} - -func assertNumActiveHtlcsChanPoint(node *lntest.HarnessNode, - chanPoint wire.OutPoint, numHtlcs int) error { - - ctxb := context.Background() - - req := &lnrpc.ListChannelsRequest{} - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - nodeChans, err := node.ListChannels(ctxt, req) - if err != nil { - return err - } - - for _, channel := range nodeChans.Channels { - if channel.ChannelPoint != chanPoint.String() { - continue - } - - if len(channel.PendingHtlcs) != numHtlcs { - return fmt.Errorf("expected %v active HTLCs, got %v", - numHtlcs, len(channel.PendingHtlcs)) - } - return nil - } - - return fmt.Errorf("channel point %v not found", chanPoint) -} - -func assertNumActiveHtlcs(nodes []*lntest.HarnessNode, numHtlcs int) error { - ctxb := context.Background() - - req := &lnrpc.ListChannelsRequest{} - for _, node := range nodes { - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - nodeChans, err := node.ListChannels(ctxt, req) - if err != nil { - return err - } - - for _, channel := range nodeChans.Channels { - if len(channel.PendingHtlcs) != numHtlcs { - return fmt.Errorf("expected %v HTLCs, got %v", - numHtlcs, len(channel.PendingHtlcs)) - } - } - } - - return nil -} - -func assertSpendingTxInMempool(t *harnessTest, miner *rpcclient.Client, - timeout time.Duration, inputs ...wire.OutPoint) chainhash.Hash { - - tx := getSpendingTxInMempool(t, miner, timeout, inputs...) - return tx.TxHash() -} - -// getSpendingTxInMempool waits for a transaction spending the given outpoint to -// appear in the mempool and returns that tx in full. -func getSpendingTxInMempool(t *harnessTest, miner *rpcclient.Client, - timeout time.Duration, inputs ...wire.OutPoint) *wire.MsgTx { - - inputSet := make(map[wire.OutPoint]struct{}, len(inputs)) - breakTimeout := time.After(timeout) - ticker := time.NewTicker(50 * time.Millisecond) - defer ticker.Stop() - - for { - select { - case <-breakTimeout: - t.Fatalf("didn't find tx in mempool") - case <-ticker.C: - mempool, err := miner.GetRawMempool() - require.NoError(t.t, err, "unable to get mempool") - - if len(mempool) == 0 { - continue - } - - for _, txid := range mempool { - tx, err := miner.GetRawTransaction(txid) - require.NoError(t.t, err, "unable to fetch tx") - msgTx := tx.MsgTx() - - // Include the inputs again in case they were - // removed in a previous iteration. - for _, input := range inputs { - inputSet[input] = struct{}{} - } - - for _, txIn := range msgTx.TxIn { - input := txIn.PreviousOutPoint - delete(inputSet, input) - } - - if len(inputSet) > 0 { - // Missing input, check next transaction - // or try again. - continue - } - - // Transaction spends all expected inputs, - // return. - return msgTx - } - } - } -} - -// assertTxLabel is a helper function which finds a target tx in our set -// of transactions and checks that it has the desired label. -func assertTxLabel(t *harnessTest, node *lntest.HarnessNode, - targetTx, label string) { - - // List all transactions relevant to our wallet, and find the tx so that - // we can check the correct label has been set. - ctxb := context.Background() - ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - txResp, err := node.GetTransactions( - ctxt, &lnrpc.GetTransactionsRequest{}, - ) - require.NoError(t.t, err, "could not get transactions") - - // Find our transaction in the set of transactions returned and check - // its label. - for _, txn := range txResp.Transactions { - if txn.TxHash == targetTx { - require.Equal(t.t, label, txn.Label, "labels not match") - } - } -} - -// sendAndAssertSuccess sends the given payment requests and asserts that the -// payment completes successfully. -func sendAndAssertSuccess(t *harnessTest, node *lntest.HarnessNode, - req *routerrpc.SendPaymentRequest) *lnrpc.Payment { - - ctxb := context.Background() - ctx, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - var result *lnrpc.Payment - err := wait.NoError(func() error { - stream, err := node.RouterClient.SendPaymentV2(ctx, req) - if err != nil { - return fmt.Errorf("unable to send payment: %v", err) - } - - result, err = getPaymentResult(stream) - if err != nil { - return fmt.Errorf("unable to get payment result: %v", - err) - } - - if result.Status != lnrpc.Payment_SUCCEEDED { - return fmt.Errorf("payment failed: %v", result.Status) - } - - return nil - }, defaultTimeout) - require.NoError(t.t, err) - - return result -} - -// sendAndAssertFailure sends the given payment requests and asserts that the -// payment fails with the expected reason. -func sendAndAssertFailure(t *harnessTest, node *lntest.HarnessNode, - req *routerrpc.SendPaymentRequest, - failureReason lnrpc.PaymentFailureReason) *lnrpc.Payment { - - ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) - defer cancel() - - stream, err := node.RouterClient.SendPaymentV2(ctx, req) - require.NoError(t.t, err, "unable to send payment") - - result, err := getPaymentResult(stream) - require.NoError(t.t, err, "unable to get payment result") - - require.Equal( - t.t, lnrpc.Payment_FAILED, result.Status, - "payment was expected to fail, but succeeded", - ) - - require.Equal( - t.t, failureReason, result.FailureReason, - "payment failureReason not matched", - ) - - return result -} - -// getPaymentResult reads a final result from the stream and returns it. -func getPaymentResult(stream routerrpc.Router_SendPaymentV2Client) ( - *lnrpc.Payment, error) { - - for { - payment, err := stream.Recv() - if err != nil { - return nil, err - } - - if payment.Status != lnrpc.Payment_IN_FLIGHT { - return payment, nil - } - } -} - -// assertNumUTXOs waits for the given number of UTXOs to be available or fails -// if that isn't the case before the default timeout. -func assertNumUTXOs(t *testing.T, node *lntest.HarnessNode, expectedUtxos int) { - ctxb := context.Background() - ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - err := wait.NoError(func() error { - resp, err := node.ListUnspent( // nolint:staticcheck - ctxt, &lnrpc.ListUnspentRequest{ - MinConfs: 1, - MaxConfs: math.MaxInt32, - }, - ) - if err != nil { - return fmt.Errorf("error listing unspent: %v", err) - } - - if len(resp.Utxos) != expectedUtxos { - return fmt.Errorf("not enough UTXOs, got %d wanted %d", - len(resp.Utxos), expectedUtxos) - } - - return nil - }, defaultTimeout) - require.NoError(t, err, "wait for listunspent") -} - -// assertChannelPolicyUpdate checks that the required policy update has -// happened on the given node. -func assertChannelPolicyUpdate(t *testing.T, node *lntest.HarnessNode, - advertisingNode string, policy *lnrpc.RoutingPolicy, - chanPoint *lnrpc.ChannelPoint, includeUnannounced bool) { - - require.NoError( - t, node.WaitForChannelPolicyUpdate( - advertisingNode, policy, - chanPoint, includeUnannounced, - ), "error while waiting for channel update", - ) -} - -func transactionInWallet(node *lntest.HarnessNode, txid chainhash.Hash) bool { - txStr := txid.String() - - txResp, err := node.GetTransactions( - context.Background(), &lnrpc.GetTransactionsRequest{}, - ) - if err != nil { - return false - } - - for _, txn := range txResp.Transactions { - if txn.TxHash == txStr { - return true - } - } - - return false -} - -func assertTransactionInWallet(t *testing.T, node *lntest.HarnessNode, txID chainhash.Hash) { - t.Helper() - - err := wait.Predicate(func() bool { - return transactionInWallet(node, txID) - }, defaultTimeout) - require.NoError( - t, err, fmt.Sprintf("transaction %v not found in wallet", txID), - ) -} - -func assertTransactionNotInWallet(t *testing.T, node *lntest.HarnessNode, - txID chainhash.Hash) { - - t.Helper() - - err := wait.Predicate(func() bool { - return !transactionInWallet(node, txID) - }, defaultTimeout) - require.NoError( - t, err, fmt.Sprintf("transaction %v found in wallet", txID), - ) -} - -// assertNodeAnnouncement compares that two node announcements match. -func assertNodeAnnouncement(t *harnessTest, n1, n2 *lnrpc.NodeUpdate) { - // Alias should match. - require.Equal(t.t, n1.Alias, n2.Alias, "alias don't match") - - // Color should match. - require.Equal(t.t, n1.Color, n2.Color, "color don't match") - - // NodeAddresses should match. - require.Equal( - t.t, len(n1.NodeAddresses), len(n2.NodeAddresses), - "node addresses don't match", - ) - - addrs := make(map[string]struct{}, len(n1.NodeAddresses)) - for _, nodeAddr := range n1.NodeAddresses { - addrs[nodeAddr.Addr] = struct{}{} - } - - for _, nodeAddr := range n2.NodeAddresses { - if _, ok := addrs[nodeAddr.Addr]; !ok { - t.Fatalf("address %v not found in node announcement", - nodeAddr.Addr) - } - } -} diff --git a/itest/lnd_channel_force_close_test.go b/itest/lnd_channel_force_close_test.go index 0857751d4..03b1955ab 100644 --- a/itest/lnd_channel_force_close_test.go +++ b/itest/lnd_channel_force_close_test.go @@ -1087,3 +1087,71 @@ func assertReports(ht *lntemp.HarnessTest, hn *node.HarnessNode, require.Equal(ht, expected, res) } } + +// checkCommitmentMaturity checks that both the maturity height and blocks +// maturity height are as expected. +// +// NOTE: only used in current test file. +func checkCommitmentMaturity(forceClose lntemp.PendingForceClose, + maturityHeight uint32, blocksTilMaturity int32) error { + + if forceClose.MaturityHeight != maturityHeight { + return fmt.Errorf("expected commitment maturity height to be "+ + "%d, found %d instead", maturityHeight, + forceClose.MaturityHeight) + } + if forceClose.BlocksTilMaturity != blocksTilMaturity { + return fmt.Errorf("expected commitment blocks til maturity to "+ + "be %d, found %d instead", blocksTilMaturity, + forceClose.BlocksTilMaturity) + } + + return nil +} + +// checkForceClosedChannelNumHtlcs verifies that a force closed channel has the +// proper number of htlcs. +// +// NOTE: only used in current test file. +func checkPendingChannelNumHtlcs( + forceClose *lnrpc.PendingChannelsResponse_ForceClosedChannel, + expectedNumHtlcs int) error { + + if len(forceClose.PendingHtlcs) != expectedNumHtlcs { + return fmt.Errorf("expected force closed channel to have %d "+ + "pending htlcs, found %d instead", expectedNumHtlcs, + len(forceClose.PendingHtlcs)) + } + + return nil +} + +// checkPendingHtlcStageAndMaturity uniformly tests all pending htlc's belonging +// to a force closed channel, testing for the expected stage number, blocks till +// maturity, and the maturity height. +// +// NOTE: only used in current test file. +func checkPendingHtlcStageAndMaturity( + forceClose *lnrpc.PendingChannelsResponse_ForceClosedChannel, + stage, maturityHeight uint32, blocksTillMaturity int32) error { + + for _, pendingHtlc := range forceClose.PendingHtlcs { + if pendingHtlc.Stage != stage { + return fmt.Errorf("expected pending htlc to be stage "+ + "%d, found %d", stage, pendingHtlc.Stage) + } + if pendingHtlc.MaturityHeight != maturityHeight { + return fmt.Errorf("expected pending htlc maturity "+ + "height to be %d, instead has %d", + maturityHeight, pendingHtlc.MaturityHeight) + } + if pendingHtlc.BlocksTilMaturity != blocksTillMaturity { + return fmt.Errorf("expected pending htlc blocks til "+ + "maturity to be %d, instead has %d", + blocksTillMaturity, + pendingHtlc.BlocksTilMaturity) + } + } + + return nil +} diff --git a/itest/lnd_channel_policy_test.go b/itest/lnd_channel_policy_test.go index faac28c39..b605ea8b7 100644 --- a/itest/lnd_channel_policy_test.go +++ b/itest/lnd_channel_policy_test.go @@ -12,25 +12,10 @@ import ( "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lntemp" "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/require" ) -// assertPolicyUpdate checks that a given policy update has been received by a -// list of given nodes. -// TODO(yy): delete. -func assertPolicyUpdate(t *harnessTest, nodes []*lntest.HarnessNode, - advertisingNode string, policy *lnrpc.RoutingPolicy, - chanPoint *lnrpc.ChannelPoint) { - - for _, node := range nodes { - assertChannelPolicyUpdate( - t.t, node, advertisingNode, policy, chanPoint, false, - ) - } -} - // testUpdateChannelPolicy tests that policy updates made to a channel // gets propagated to other nodes in the network. func testUpdateChannelPolicy(ht *lntemp.HarnessTest) { diff --git a/itest/lnd_etcd_failover_test.go b/itest/lnd_etcd_failover_test.go index 90bd5fbbe..0488191f8 100644 --- a/itest/lnd_etcd_failover_test.go +++ b/itest/lnd_etcd_failover_test.go @@ -13,7 +13,7 @@ import ( "github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntemp/node" "github.com/stretchr/testify/require" ) @@ -56,8 +56,8 @@ func testEtcdFailover(ht *lntemp.HarnessTest) { func testEtcdFailoverCase(ht *lntemp.HarnessTest, kill bool) { etcdCfg, cleanup, err := kvdb.StartEtcdTestBackend( - ht.T.TempDir(), uint16(lntest.NextAvailablePort()), - uint16(lntest.NextAvailablePort()), "", + ht.T.TempDir(), uint16(node.NextAvailablePort()), + uint16(node.NextAvailablePort()), "", ) require.NoError(ht, err, "Failed to start etcd instance") defer cleanup() diff --git a/itest/lnd_multi-hop_test.go b/itest/lnd_multi-hop_test.go index 8f738dc7c..287444ac9 100644 --- a/itest/lnd_multi-hop_test.go +++ b/itest/lnd_multi-hop_test.go @@ -15,7 +15,6 @@ import ( "github.com/lightningnetwork/lnd/lntemp" "github.com/lightningnetwork/lnd/lntemp/node" "github.com/lightningnetwork/lnd/lntemp/rpc" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/routing" "github.com/stretchr/testify/require" @@ -52,102 +51,6 @@ var commitWithZeroConf = []struct { }, } -// waitForInvoiceAccepted waits until the specified invoice moved to the -// accepted state by the node. -func waitForInvoiceAccepted(t *harnessTest, node *lntest.HarnessNode, - payHash lntypes.Hash) { - - ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) - defer cancel() - invoiceUpdates, err := node.SubscribeSingleInvoice(ctx, - &invoicesrpc.SubscribeSingleInvoiceRequest{ - RHash: payHash[:], - }, - ) - if err != nil { - t.Fatalf("subscribe single invoice: %v", err) - } - - for { - update, err := invoiceUpdates.Recv() - if err != nil { - t.Fatalf("invoice update err: %v", err) - } - if update.State == lnrpc.Invoice_ACCEPTED { - break - } - } -} - -// checkPaymentStatus asserts that the given node list a payment with the given -// preimage has the expected status. -func checkPaymentStatus(node *lntest.HarnessNode, preimage lntypes.Preimage, - status lnrpc.Payment_PaymentStatus) error { - - ctxb := context.Background() - ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - req := &lnrpc.ListPaymentsRequest{ - IncludeIncomplete: true, - } - paymentsResp, err := node.ListPayments(ctxt, req) - if err != nil { - return fmt.Errorf("error when obtaining Alice payments: %v", - err) - } - - payHash := preimage.Hash() - var found bool - for _, p := range paymentsResp.Payments { - if p.PaymentHash != payHash.String() { - continue - } - - found = true - if p.Status != status { - return fmt.Errorf("expected payment status "+ - "%v, got %v", status, p.Status) - } - - switch status { - // If this expected status is SUCCEEDED, we expect the final preimage. - case lnrpc.Payment_SUCCEEDED: - if p.PaymentPreimage != preimage.String() { - return fmt.Errorf("preimage doesn't match: %v vs %v", - p.PaymentPreimage, preimage.String()) - } - - // Otherwise we expect an all-zero preimage. - default: - if p.PaymentPreimage != (lntypes.Preimage{}).String() { - return fmt.Errorf("expected zero preimage, got %v", - p.PaymentPreimage) - } - } - } - - if !found { - return fmt.Errorf("payment with payment hash %v not found "+ - "in response", payHash) - } - - return nil -} - -// assertAllTxesSpendFrom asserts that all txes in the list spend from the given -// tx. -func assertAllTxesSpendFrom(t *harnessTest, txes []*wire.MsgTx, - prevTxid chainhash.Hash) { - - for _, tx := range txes { - if tx.TxIn[0].PreviousOutPoint.Hash != prevTxid { - t.Fatalf("tx %v did not spend from %v", - tx.TxHash(), prevTxid) - } - } -} - // caseRunner defines a single test case runner. type caseRunner func(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) diff --git a/itest/lnd_network_test.go b/itest/lnd_network_test.go index 6763a952e..9244484a6 100644 --- a/itest/lnd_network_test.go +++ b/itest/lnd_network_test.go @@ -8,7 +8,6 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lntemp" "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) @@ -105,7 +104,7 @@ func testReconnectAfterIPChange(ht *lntemp.HarnessTest) { // We derive an extra port for Dave, and we initialise his node with // the port advertised as `--externalip` arguments. - ip2 := lntest.NextAvailablePort() + ip2 := node.NextAvailablePort() // Create a new node, Dave, which will initialize a P2P port for him. daveArgs := []string{fmt.Sprintf("--externalip=127.0.0.1:%d", ip2)} @@ -184,7 +183,7 @@ func testReconnectAfterIPChange(ht *lntemp.HarnessTest) { // address. // Change Dave's listening port and restart. - dave.Cfg.P2PPort = lntest.NextAvailablePort() + dave.Cfg.P2PPort = node.NextAvailablePort() dave.Cfg.ExtraArgs = []string{ fmt.Sprintf( "--externalip=127.0.0.1:%d", dave.Cfg.P2PPort, diff --git a/itest/lnd_neutrino_test.go b/itest/lnd_neutrino_test.go index 902eac430..acf56f9d8 100644 --- a/itest/lnd_neutrino_test.go +++ b/itest/lnd_neutrino_test.go @@ -3,14 +3,13 @@ package itest import ( "github.com/lightningnetwork/lnd/lnrpc/neutrinorpc" "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" ) // testNeutrino checks that the neutrino sub-server can fetch compact // block filters, server status and connect to a connected peer. func testNeutrino(ht *lntemp.HarnessTest) { - if ht.ChainBackendName() != lntest.NeutrinoBackendName { + if !ht.IsNeutrinoBackend() { ht.Skipf("skipping test for non neutrino backends") } diff --git a/itest/lnd_psbt_test.go b/itest/lnd_psbt_test.go index 286abad6e..5cc0865bc 100644 --- a/itest/lnd_psbt_test.go +++ b/itest/lnd_psbt_test.go @@ -22,7 +22,6 @@ import ( "github.com/lightningnetwork/lnd/lnrpc/walletrpc" "github.com/lightningnetwork/lnd/lntemp" "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" ) @@ -1187,60 +1186,6 @@ func deriveInternalKey(ht *lntemp.HarnessTest, return keyDesc, parsedPubKey, fullDerivationPath } -// openChannelPsbt attempts to open a channel between srcNode and destNode with -// the passed channel funding parameters. If the passed context has a timeout, -// then if the timeout is reached before the channel pending notification is -// received, an error is returned. An error is returned if the expected step -// of funding the PSBT is not received from the source node. -func openChannelPsbt(ctx context.Context, srcNode, destNode *lntest.HarnessNode, - p lntest.OpenChannelParams) (lnrpc.Lightning_OpenChannelClient, []byte, - error) { - - // Wait until srcNode and destNode have the latest chain synced. - // Otherwise, we may run into a check within the funding manager that - // prevents any funding workflows from being kicked off if the chain - // isn't yet synced. - if err := srcNode.WaitForBlockchainSync(); err != nil { - return nil, nil, fmt.Errorf("unable to sync srcNode chain: %v", - err) - } - if err := destNode.WaitForBlockchainSync(); err != nil { - return nil, nil, fmt.Errorf("unable to sync destNode chain: %v", - err) - } - - // Send the request to open a channel to the source node now. This will - // open a long-lived stream where we'll receive status updates about the - // progress of the channel. - respStream, err := srcNode.OpenChannel(ctx, &lnrpc.OpenChannelRequest{ - NodePubkey: destNode.PubKey[:], - LocalFundingAmount: int64(p.Amt), - PushSat: int64(p.PushAmt), - Private: p.Private, - SpendUnconfirmed: p.SpendUnconfirmed, - MinHtlcMsat: int64(p.MinHtlc), - FundingShim: p.FundingShim, - }) - if err != nil { - return nil, nil, fmt.Errorf("unable to open channel between "+ - "source and dest: %v", err) - } - - // Consume the "PSBT funding ready" update. This waits until the node - // notifies us that the PSBT can now be funded. - resp, err := receiveChanUpdate(ctx, respStream) - if err != nil { - return nil, nil, fmt.Errorf("unable to consume channel update "+ - "message: %v", err) - } - upd, ok := resp.Update.(*lnrpc.OpenStatusUpdate_PsbtFund) - if !ok { - return nil, nil, fmt.Errorf("expected PSBT funding update, "+ - "instead got %v", resp) - } - return respStream, upd.PsbtFund.Psbt, nil -} - // receiveChanUpdate waits until a message is received on the stream or the // context is canceled. The context must have a timeout or must be canceled // in case no message is received, otherwise this function will block forever. diff --git a/itest/lnd_revocation_test.go b/itest/lnd_revocation_test.go index bff6e6760..0184d634b 100644 --- a/itest/lnd_revocation_test.go +++ b/itest/lnd_revocation_test.go @@ -13,7 +13,6 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/wtclientrpc" "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) @@ -158,7 +157,7 @@ func testRevokedCloseRetribution(ht *lntemp.HarnessTest) { // tx's confHeight+CSV-1 blocks and since we've already mined one that // included the justice tx we only need to mine extra DefaultCSV-2 // blocks to unlock it. - ht.MineBlocks(lntest.DefaultCSV - 2) + ht.MineBlocks(defaultCSV - 2) ht.AssertNumPendingForceClose(bob, 0) } diff --git a/itest/lnd_test.go b/itest/lnd_test.go index fa3606d0a..195890ac2 100644 --- a/itest/lnd_test.go +++ b/itest/lnd_test.go @@ -13,7 +13,7 @@ import ( "github.com/btcsuite/btcd/integration/rpctest" "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntemp/node" "github.com/stretchr/testify/require" "google.golang.org/grpc/grpclog" ) @@ -62,7 +62,7 @@ func TestLightningNetworkDaemon(t *testing.T) { // Get the test cases to be run in this tranche. testCases, trancheIndex, trancheOffset := getTestCaseSplitTranche() - lntest.ApplyPortOffset(uint32(trancheIndex) * 1000) + node.ApplyPortOffset(uint32(trancheIndex) * 1000) // Create a simple fee service. feeService := lntemp.NewFeeService(t) @@ -188,7 +188,7 @@ func init() { // Before we start any node, we need to make sure that any btcd node // that is started through the RPC harness uses a unique port as well // to avoid any port collisions. - rpctest.ListenAddressGenerator = lntest.GenerateBtcdListenerAddresses + rpctest.ListenAddressGenerator = node.GenerateBtcdListenerAddresses // Swap out grpc's default logger with out fake logger which drops the // statements on the floor. diff --git a/itest/lnd_zero_conf_test.go b/itest/lnd_zero_conf_test.go index bf5de369a..61aadb708 100644 --- a/itest/lnd_zero_conf_test.go +++ b/itest/lnd_zero_conf_test.go @@ -16,7 +16,6 @@ import ( "github.com/lightningnetwork/lnd/lntemp" "github.com/lightningnetwork/lnd/lntemp/node" "github.com/lightningnetwork/lnd/lntemp/rpc" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/require" @@ -893,7 +892,7 @@ func acceptChannel(t *testing.T, zeroConf bool, stream rpc.AcceptorClient) { // be deleted from the channel graph. This was previously the case due to logic // in the function DisconnectBlockAtHeight. func testZeroConfReorg(ht *lntemp.HarnessTest) { - if ht.ChainBackendName() == lntest.NeutrinoBackendName { + if ht.IsNeutrinoBackend() { ht.Skipf("skipping zero-conf reorg test for neutrino backend") } diff --git a/itest/test_harness.go b/itest/test_harness.go deleted file mode 100644 index 88f11ba08..000000000 --- a/itest/test_harness.go +++ /dev/null @@ -1,351 +0,0 @@ -package itest - -import ( - "bytes" - "context" - "flag" - "fmt" - "math" - "os" - "path/filepath" - "runtime" - "testing" - "time" - - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/wire" - "github.com/go-errors/errors" - "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntest" - "github.com/lightningnetwork/lnd/lntest/wait" - "github.com/stretchr/testify/require" -) - -var ( - harnessNetParams = &chaincfg.RegressionNetParams - - // lndExecutable is the full path to the lnd binary. - lndExecutable = flag.String( - "lndexec", itestLndBinary, "full path to lnd binary", - ) - - slowMineDelay = 20 * time.Millisecond -) - -const ( - testFeeBase = 1e+6 - defaultCSV = lntest.DefaultCSV - defaultTimeout = wait.DefaultTimeout - minerMempoolTimeout = wait.MinerMempoolTimeout - channelCloseTimeout = wait.ChannelCloseTimeout - 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 -) - -// harnessTest wraps a regular testing.T providing enhanced error detection -// and propagation. All error will be augmented with a full stack-trace in -// order to aid in debugging. Additionally, any panics caused by active -// test cases will also be handled and represented as fatals. -type harnessTest struct { - t *testing.T - - // testCase is populated during test execution and represents the - // current test case. - testCase *testCase - - // lndHarness is a reference to the current network harness. Will be - // nil if not yet set up. - lndHarness *lntest.NetworkHarness -} - -// newHarnessTest creates a new instance of a harnessTest from a regular -// testing.T instance. -func newHarnessTest(t *testing.T, net *lntest.NetworkHarness) *harnessTest { - return &harnessTest{t, nil, net} -} - -// Skipf calls the underlying testing.T's Skip method, causing the current test -// to be skipped. -func (h *harnessTest) Skipf(format string, args ...interface{}) { - h.t.Skipf(format, args...) -} - -// Fatalf causes the current active test case to fail with a fatal error. All -// integration tests should mark test failures solely with this method due to -// the error stack traces it produces. -func (h *harnessTest) Fatalf(format string, a ...interface{}) { - if h.lndHarness != nil { - h.lndHarness.SaveProfilesPages(h.t) - } - - stacktrace := errors.Wrap(fmt.Sprintf(format, a...), 1).ErrorStack() - - if h.testCase != nil { - h.t.Fatalf("Failed: (%v): exited with error: \n"+ - "%v", h.testCase.name, stacktrace) - } else { - h.t.Fatalf("Error outside of test: %v", stacktrace) - } -} - -// RunTestCase executes a harness test case. Any errors or panics will be -// represented as fatal. -func (h *harnessTest) RunTestCase(testCase *testCase) { - h.testCase = testCase - defer func() { - h.testCase = nil - }() - - defer func() { - if err := recover(); err != nil { - description := errors.Wrap(err, 2).ErrorStack() - h.t.Fatalf("Failed: (%v) panicked with: \n%v", - h.testCase.name, description) - } - }() - - testCase.test(h.lndHarness, h) -} - -func (h *harnessTest) Logf(format string, args ...interface{}) { - h.t.Logf(format, args...) -} - -func (h *harnessTest) Log(args ...interface{}) { - h.t.Log(args...) -} - -func (h *harnessTest) getLndBinary() string { - binary := itestLndBinary - lndExec := "" - if lndExecutable != nil && *lndExecutable != "" { - lndExec = *lndExecutable - } - if lndExec == "" && runtime.GOOS == "windows" { - // Windows (even in a bash like environment like git bash as on - // Travis) doesn't seem to like relative paths to exe files... - currentDir, err := os.Getwd() - if err != nil { - h.Fatalf("unable to get working directory: %v", err) - } - targetPath := filepath.Join(currentDir, "../../lnd-itest.exe") - binary, err = filepath.Abs(targetPath) - if err != nil { - h.Fatalf("unable to get absolute path: %v", err) - } - } else if lndExec != "" { - binary = lndExec - } - - return binary -} - -type testCase struct { - name string - test func(net *lntest.NetworkHarness, t *harnessTest) -} - -// waitForTxInMempool polls until finding one transaction in the provided -// miner's mempool. An error is returned if *one* transaction isn't found within -// the given timeout. -func waitForTxInMempool(miner *rpcclient.Client, - timeout time.Duration) (*chainhash.Hash, error) { - - txs, err := waitForNTxsInMempool(miner, 1, timeout) - if err != nil { - return nil, err - } - - return txs[0], err -} - -// waitForNTxsInMempool polls until finding the desired number of transactions -// in the provided miner's mempool. An error is returned if this number is not -// met after the given timeout. -func waitForNTxsInMempool(miner *rpcclient.Client, n int, - timeout time.Duration) ([]*chainhash.Hash, error) { - - breakTimeout := time.After(timeout) - ticker := time.NewTicker(50 * time.Millisecond) - defer ticker.Stop() - - var err error - var mempool []*chainhash.Hash - for { - select { - case <-breakTimeout: - return nil, fmt.Errorf("wanted %v, found %v txs "+ - "in mempool: %v", n, len(mempool), mempool) - case <-ticker.C: - mempool, err = miner.GetRawMempool() - if err != nil { - return nil, err - } - - if len(mempool) == n { - return mempool, nil - } - } - } -} - -// mineBlocks mine 'num' of blocks and check that blocks are present in -// node blockchain. numTxs should be set to the number of transactions -// (excluding the coinbase) we expect to be included in the first mined block. -func mineBlocksFast(t *harnessTest, net *lntest.NetworkHarness, - num uint32, numTxs int) []*wire.MsgBlock { - - // If we expect transactions to be included in the blocks we'll mine, - // we wait here until they are seen in the miner's mempool. - var txids []*chainhash.Hash - var err error - if numTxs > 0 { - txids, err = waitForNTxsInMempool( - net.Miner.Client, numTxs, minerMempoolTimeout, - ) - if err != nil { - t.Fatalf("unable to find txns in mempool: %v", err) - } - } - - blocks := make([]*wire.MsgBlock, num) - - blockHashes, err := net.Miner.Client.Generate(num) - if err != nil { - t.Fatalf("unable to generate blocks: %v", err) - } - - for i, blockHash := range blockHashes { - block, err := net.Miner.Client.GetBlock(blockHash) - if err != nil { - t.Fatalf("unable to get block: %v", err) - } - - blocks[i] = block - } - - // Finally, assert that all the transactions were included in the first - // block. - for _, txid := range txids { - assertTxInBlock(t, blocks[0], txid) - } - - return blocks -} - -// mineBlocksSlow mines 'num' of blocks and checks that blocks are present in -// the mining node's blockchain. numTxs should be set to the number of -// transactions (excluding the coinbase) we expect to be included in the first -// mined block. Between each mined block an artificial delay is introduced to -// give all network participants time to catch up. -// -// NOTE: This function currently is just an alias for mineBlocksSlow. -func mineBlocks(t *harnessTest, net *lntest.NetworkHarness, - num uint32, numTxs int) []*wire.MsgBlock { - - return mineBlocksSlow(t, net, num, numTxs) -} - -// mineBlocksSlow mines 'num' of blocks and checks that blocks are present in -// the mining node's blockchain. numTxs should be set to the number of -// transactions (excluding the coinbase) we expect to be included in the first -// mined block. Between each mined block an artificial delay is introduced to -// give all network participants time to catch up. -func mineBlocksSlow(t *harnessTest, net *lntest.NetworkHarness, - num uint32, numTxs int) []*wire.MsgBlock { - - t.t.Helper() - - // If we expect transactions to be included in the blocks we'll mine, - // we wait here until they are seen in the miner's mempool. - var txids []*chainhash.Hash - var err error - if numTxs > 0 { - txids, err = waitForNTxsInMempool( - net.Miner.Client, numTxs, minerMempoolTimeout, - ) - require.NoError(t.t, err, "unable to find txns in mempool") - } - - blocks := make([]*wire.MsgBlock, num) - blockHashes := make([]*chainhash.Hash, 0, num) - - for i := uint32(0); i < num; i++ { - generatedHashes, err := net.Miner.Client.Generate(1) - require.NoError(t.t, err, "generate blocks") - blockHashes = append(blockHashes, generatedHashes...) - - time.Sleep(slowMineDelay) - } - - for i, blockHash := range blockHashes { - block, err := net.Miner.Client.GetBlock(blockHash) - require.NoError(t.t, err, "get blocks") - - blocks[i] = block - } - - // Finally, assert that all the transactions were included in the first - // block. - for _, txid := range txids { - assertTxInBlock(t, blocks[0], txid) - } - - return blocks -} - -func assertTxInBlock(t *harnessTest, block *wire.MsgBlock, txid *chainhash.Hash) { - for _, tx := range block.Transactions { - sha := tx.TxHash() - if bytes.Equal(txid[:], sha[:]) { - return - } - } - - t.Fatalf("tx was not included in block") -} - -func assertWalletUnspent(t *harnessTest, node *lntest.HarnessNode, - out *lnrpc.OutPoint, account string) { - - t.t.Helper() - - ctxb := context.Background() - err := wait.NoError(func() error { - ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - unspent, err := node.WalletKitClient.ListUnspent( - ctxt, &walletrpc.ListUnspentRequest{ - Account: account, - }, - ) - if err != nil { - return err - } - - err = errors.New("tx with wanted txhash never found") - for _, utxo := range unspent.Utxos { - if !bytes.Equal(utxo.Outpoint.TxidBytes, out.TxidBytes) { - continue - } - - err = errors.New("wanted output is not a wallet utxo") - if utxo.Outpoint.OutputIndex != out.OutputIndex { - continue - } - - return nil - } - - return err - }, defaultTimeout) - require.NoError(t.t, err) -} diff --git a/itest/utils.go b/itest/utils.go index 4995a0beb..828ee04e3 100644 --- a/itest/utils.go +++ b/itest/utils.go @@ -1,211 +1,42 @@ package itest import ( - "context" - "crypto/rand" - "fmt" - "io" - "time" + "flag" + "math" "github.com/btcsuite/btcd/btcutil" - "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/wire" - "github.com/go-errors/errors" + "github.com/btcsuite/btcd/chaincfg" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntest" + "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" - "github.com/stretchr/testify/require" ) -// completePaymentRequests sends payments from a lightning node to complete all -// payment requests. If the awaitResponse parameter is true, this function -// does not return until all payments successfully complete without errors. -func completePaymentRequests(client lnrpc.LightningClient, - routerClient routerrpc.RouterClient, paymentRequests []string, - awaitResponse bool) error { +const ( + testFeeBase = 1e+6 + defaultCSV = node.DefaultCSV + defaultTimeout = wait.DefaultTimeout + itestLndBinary = "../../lnd-itest" + anchorSize = 330 + noFeeLimitMsat = math.MaxInt64 - ctxb := context.Background() - ctx, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() + AddrTypeWitnessPubkeyHash = lnrpc.AddressType_WITNESS_PUBKEY_HASH + AddrTypeNestedPubkeyHash = lnrpc.AddressType_NESTED_PUBKEY_HASH + AddrTypeTaprootPubkey = lnrpc.AddressType_TAPROOT_PUBKEY +) - // We start by getting the current state of the client's channels. This - // is needed to ensure the payments actually have been committed before - // we return. - req := &lnrpc.ListChannelsRequest{} - listResp, err := client.ListChannels(ctx, req) - if err != nil { - return err - } +var ( + harnessNetParams = &chaincfg.RegressionNetParams - // send sends a payment and returns an error if it doesn't succeeded. - send := func(payReq string) error { - ctxc, cancel := context.WithCancel(ctx) - defer cancel() - - payStream, err := routerClient.SendPaymentV2( - ctxc, - &routerrpc.SendPaymentRequest{ - PaymentRequest: payReq, - TimeoutSeconds: 60, - FeeLimitMsat: noFeeLimitMsat, - }, - ) - if err != nil { - return err - } - - resp, err := getPaymentResult(payStream) - if err != nil { - return err - } - if resp.Status != lnrpc.Payment_SUCCEEDED { - return errors.New(resp.FailureReason) - } - - return nil - } - - // Launch all payments simultaneously. - results := make(chan error) - for _, payReq := range paymentRequests { - go func(payReq string) { - err := send(payReq) - if awaitResponse { - results <- err - } - }(payReq) - } - - // If awaiting a response, verify that all payments succeeded. - if awaitResponse { - for range paymentRequests { - err := <-results - if err != nil { - return err - } - } - return nil - } - - // We are not waiting for feedback in the form of a response, but we - // should still wait long enough for the server to receive and handle - // the send before cancelling the request. We wait for the number of - // updates to one of our channels has increased before we return. - err = wait.Predicate(func() bool { - newListResp, err := client.ListChannels(ctx, req) - if err != nil { - return false - } - - // If the number of open channels is now lower than before - // attempting the payments, it means one of the payments - // triggered a force closure (for example, due to an incorrect - // preimage). Return early since it's clear the payment was - // attempted. - if len(newListResp.Channels) < len(listResp.Channels) { - return true - } - - for _, c1 := range listResp.Channels { - for _, c2 := range newListResp.Channels { - if c1.ChannelPoint != c2.ChannelPoint { - continue - } - - // If this channel has an increased numbr of - // updates, we assume the payments are - // committed, and we can return. - if c2.NumUpdates > c1.NumUpdates { - return true - } - } - } - - return false - }, defaultTimeout) - if err != nil { - return err - } - - return nil -} - -// makeFakePayHash creates random pre image hash. -func makeFakePayHash(t *harnessTest) []byte { - randBuf := make([]byte, 32) - - if _, err := rand.Read(randBuf); err != nil { - t.Fatalf("internal error, cannot generate random string: %v", err) - } - - return randBuf -} - -// createPayReqs is a helper method that will create a slice of payment -// requests for the given node. -func createPayReqs(node *lntest.HarnessNode, paymentAmt btcutil.Amount, - numInvoices int) ([]string, [][]byte, []*lnrpc.Invoice, error) { - - payReqs := make([]string, numInvoices) - rHashes := make([][]byte, numInvoices) - invoices := make([]*lnrpc.Invoice, numInvoices) - for i := 0; i < numInvoices; i++ { - preimage := make([]byte, 32) - _, err := rand.Read(preimage) - if err != nil { - return nil, nil, nil, fmt.Errorf("unable to generate "+ - "preimage: %v", err) - } - invoice := &lnrpc.Invoice{ - Memo: "testing", - RPreimage: preimage, - Value: int64(paymentAmt), - } - ctxt, _ := context.WithTimeout( - context.Background(), defaultTimeout, - ) - resp, err := node.AddInvoice(ctxt, invoice) - if err != nil { - return nil, nil, nil, fmt.Errorf("unable to add "+ - "invoice: %v", err) - } - - // Set the payment address in the invoice so the caller can - // properly use it. - invoice.PaymentAddr = resp.PaymentAddr - - payReqs[i] = resp.PaymentRequest - rHashes[i] = resp.RHash - invoices[i] = invoice - } - return payReqs, rHashes, invoices, nil -} - -// getChanInfo is a helper method for getting channel info for a node's sole -// channel. -func getChanInfo(node *lntest.HarnessNode) (*lnrpc.Channel, error) { - ctxb := context.Background() - ctx, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - req := &lnrpc.ListChannelsRequest{} - channelInfo, err := node.ListChannels(ctx, req) - if err != nil { - return nil, err - } - if len(channelInfo.Channels) != 1 { - return nil, fmt.Errorf("node should only have a single "+ - "channel, instead it has %v", len(channelInfo.Channels)) - } - - return channelInfo.Channels[0], nil -} + // lndExecutable is the full path to the lnd binary. + lndExecutable = flag.String( + "lndexec", itestLndBinary, "full path to lnd binary", + ) +) // commitTypeHasAnchors returns whether commitType uses anchor outputs. func commitTypeHasAnchors(commitType lnrpc.CommitmentType) bool { @@ -247,8 +78,9 @@ func calcStaticFee(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { feePerKw = chainfee.SatPerKWeight( lntemp.DefaultFeeRateSatPerKw, ) - commitWeight = input.CommitWeight - anchors = btcutil.Amount(0) + commitWeight = input.CommitWeight + anchors = btcutil.Amount(0) + defaultSatPerVByte = lnwallet.DefaultAnchorsCommitMaxFeeRateSatPerVByte ) // The anchor commitment type is slightly heavier, and we must also add @@ -257,8 +89,7 @@ func calcStaticFee(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { // channels. if commitTypeHasAnchors(c) { feePerKw = chainfee.SatPerKVByte( - lnwallet.DefaultAnchorsCommitMaxFeeRateSatPerVByte * 1000, - ).FeePerKWeight() + defaultSatPerVByte * 1000).FeePerKWeight() commitWeight = input.AnchorCommitWeight anchors = 2 * anchorSize } @@ -267,29 +98,6 @@ func calcStaticFee(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { anchors } -// channelCommitType retrieves the active channel commitment type for the given -// chan point. -func channelCommitType(node *lntest.HarnessNode, - chanPoint *lnrpc.ChannelPoint) (lnrpc.CommitmentType, error) { - - ctxb := context.Background() - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - - req := &lnrpc.ListChannelsRequest{} - channels, err := node.ListChannels(ctxt, req) - if err != nil { - return 0, fmt.Errorf("listchannels failed: %v", err) - } - - for _, c := range channels.Channels { - if c.ChannelPoint == txStr(chanPoint) { - return c.CommitmentType, nil - } - } - - return 0, fmt.Errorf("channel point %v not found", chanPoint) -} - // 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. @@ -298,171 +106,3 @@ func calculateMaxHtlc(chanCap btcutil.Amount) uint64 { max := lnwire.NewMSatFromSatoshis(chanCap) - reserve return uint64(max) } - -// waitForNodeBlockHeight queries the node for its current block height until -// it reaches the passed height. -func waitForNodeBlockHeight(node *lntest.HarnessNode, height int32) error { - ctxb := context.Background() - ctx, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - var predErr error - err := wait.Predicate(func() bool { - info, err := node.GetInfo(ctx, &lnrpc.GetInfoRequest{}) - if err != nil { - predErr = err - return false - } - - if int32(info.BlockHeight) != height { - predErr = fmt.Errorf("expected block height to "+ - "be %v, was %v", height, info.BlockHeight) - return false - } - return true - }, defaultTimeout) - if err != nil { - return predErr - } - return nil -} - -// getNTxsFromMempool polls until finding the desired number of transactions in -// the provided miner's mempool and returns the full transactions to the caller. -func getNTxsFromMempool(miner *rpcclient.Client, n int, - timeout time.Duration) ([]*wire.MsgTx, error) { - - txids, err := waitForNTxsInMempool(miner, n, timeout) - if err != nil { - return nil, err - } - - var txes []*wire.MsgTx - for _, txid := range txids { - tx, err := miner.GetRawTransaction(txid) - if err != nil { - return nil, err - } - txes = append(txes, tx.MsgTx()) - } - return txes, nil -} - -// getTxFee retrieves parent transactions and reconstructs the fee paid. -func getTxFee(miner *rpcclient.Client, tx *wire.MsgTx) (btcutil.Amount, error) { - var balance btcutil.Amount - for _, in := range tx.TxIn { - parentHash := in.PreviousOutPoint.Hash - rawTx, err := miner.GetRawTransaction(&parentHash) - if err != nil { - return 0, err - } - parent := rawTx.MsgTx() - balance += btcutil.Amount( - parent.TxOut[in.PreviousOutPoint.Index].Value, - ) - } - - for _, out := range tx.TxOut { - balance -= btcutil.Amount(out.Value) - } - - return balance, nil -} - -// channelSubscription houses the proxied update and error chans for a node's -// channel subscriptions. -type channelSubscription struct { - updateChan chan *lnrpc.ChannelEventUpdate - errChan chan error - quit chan struct{} -} - -// subscribeChannelNotifications subscribes to channel updates and launches a -// goroutine that forwards these to the returned channel. -func subscribeChannelNotifications(ctxb context.Context, t *harnessTest, - node *lntest.HarnessNode) channelSubscription { - - // We'll first start by establishing a notification client which will - // send us notifications upon channels becoming active, inactive or - // closed. - req := &lnrpc.ChannelEventSubscription{} - ctx, cancelFunc := context.WithCancel(ctxb) - - chanUpdateClient, err := node.SubscribeChannelEvents(ctx, req) - if err != nil { - t.Fatalf("unable to create channel update client: %v", err) - } - - // We'll launch a goroutine that will be responsible for proxying all - // notifications recv'd from the client into the channel below. - errChan := make(chan error, 1) - quit := make(chan struct{}) - chanUpdates := make(chan *lnrpc.ChannelEventUpdate, 20) - go func() { - defer cancelFunc() - - for { - select { - case <-quit: - return - default: - chanUpdate, err := chanUpdateClient.Recv() - select { - case <-quit: - return - default: - } - - if err == io.EOF { - return - } else if err != nil { - select { - case errChan <- err: - case <-quit: - } - return - } - - select { - case chanUpdates <- chanUpdate: - case <-quit: - return - } - } - } - }() - - return channelSubscription{ - updateChan: chanUpdates, - errChan: errChan, - quit: quit, - } -} - -// findTxAtHeight gets all of the transactions that a node's wallet has a record -// of at the target height, and finds and returns the tx with the target txid, -// failing if it is not found. -func findTxAtHeight(t *harnessTest, height int32, - target string, node *lntest.HarnessNode) *lnrpc.Transaction { - - ctxb := context.Background() - ctx, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - txns, err := node.LightningClient.GetTransactions( - ctx, &lnrpc.GetTransactionsRequest{ - StartHeight: height, - EndHeight: height, - }, - ) - require.NoError(t.t, err, "could not get transactions") - - for _, tx := range txns.Transactions { - if tx.TxHash == target { - return tx - } - } - - return nil -} diff --git a/lntemp/fee_service.go b/lntemp/fee_service.go index aac4cbd1d..e89809c71 100644 --- a/lntemp/fee_service.go +++ b/lntemp/fee_service.go @@ -9,7 +9,7 @@ import ( "sync" "testing" - "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntemp/node" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/stretchr/testify/require" ) @@ -61,7 +61,7 @@ var _ WebFeeService = (*FeeService)(nil) // Start spins up a go-routine to serve fee estimates. func NewFeeService(t *testing.T) *FeeService { - port := lntest.NextAvailablePort() + port := node.NextAvailablePort() f := FeeService{ T: t, url: fmt.Sprintf( diff --git a/lntemp/harness.go b/lntemp/harness.go index cc11ec9ae..9a656723c 100644 --- a/lntemp/harness.go +++ b/lntemp/harness.go @@ -19,7 +19,6 @@ import ( "github.com/lightningnetwork/lnd/lnrpc/walletrpc" "github.com/lightningnetwork/lnd/lntemp/node" "github.com/lightningnetwork/lnd/lntemp/rpc" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwire" @@ -100,7 +99,7 @@ type HarnessTest struct { // NewHarnessTest creates a new instance of a harnessTest from a regular // testing.T instance. func NewHarnessTest(t *testing.T, lndBinary string, feeService WebFeeService, - dbBackend lntest.DatabaseBackend) *HarnessTest { + dbBackend node.DatabaseBackend) *HarnessTest { // Create the run context. ctxt, cancel := context.WithCancel(context.Background()) @@ -636,7 +635,7 @@ func (h *HarnessTest) NewNodeEtcd(name string, etcdCfg *etcd.Config, leaderSessionTTL int) *node.HarnessNode { // We don't want to use the embedded etcd instance. - h.manager.dbBackend = lntest.BackendBbolt + h.manager.dbBackend = node.BackendBbolt extraArgs := node.ExtraArgsEtcd( etcdCfg, name, cluster, leaderSessionTTL, @@ -659,7 +658,7 @@ func (h *HarnessTest) NewNodeWithSeedEtcd(name string, etcdCfg *etcd.Config, leaderSessionTTL int) (*node.HarnessNode, []string, []byte) { // We don't want to use the embedded etcd instance. - h.manager.dbBackend = lntest.BackendBbolt + h.manager.dbBackend = node.BackendBbolt // Create a request to generate a new aezeed. The new seed will have // the same password as the internal wallet. @@ -1402,7 +1401,7 @@ func (h *HarnessTest) CleanupForceClose(hn *node.HarnessNode, // // The commit sweep resolver is able to broadcast the sweep tx up to // one block before the CSV elapses, so wait until defaulCSV-1. - h.MineBlocks(lntest.DefaultCSV - 1) + h.MineBlocks(node.DefaultCSV - 1) // The node should now sweep the funds, clean up by mining the sweeping // tx. diff --git a/lntemp/harness_miner.go b/lntemp/harness_miner.go index 9568a2c86..851423438 100644 --- a/lntemp/harness_miner.go +++ b/lntemp/harness_miner.go @@ -18,7 +18,7 @@ import ( "github.com/btcsuite/btcd/integration/rpctest" "github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcd/wire" - "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntemp/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) @@ -73,8 +73,8 @@ func newMiner(ctxb context.Context, t *testing.T, minerDirName, logFilename string) *HarnessMiner { handler := &rpcclient.NotificationHandlers{} - btcdBinary := lntest.GetBtcdBinary() - baseLogPath := fmt.Sprintf("%s/%s", lntest.GetLogDir(), minerDirName) + btcdBinary := node.GetBtcdBinary() + baseLogPath := fmt.Sprintf("%s/%s", node.GetLogDir(), minerDirName) args := []string{ "--rejectnonstd", diff --git a/lntemp/harness_node_manager.go b/lntemp/harness_node_manager.go index 1ee502354..4ed365a33 100644 --- a/lntemp/harness_node_manager.go +++ b/lntemp/harness_node_manager.go @@ -9,7 +9,6 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" ) @@ -30,7 +29,7 @@ type nodeManager struct { lndBinary string // dbBackend sets the database backend to use. - dbBackend lntest.DatabaseBackend + dbBackend node.DatabaseBackend // activeNodes is a map of all running nodes, format: // {pubkey: *HarnessNode}. @@ -50,7 +49,7 @@ type nodeManager struct { // newNodeManager creates a new node manager instance. func newNodeManager(lndBinary string, - dbBackend lntest.DatabaseBackend) *nodeManager { + dbBackend node.DatabaseBackend) *nodeManager { return &nodeManager{ lndBinary: lndBinary, diff --git a/lntemp/harness_setup.go b/lntemp/harness_setup.go index 8a08c03c3..4c14a4479 100644 --- a/lntemp/harness_setup.go +++ b/lntemp/harness_setup.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/btcsuite/btcd/integration/rpctest" + "github.com/lightningnetwork/lnd/lntemp/node" "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" ) @@ -23,7 +24,7 @@ func SetupHarness(t *testing.T, binaryPath, dbBackendName string, t.Log("Setting up HarnessTest...") // Parse testing flags that influence our test execution. - logDir := lntest.GetLogDir() + logDir := node.GetLogDir() require.NoError(t, os.MkdirAll(logDir, 0700), "create log dir failed") // Parse database backend @@ -82,7 +83,7 @@ func prepareMiner(ctxt context.Context, t *testing.T) *HarnessMiner { // prepareChainBackend creates a new chain backend. func prepareChainBackend(t *testing.T, - minerAddr string) (lntest.BackendConfig, func()) { + minerAddr string) (node.BackendConfig, func()) { chainBackend, cleanUp, err := lntest.NewBackend( minerAddr, harnessNetParams, @@ -96,21 +97,21 @@ func prepareChainBackend(t *testing.T, // prepareDbBackend parses a DatabaseBackend based on the name given. func prepareDbBackend(t *testing.T, - dbBackendName string) lntest.DatabaseBackend { + dbBackendName string) node.DatabaseBackend { - var dbBackend lntest.DatabaseBackend + var dbBackend node.DatabaseBackend switch dbBackendName { case "bbolt": - dbBackend = lntest.BackendBbolt + dbBackend = node.BackendBbolt case "etcd": - dbBackend = lntest.BackendEtcd + dbBackend = node.BackendEtcd case "postgres": - dbBackend = lntest.BackendPostgres + dbBackend = node.BackendPostgres case "sqlite": - dbBackend = lntest.BackendSqlite + dbBackend = node.BackendSqlite default: require.Fail(t, "unknown db backend") diff --git a/lntemp/node/config.go b/lntemp/node/config.go index ef00d1bfa..e398cad48 100644 --- a/lntemp/node/config.go +++ b/lntemp/node/config.go @@ -1,14 +1,18 @@ package node import ( + "flag" "fmt" + "io" + "net" + "os" "path" "path/filepath" + "sync/atomic" "github.com/btcsuite/btcd/chaincfg" "github.com/lightningnetwork/lnd/chanbackup" "github.com/lightningnetwork/lnd/kvdb/etcd" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" ) @@ -16,6 +20,49 @@ const ( // ListenerFormat is the format string that is used to generate local // listener addresses. ListenerFormat = "127.0.0.1:%d" + + // DefaultCSV is the CSV delay (remotedelay) we will start our test + // nodes with. + DefaultCSV = 4 + + // defaultNodePort is the start of the range for listening ports of + // harness nodes. Ports are monotonically increasing starting from this + // number and are determined by the results of NextAvailablePort(). + defaultNodePort = 5555 +) + +var ( + // lastPort is the last port determined to be free for use by a new + // node. It should be used atomically. + lastPort uint32 = defaultNodePort + + // logOutput is a flag that can be set to append the output from the + // seed nodes to log files. + logOutput = flag.Bool("logoutput", false, + "log output from node n to file output-n.log") + + // logSubDir is the default directory where the logs are written to if + // logOutput is true. + logSubDir = flag.String("logdir", ".", "default dir to write logs to") + + // goroutineDump is a flag that can be set to dump the active + // goroutines of test nodes on failure. + goroutineDump = flag.Bool("goroutinedump", false, + "write goroutine dump from node n to file pprof-n.log") + + // btcdExecutable is the full path to the btcd binary. + btcdExecutable = flag.String( + "btcdexec", "", "full path to btcd binary", + ) +) + +type DatabaseBackend int + +const ( + BackendBbolt DatabaseBackend = iota + BackendEtcd + BackendPostgres + BackendSqlite ) // Option is a function for updating a node's configuration. @@ -74,7 +121,7 @@ type BaseNodeConfig struct { FeeURL string - DbBackend lntest.DatabaseBackend + DbBackend DatabaseBackend PostgresDsn string // NodeID is a unique ID used to identify the node. @@ -127,16 +174,16 @@ func (cfg BaseNodeConfig) ChanBackupPath() string { // current lightning network test. func (cfg *BaseNodeConfig) GenerateListeningPorts() { if cfg.P2PPort == 0 { - cfg.P2PPort = lntest.NextAvailablePort() + cfg.P2PPort = NextAvailablePort() } if cfg.RPCPort == 0 { - cfg.RPCPort = lntest.NextAvailablePort() + cfg.RPCPort = NextAvailablePort() } if cfg.RESTPort == 0 { - cfg.RESTPort = lntest.NextAvailablePort() + cfg.RESTPort = NextAvailablePort() } if cfg.ProfilePort == 0 { - cfg.ProfilePort = lntest.NextAvailablePort() + cfg.ProfilePort = NextAvailablePort() } } @@ -170,8 +217,7 @@ func (cfg *BaseNodeConfig) GenArgs() []string { "--accept-keysend", "--keep-failed-payment-attempts", fmt.Sprintf("--db.batch-commit-interval=%v", commitInterval), - fmt.Sprintf("--bitcoin.defaultremotedelay=%v", - lntest.DefaultCSV), + fmt.Sprintf("--bitcoin.defaultremotedelay=%v", DefaultCSV), fmt.Sprintf("--rpclisten=%v", cfg.RPCAddr()), fmt.Sprintf("--restlisten=%v", cfg.RESTAddr()), fmt.Sprintf("--restcors=https://%v", cfg.RESTAddr()), @@ -200,19 +246,19 @@ func (cfg *BaseNodeConfig) GenArgs() []string { } switch cfg.DbBackend { - case lntest.BackendEtcd: + case BackendEtcd: args = append(args, "--db.backend=etcd") args = append(args, "--db.etcd.embedded") args = append( args, fmt.Sprintf( "--db.etcd.embedded_client_port=%v", - lntest.NextAvailablePort(), + NextAvailablePort(), ), ) args = append( args, fmt.Sprintf( "--db.etcd.embedded_peer_port=%v", - lntest.NextAvailablePort(), + NextAvailablePort(), ), ) args = append( @@ -222,11 +268,11 @@ func (cfg *BaseNodeConfig) GenArgs() []string { ), ) - case lntest.BackendPostgres: + case BackendPostgres: args = append(args, "--db.backend=postgres") args = append(args, "--db.postgres.dsn="+cfg.PostgresDsn) - case lntest.BackendSqlite: + case BackendSqlite: args = append(args, "--db.backend=sqlite") args = append(args, fmt.Sprintf("--db.sqlite.busytimeout=%v", wait.SqliteBusyTimeout)) @@ -273,3 +319,85 @@ func ExtraArgsEtcd(etcdCfg *etcd.Config, name string, cluster bool, return extraArgs } + +// NextAvailablePort returns the first port that is available for listening by +// a new node. It panics if no port is found and the maximum available TCP port +// is reached. +func NextAvailablePort() int { + port := atomic.AddUint32(&lastPort, 1) + for port < 65535 { + // If there are no errors while attempting to listen on this + // port, close the socket and return it as available. While it + // could be the case that some other process picks up this port + // between the time the socket is closed and it's reopened in + // the harness node, in practice in CI servers this seems much + // less likely than simply some other process already being + // bound at the start of the tests. + addr := fmt.Sprintf(ListenerFormat, port) + l, err := net.Listen("tcp4", addr) + if err == nil { + err := l.Close() + if err == nil { + return int(port) + } + } + port = atomic.AddUint32(&lastPort, 1) + } + + // No ports available? Must be a mistake. + panic("no ports available for listening") +} + +// GetLogDir returns the passed --logdir flag or the default value if it wasn't +// set. +func GetLogDir() string { + if logSubDir != nil && *logSubDir != "" { + return *logSubDir + } + return "." +} + +// CopyFile copies the file src to dest. +func CopyFile(dest, src string) error { + s, err := os.Open(src) + if err != nil { + return err + } + defer s.Close() + + d, err := os.Create(dest) + if err != nil { + return err + } + + if _, err := io.Copy(d, s); err != nil { + d.Close() + return err + } + + return d.Close() +} + +// GetBtcdBinary returns the full path to the binary of the custom built btcd +// executable or an empty string if none is set. +func GetBtcdBinary() string { + if btcdExecutable != nil { + return *btcdExecutable + } + + return "" +} + +// GenerateBtcdListenerAddresses is a function that returns two listener +// addresses with unique ports and should be used to overwrite rpctest's +// default generator which is prone to use colliding ports. +func GenerateBtcdListenerAddresses() (string, string) { + return fmt.Sprintf(ListenerFormat, NextAvailablePort()), + fmt.Sprintf(ListenerFormat, NextAvailablePort()) +} + +// ApplyPortOffset adds the given offset to the lastPort variable, making it +// possible to run the tests in parallel without colliding on the same ports. +func ApplyPortOffset(offset uint32) { + _ = atomic.AddUint32(&lastPort, offset) +} diff --git a/lntemp/node/harness_node.go b/lntemp/node/harness_node.go index c86e30af8..ebba81e84 100644 --- a/lntemp/node/harness_node.go +++ b/lntemp/node/harness_node.go @@ -19,7 +19,6 @@ import ( "github.com/jackc/pgx/v4/pgxpool" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lntemp/rpc" - "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/macaroons" "google.golang.org/grpc" @@ -117,7 +116,7 @@ func NewHarnessNode(t *testing.T, cfg *BaseNodeConfig) (*HarnessNode, error) { // Create temporary database. var dbName string - if cfg.DbBackend == lntest.BackendPostgres { + if cfg.DbBackend == BackendPostgres { var err error dbName, err = createTempPgDb() if err != nil { @@ -383,7 +382,7 @@ func (hn *HarnessNode) StartLndCmd(ctxb context.Context) error { // If the logoutput flag is passed, redirect output from the nodes to // log files. - if *lntest.LogOutput { + if *logOutput { err := addLogFile(hn) if err != nil { return err @@ -918,10 +917,8 @@ func getFinalizedLogFilePrefix(hn *HarnessNode) string { hn.PubKey[:logPubKeyBytes], ) - return fmt.Sprintf("%s/%d-%s-%s-%s", - lntest.GetLogDir(), hn.Cfg.NodeID, - hn.Cfg.LogFilenamePrefix, - hn.Cfg.Name, pubKeyHex) + return fmt.Sprintf("%s/%d-%s-%s-%s", GetLogDir(), hn.Cfg.NodeID, + hn.Cfg.LogFilenamePrefix, hn.Cfg.Name, pubKeyHex) } // finalizeLogfile makes sure the log file cleanup function is initialized, @@ -935,7 +932,7 @@ func finalizeLogfile(hn *HarnessNode) { hn.logFile.Close() // If logoutput flag is not set, return early. - if !*lntest.LogOutput { + if !*logOutput { return } @@ -948,7 +945,7 @@ func finalizeLogfile(hn *HarnessNode) { // finalizeEtcdLog saves the etcd log files when test ends. func finalizeEtcdLog(hn *HarnessNode) { // Exit early if this is not etcd backend. - if hn.Cfg.DbBackend != lntest.BackendEtcd { + if hn.Cfg.DbBackend != BackendEtcd { return } @@ -964,7 +961,7 @@ func finalizeEtcdLog(hn *HarnessNode) { func addLogFile(hn *HarnessNode) error { var fileName string - dir := lntest.GetLogDir() + dir := GetLogDir() fileName = fmt.Sprintf("%s/%d-%s-%s-%s.log", dir, hn.Cfg.NodeID, hn.Cfg.LogFilenamePrefix, hn.Cfg.Name, hex.EncodeToString(hn.PubKey[:logPubKeyBytes])) @@ -1028,7 +1025,7 @@ func copyAll(dstDir, srcDir string) error { if err != nil { return err } - } else if err := lntest.CopyFile(dstPath, srcPath); err != nil { + } else if err := CopyFile(dstPath, srcPath); err != nil { return err } } diff --git a/lntemp/utils.go b/lntemp/utils.go index d9946f365..b1a5f00d4 100644 --- a/lntemp/utils.go +++ b/lntemp/utils.go @@ -10,15 +10,14 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/wait" ) const ( // NeutrinoBackendName is the name of the neutrino backend. NeutrinoBackendName = "neutrino" - // TODO(yy): delete. - DefaultTimeout = lntest.DefaultTimeout + DefaultTimeout = wait.DefaultTimeout // noFeeLimitMsat is used to specify we will put no requirements on fee // charged when choosing a route path. diff --git a/lntest/bitcoind_common.go b/lntest/bitcoind_common.go index d9bf102f6..320d89345 100644 --- a/lntest/bitcoind_common.go +++ b/lntest/bitcoind_common.go @@ -14,6 +14,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/rpcclient" + "github.com/lightningnetwork/lnd/lntemp/node" ) // logDirPattern is the pattern of the name of the temporary log directory. @@ -37,7 +38,7 @@ type BitcoindBackendConfig struct { // A compile time assertion to ensure BitcoindBackendConfig meets the // BackendConfig interface. -var _ BackendConfig = (*BitcoindBackendConfig)(nil) +var _ node.BackendConfig = (*BitcoindBackendConfig)(nil) // GenArgs returns the arguments needed to be passed to LND at startup for // using this node as a chain backend. @@ -89,7 +90,7 @@ func (b BitcoindBackendConfig) Name() string { func newBackend(miner string, netParams *chaincfg.Params, extraArgs []string, rpcPolling bool) (*BitcoindBackendConfig, func() error, error) { - baseLogDir := fmt.Sprintf(logDirPattern, GetLogDir()) + baseLogDir := fmt.Sprintf(logDirPattern, node.GetLogDir()) if netParams != &chaincfg.RegressionNetParams { return nil, nil, fmt.Errorf("only regtest supported") } @@ -109,10 +110,12 @@ func newBackend(miner string, netParams *chaincfg.Params, extraArgs []string, fmt.Errorf("unable to create temp directory: %v", err) } - zmqBlockAddr := fmt.Sprintf("tcp://127.0.0.1:%d", NextAvailablePort()) - zmqTxAddr := fmt.Sprintf("tcp://127.0.0.1:%d", NextAvailablePort()) - rpcPort := NextAvailablePort() - p2pPort := NextAvailablePort() + zmqBlockAddr := fmt.Sprintf("tcp://127.0.0.1:%d", + node.NextAvailablePort()) + zmqTxAddr := fmt.Sprintf("tcp://127.0.0.1:%d", + node.NextAvailablePort()) + rpcPort := node.NextAvailablePort() + p2pPort := node.NextAvailablePort() cmdArgs := []string{ "-datadir=" + tempBitcoindDir, @@ -146,9 +149,9 @@ func newBackend(miner string, netParams *chaincfg.Params, extraArgs []string, // After shutting down the chain backend, we'll make a copy of // the log file before deleting the temporary log dir. logDestination := fmt.Sprintf( - "%s/output_bitcoind_chainbackend.log", GetLogDir(), + "%s/output_bitcoind_chainbackend.log", node.GetLogDir(), ) - err := CopyFile(logDestination, logFile) + err := node.CopyFile(logDestination, logFile) if err != nil { errStr += fmt.Sprintf("unable to copy file: %v\n", err) } diff --git a/lntest/btcd.go b/lntest/btcd.go index 200faa9bf..817936709 100644 --- a/lntest/btcd.go +++ b/lntest/btcd.go @@ -15,6 +15,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/integration/rpctest" "github.com/btcsuite/btcd/rpcclient" + "github.com/lightningnetwork/lnd/lntemp/node" ) // logDirPattern is the pattern of the name of the temporary log directory. @@ -41,7 +42,7 @@ type BtcdBackendConfig struct { // A compile time assertion to ensure BtcdBackendConfig meets the BackendConfig // interface. -var _ BackendConfig = (*BtcdBackendConfig)(nil) +var _ node.BackendConfig = (*BtcdBackendConfig)(nil) // GenArgs returns the arguments needed to be passed to LND at startup for // using this node as a chain backend. @@ -83,7 +84,7 @@ func (b BtcdBackendConfig) Name() string { func NewBackend(miner string, netParams *chaincfg.Params) ( *BtcdBackendConfig, func() error, error) { - baseLogDir := fmt.Sprintf(logDirPattern, GetLogDir()) + baseLogDir := fmt.Sprintf(logDirPattern, node.GetLogDir()) args := []string{ "--rejectnonstd", "--txindex", @@ -98,9 +99,12 @@ func NewBackend(miner string, netParams *chaincfg.Params) ( // Don't disconnect if a reply takes too long. "--nostalldetect", } - chainBackend, err := rpctest.New(netParams, nil, args, GetBtcdBinary()) + chainBackend, err := rpctest.New( + netParams, nil, args, node.GetBtcdBinary(), + ) if err != nil { - return nil, nil, fmt.Errorf("unable to create btcd node: %v", err) + return nil, nil, fmt.Errorf("unable to create btcd node: %v", + err) } // We want to overwrite some of the connection settings to make the @@ -112,7 +116,8 @@ func NewBackend(miner string, netParams *chaincfg.Params) ( chainBackend.ConnectionRetryTimeout = rpctest.DefaultConnectionRetryTimeout * 2 if err := chainBackend.SetUp(false, 0); err != nil { - return nil, nil, fmt.Errorf("unable to set up btcd backend: %v", err) + return nil, nil, fmt.Errorf("unable to set up btcd backend: %v", + err) } bd := &BtcdBackendConfig{ @@ -141,14 +146,16 @@ func NewBackend(miner string, netParams *chaincfg.Params) ( for _, file := range files { logFile := fmt.Sprintf("%s/%s", logDir, file.Name()) newFilename := strings.Replace( - file.Name(), "btcd.log", "output_btcd_chainbackend.log", 1, + file.Name(), "btcd.log", + "output_btcd_chainbackend.log", 1, ) logDestination := fmt.Sprintf( - "%s/%s", GetLogDir(), newFilename, + "%s/%s", node.GetLogDir(), newFilename, ) - err := CopyFile(logDestination, logFile) + err := node.CopyFile(logDestination, logFile) if err != nil { - errStr += fmt.Sprintf("unable to copy file: %v\n", err) + errStr += fmt.Sprintf("unable to copy file: "+ + "%v\n", err) } } diff --git a/lntest/fee_service.go b/lntest/fee_service.go deleted file mode 100644 index e2c1df361..000000000 --- a/lntest/fee_service.go +++ /dev/null @@ -1,114 +0,0 @@ -package lntest - -import ( - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "sync" - "testing" - - "github.com/lightningnetwork/lnd/lnwallet/chainfee" -) - -const ( - // feeServiceTarget is the confirmation target for which a fee estimate - // is returned. Requests for higher confirmation targets will fall back - // to this. - feeServiceTarget = 1 -) - -// feeService runs a web service that provides fee estimation information. -type feeService struct { - feeEstimates - - t *testing.T - - srv *http.Server - wg sync.WaitGroup - - url string - - lock sync.Mutex -} - -// feeEstimates contains the current fee estimates. -type feeEstimates struct { - Fees map[uint32]uint32 `json:"fee_by_block_target"` -} - -// startFeeService spins up a go-routine to serve fee estimates. -func startFeeService(t *testing.T) *feeService { - port := NextAvailablePort() - f := feeService{ - t: t, - url: fmt.Sprintf("http://localhost:%v/fee-estimates.json", port), - } - - // Initialize default fee estimate. - f.Fees = map[uint32]uint32{feeServiceTarget: 50000} - - listenAddr := fmt.Sprintf(":%v", port) - mux := http.NewServeMux() - mux.HandleFunc("/fee-estimates.json", f.handleRequest) - - f.srv = &http.Server{ - Addr: listenAddr, - Handler: mux, - } - - f.wg.Add(1) - go func() { - defer f.wg.Done() - - if err := f.srv.ListenAndServe(); err != http.ErrServerClosed { - f.t.Errorf("error: cannot start fee api: %v", err) - } - }() - - return &f -} - -// handleRequest handles a client request for fee estimates. -func (f *feeService) handleRequest(w http.ResponseWriter, r *http.Request) { - f.lock.Lock() - defer f.lock.Unlock() - - bytes, err := json.Marshal(f.feeEstimates) - if err != nil { - f.t.Errorf("error: cannot serialize estimates: %v", err) - - return - } - - _, err = io.WriteString(w, string(bytes)) - if err != nil { - f.t.Errorf("error: cannot send estimates: %v", err) - } -} - -// stop stops the web server. -func (f *feeService) stop() { - if err := f.srv.Shutdown(context.Background()); err != nil { - f.t.Errorf("error: cannot stop fee api: %v", err) - } - - f.wg.Wait() -} - -// setFee changes the current fee estimate for the fixed confirmation target. -func (f *feeService) setFee(fee chainfee.SatPerKWeight) { - f.lock.Lock() - defer f.lock.Unlock() - - f.Fees[feeServiceTarget] = uint32(fee.FeePerKVByte()) -} - -// setFeeWithConf sets a fee for the given confirmation target. -func (f *feeService) setFeeWithConf(fee chainfee.SatPerKWeight, conf uint32) { - f.lock.Lock() - defer f.lock.Unlock() - - f.Fees[conf] = uint32(fee.FeePerKVByte()) -} diff --git a/lntest/fee_service_test.go b/lntest/fee_service_test.go deleted file mode 100644 index 228d7c30e..000000000 --- a/lntest/fee_service_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package lntest - -import ( - "io/ioutil" - "net/http" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -// TestFeeService tests the itest fee estimating web service. -func TestFeeService(t *testing.T) { - service := startFeeService(t) - defer service.stop() - - service.setFee(5000) - - // Wait for service to start accepting connections. - var resp *http.Response - require.Eventually( - t, - func() bool { - var err error - resp, err = http.Get(service.url) // nolint:bodyclose - return err == nil - }, - 10*time.Second, time.Second, - ) - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - require.NoError(t, err) - - require.Equal( - t, "{\"fee_by_block_target\":{\"1\":20000}}", string(body), - ) -} diff --git a/lntest/harness_miner.go b/lntest/harness_miner.go deleted file mode 100644 index b9f54619a..000000000 --- a/lntest/harness_miner.go +++ /dev/null @@ -1,161 +0,0 @@ -package lntest - -import ( - "context" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" - - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/integration/rpctest" - "github.com/btcsuite/btcd/rpcclient" -) - -const ( - // minerLogFilename is the default log filename for the miner node. - minerLogFilename = "output_btcd_miner.log" - - // minerLogDir is the default log dir for the miner node. - minerLogDir = ".minerlogs" -) - -var harnessNetParams = &chaincfg.RegressionNetParams - -type HarnessMiner struct { - *rpctest.Harness - - // runCtx is a context with cancel method. It's used to signal when the - // node needs to quit, and used as the parent context when spawning - runCtx context.Context - cancel context.CancelFunc - - // logPath is the directory path of the miner's logs. - logPath string - - // logFilename is the saved log filename of the miner node. - logFilename string -} - -// NewMiner creates a new miner using btcd backend with the default log file -// dir and name. -func NewMiner() (*HarnessMiner, error) { - return newMiner(minerLogDir, minerLogFilename) -} - -// NewTempMiner creates a new miner using btcd backend with the specified log -// file dir and name. -func NewTempMiner(tempDir, tempLogFilename string) (*HarnessMiner, error) { - return newMiner(tempDir, tempLogFilename) -} - -// newMiner creates a new miner using btcd's rpctest. -func newMiner(minerDirName, logFilename string) (*HarnessMiner, error) { - handler := &rpcclient.NotificationHandlers{} - btcdBinary := GetBtcdBinary() - baseLogPath := fmt.Sprintf("%s/%s", GetLogDir(), minerDirName) - - args := []string{ - "--rejectnonstd", - "--txindex", - "--nowinservice", - "--nobanning", - "--debuglevel=debug", - "--logdir=" + baseLogPath, - "--trickleinterval=100ms", - // Don't disconnect if a reply takes too long. - "--nostalldetect", - } - - miner, err := rpctest.New(harnessNetParams, handler, args, btcdBinary) - if err != nil { - return nil, fmt.Errorf("unable to create mining node: %v", err) - } - - ctxt, cancel := context.WithCancel(context.Background()) - m := &HarnessMiner{ - Harness: miner, - runCtx: ctxt, - cancel: cancel, - logPath: baseLogPath, - logFilename: logFilename, - } - return m, nil -} - -// Stop shuts down the miner and saves its logs. -func (h *HarnessMiner) Stop() error { - h.cancel() - - if err := h.TearDown(); err != nil { - return fmt.Errorf("tear down miner got error: %s", err) - } - - return h.saveLogs() -} - -// saveLogs copies the node logs and save it to the file specified by -// h.logFilename. -func (h *HarnessMiner) saveLogs() error { - // After shutting down the miner, we'll make a copy of the log files - // before deleting the temporary log dir. - path := fmt.Sprintf("%s/%s", h.logPath, harnessNetParams.Name) - files, err := ioutil.ReadDir(path) - if err != nil { - return fmt.Errorf("unable to read log directory: %v", err) - } - - for _, file := range files { - newFilename := strings.Replace( - file.Name(), "btcd.log", h.logFilename, 1, - ) - copyPath := fmt.Sprintf("%s/../%s", h.logPath, newFilename) - - logFile := fmt.Sprintf("%s/%s", path, file.Name()) - err := CopyFile(filepath.Clean(copyPath), logFile) - if err != nil { - return fmt.Errorf("unable to copy file: %v", err) - } - } - - if err = os.RemoveAll(h.logPath); err != nil { - return fmt.Errorf("cannot remove dir %s: %v", h.logPath, err) - } - - return nil -} - -// waitForTxInMempool blocks until the target txid is seen in the mempool. If -// the transaction isn't seen within the network before the passed timeout, -// then an error is returned. -func (h *HarnessMiner) waitForTxInMempool(txid chainhash.Hash) error { - ticker := time.NewTicker(50 * time.Millisecond) - defer ticker.Stop() - - var mempool []*chainhash.Hash - for { - select { - case <-h.runCtx.Done(): - return fmt.Errorf("NetworkHarness has been torn down") - case <-time.After(DefaultTimeout): - return fmt.Errorf("wanted %v, found %v txs "+ - "in mempool: %v", txid, len(mempool), mempool) - - case <-ticker.C: - var err error - mempool, err = h.Client.GetRawMempool() - if err != nil { - return err - } - - for _, mempoolTx := range mempool { - if *mempoolTx == txid { - return nil - } - } - } - } -} diff --git a/lntest/harness_net.go b/lntest/harness_net.go deleted file mode 100644 index 358a1c0b3..000000000 --- a/lntest/harness_net.go +++ /dev/null @@ -1,1759 +0,0 @@ -package lntest - -import ( - "context" - "encoding/hex" - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "path/filepath" - "strings" - "sync" - "testing" - "time" - - "github.com/btcsuite/btcd/btcutil" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcd/wire" - "github.com/lightningnetwork/lnd" - "github.com/lightningnetwork/lnd/kvdb/etcd" - "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntest/wait" - "github.com/lightningnetwork/lnd/lnwallet/chainfee" - "github.com/lightningnetwork/lnd/lnwire" - "github.com/stretchr/testify/require" - "golang.org/x/sync/errgroup" - "google.golang.org/grpc/grpclog" -) - -// DefaultCSV is the CSV delay (remotedelay) we will start our test nodes with. -const DefaultCSV = 4 - -// NodeOption is a function for updating a node's configuration. -type NodeOption func(*BaseNodeConfig) - -// NetworkHarness is an integration testing harness for the lightning network. -// Building on top of HarnessNode, it is responsible for handling interactions -// among different nodes. The harness by default is created with two active -// nodes on the network: -// Alice and Bob. -type NetworkHarness struct { - netParams *chaincfg.Params - - // currentTestCase holds the name for the currently run test case. - currentTestCase string - - // lndBinary is the full path to the lnd binary that was specifically - // compiled with all required itest flags. - lndBinary string - - // Miner is a reference to a running full node that can be used to - // create new blocks on the network. - Miner *HarnessMiner - - // BackendCfg houses the information necessary to use a node as LND - // chain backend, such as rpc configuration, P2P information etc. - BackendCfg BackendConfig - - activeNodes map[int]*HarnessNode - - nodesByPub map[string]*HarnessNode - - // Alice and Bob are the initial seeder nodes that are automatically - // created to be the initial participants of the test network. - Alice *HarnessNode - Bob *HarnessNode - - // dbBackend sets the database backend to use. - dbBackend DatabaseBackend - - // Channel for transmitting stderr output from failed lightning node - // to main process. - lndErrorChan chan error - - // feeService is a web service that provides external fee estimates to - // lnd. - feeService *feeService - - // runCtx is a context with cancel method. It's used to signal when the - // node needs to quit, and used as the parent context when spawning - // children contexts for RPC requests. - runCtx context.Context - cancel context.CancelFunc - - mtx sync.Mutex -} - -// NewNetworkHarness creates a new network test harness. -// TODO(roasbeef): add option to use golang's build library to a binary of the -// current repo. This will save developers from having to manually `go install` -// within the repo each time before changes. -func NewNetworkHarness(m *HarnessMiner, b BackendConfig, lndBinary string, - dbBackend DatabaseBackend) (*NetworkHarness, error) { - - ctxt, cancel := context.WithCancel(context.Background()) - - n := NetworkHarness{ - activeNodes: make(map[int]*HarnessNode), - nodesByPub: make(map[string]*HarnessNode), - lndErrorChan: make(chan error), - netParams: m.ActiveNet, - Miner: m, - BackendCfg: b, - runCtx: ctxt, - cancel: cancel, - lndBinary: lndBinary, - dbBackend: dbBackend, - } - return &n, nil -} - -// LookUpNodeByPub queries the set of active nodes to locate a node according -// to its public key. The error is returned if the node was not found. -func (n *NetworkHarness) LookUpNodeByPub(pubStr string) (*HarnessNode, error) { - n.mtx.Lock() - defer n.mtx.Unlock() - - node, ok := n.nodesByPub[pubStr] - if !ok { - return nil, fmt.Errorf("unable to find node") - } - - return node, nil -} - -// ProcessErrors returns a channel used for reporting any fatal process errors. -// If any of the active nodes within the harness' test network incur a fatal -// error, that error is sent over this channel. -func (n *NetworkHarness) ProcessErrors() <-chan error { - return n.lndErrorChan -} - -// SetUp starts the initial seeder nodes within the test harness. The initial -// node's wallets will be funded wallets with ten 1 BTC outputs each. Finally -// rpc clients capable of communicating with the initial seeder nodes are -// created. Nodes are initialized with the given extra command line flags, which -// should be formatted properly - "--arg=value". -func (n *NetworkHarness) SetUp(t *testing.T, - testCase string, lndArgs []string) error { - - // Swap out grpc's default logger with out fake logger which drops the - // statements on the floor. - fakeLogger := grpclog.NewLoggerV2(io.Discard, io.Discard, io.Discard) - grpclog.SetLoggerV2(fakeLogger) - n.currentTestCase = testCase - n.feeService = startFeeService(t) - - // Start the initial seeder nodes within the test network, then connect - // their respective RPC clients. - eg := errgroup.Group{} - eg.Go(func() error { - var err error - n.Alice, err = n.newNode( - "Alice", lndArgs, false, nil, n.dbBackend, true, - ) - return err - }) - eg.Go(func() error { - var err error - n.Bob, err = n.newNode( - "Bob", lndArgs, false, nil, n.dbBackend, true, - ) - return err - }) - require.NoError(t, eg.Wait()) - - // First, make a connection between the two nodes. This will wait until - // both nodes are fully started since the Connect RPC is guarded behind - // the server.Started() flag that waits for all subsystems to be ready. - n.ConnectNodes(t, n.Alice, n.Bob) - - // Load up the wallets of the seeder nodes with 10 outputs of 1 BTC - // each. - addrReq := &lnrpc.NewAddressRequest{ - Type: lnrpc.AddressType_WITNESS_PUBKEY_HASH, - } - clients := []lnrpc.LightningClient{n.Alice, n.Bob} - for _, client := range clients { - for i := 0; i < 10; i++ { - resp, err := client.NewAddress(n.runCtx, addrReq) - if err != nil { - return err - } - addr, err := btcutil.DecodeAddress(resp.Address, n.netParams) - if err != nil { - return err - } - addrScript, err := txscript.PayToAddrScript(addr) - if err != nil { - return err - } - - output := &wire.TxOut{ - PkScript: addrScript, - Value: btcutil.SatoshiPerBitcoin, - } - _, err = n.Miner.SendOutputs([]*wire.TxOut{output}, 7500) - if err != nil { - return err - } - } - } - - // We generate several blocks in order to give the outputs created - // above a good number of confirmations. - if _, err := n.Miner.Client.Generate(10); err != nil { - return err - } - - // Now we want to wait for the nodes to catch up. - if err := n.Alice.WaitForBlockchainSync(); err != nil { - return err - } - if err := n.Bob.WaitForBlockchainSync(); err != nil { - return err - } - - // Now block until both wallets have fully synced up. - expectedBalance := int64(btcutil.SatoshiPerBitcoin * 10) - balReq := &lnrpc.WalletBalanceRequest{} - balanceTicker := time.NewTicker(time.Millisecond * 200) - defer balanceTicker.Stop() - balanceTimeout := time.After(DefaultTimeout) -out: - for { - select { - case <-balanceTicker.C: - aliceResp, err := n.Alice.WalletBalance(n.runCtx, balReq) - if err != nil { - return err - } - bobResp, err := n.Bob.WalletBalance(n.runCtx, balReq) - if err != nil { - return err - } - - if aliceResp.ConfirmedBalance == expectedBalance && - bobResp.ConfirmedBalance == expectedBalance { - - break out - } - case <-balanceTimeout: - return fmt.Errorf("balances not synced after deadline") - } - } - - return nil -} - -// TearDown tears down all active nodes within the test lightning network. -func (n *NetworkHarness) TearDown() error { - for _, node := range n.activeNodes { - if err := n.ShutdownNode(node); err != nil { - return err - } - } - - return nil -} - -// Stop stops the test harness. -func (n *NetworkHarness) Stop() { - close(n.lndErrorChan) - n.cancel() - - // feeService may not be created. For instance, running a non-exist - // test case. - if n.feeService != nil { - n.feeService.stop() - } -} - -// extraArgsEtcd returns extra args for configuring LND to use an external etcd -// database (for remote channel DB and wallet DB). -func extraArgsEtcd(etcdCfg *etcd.Config, name string, cluster bool, - leaderSessionTTL int) []string { - - extraArgs := []string{ - "--db.backend=etcd", - fmt.Sprintf("--db.etcd.host=%v", etcdCfg.Host), - fmt.Sprintf("--db.etcd.user=%v", etcdCfg.User), - fmt.Sprintf("--db.etcd.pass=%v", etcdCfg.Pass), - fmt.Sprintf("--db.etcd.namespace=%v", etcdCfg.Namespace), - } - - if etcdCfg.InsecureSkipVerify { - extraArgs = append(extraArgs, "--db.etcd.insecure_skip_verify") - } - - if cluster { - clusterArgs := []string{ - "--cluster.enable-leader-election", - fmt.Sprintf("--cluster.id=%v", name), - fmt.Sprintf("--cluster.leader-session-ttl=%v", - leaderSessionTTL), - } - extraArgs = append(extraArgs, clusterArgs...) - } - - return extraArgs -} - -// NewNodeWithSeedEtcd starts a new node with seed that'll use an external -// etcd database as its (remote) channel and wallet DB. The passsed cluster -// flag indicates that we'd like the node to join the cluster leader election. -func (n *NetworkHarness) NewNodeWithSeedEtcd(name string, etcdCfg *etcd.Config, - password []byte, entropy []byte, statelessInit, cluster bool, - leaderSessionTTL int) (*HarnessNode, []string, []byte, error) { - - // We don't want to use the embedded etcd instance. - const dbBackend = BackendBbolt - - extraArgs := extraArgsEtcd(etcdCfg, name, cluster, leaderSessionTTL) - return n.newNodeWithSeed( - name, extraArgs, password, entropy, statelessInit, dbBackend, - ) -} - -// NewNodeWithSeedEtcd starts a new node with seed that'll use an external -// etcd database as its (remote) channel and wallet DB. The passsed cluster -// flag indicates that we'd like the node to join the cluster leader election. -// If the wait flag is false then we won't wait until RPC is available (this is -// useful when the node is not expected to become the leader right away). -func (n *NetworkHarness) NewNodeEtcd(name string, etcdCfg *etcd.Config, - password []byte, cluster, wait bool, leaderSessionTTL int) ( - *HarnessNode, error) { - - // We don't want to use the embedded etcd instance. - const dbBackend = BackendBbolt - - extraArgs := extraArgsEtcd(etcdCfg, name, cluster, leaderSessionTTL) - return n.newNode(name, extraArgs, true, password, dbBackend, wait) -} - -// NewNode fully initializes a returns a new HarnessNode bound to the -// current instance of the network harness. The created node is running, but -// not yet connected to other nodes within the network. -func (n *NetworkHarness) NewNode(t *testing.T, - name string, extraArgs []string, opts ...NodeOption) *HarnessNode { - - node, err := n.newNode( - name, extraArgs, false, nil, n.dbBackend, true, opts..., - ) - require.NoErrorf(t, err, "unable to create new node for %s", name) - - return node -} - -// NewNodeWithSeed fully initializes a new HarnessNode after creating a fresh -// aezeed. The provided password is used as both the aezeed password and the -// wallet password. The generated mnemonic is returned along with the -// initialized harness node. -func (n *NetworkHarness) NewNodeWithSeed(name string, extraArgs []string, - password []byte, statelessInit bool) (*HarnessNode, []string, []byte, - error) { - - return n.newNodeWithSeed( - name, extraArgs, password, nil, statelessInit, n.dbBackend, - ) -} - -func (n *NetworkHarness) newNodeWithSeed(name string, extraArgs []string, - password, entropy []byte, statelessInit bool, dbBackend DatabaseBackend) ( - *HarnessNode, []string, []byte, error) { - - node, err := n.newNode( - name, extraArgs, true, password, dbBackend, true, - ) - if err != nil { - return nil, nil, nil, err - } - - // Create a request to generate a new aezeed. The new seed will have the - // same password as the internal wallet. - genSeedReq := &lnrpc.GenSeedRequest{ - AezeedPassphrase: password, - SeedEntropy: entropy, - } - - ctxt, cancel := context.WithTimeout(n.runCtx, DefaultTimeout) - defer cancel() - - var genSeedResp *lnrpc.GenSeedResponse - if err := wait.NoError(func() error { - genSeedResp, err = node.GenSeed(ctxt, genSeedReq) - return err - }, DefaultTimeout); err != nil { - return nil, nil, nil, err - } - - // With the seed created, construct the init request to the node, - // including the newly generated seed. - initReq := &lnrpc.InitWalletRequest{ - WalletPassword: password, - CipherSeedMnemonic: genSeedResp.CipherSeedMnemonic, - AezeedPassphrase: password, - StatelessInit: statelessInit, - } - - // Pass the init request via rpc to finish unlocking the node. This will - // also initialize the macaroon-authenticated LightningClient. - response, err := node.Init(initReq) - if err != nil { - return nil, nil, nil, err - } - - // With the node started, we can now record its public key within the - // global mapping. - n.RegisterNode(node) - - // In stateless initialization mode we get a macaroon back that we have - // to return to the test, otherwise gRPC calls won't be possible since - // there are no macaroon files created in that mode. - // In stateful init the admin macaroon will just be nil. - return node, genSeedResp.CipherSeedMnemonic, response.AdminMacaroon, nil -} - -func (n *NetworkHarness) NewNodeRemoteSigner(name string, extraArgs []string, - password []byte, watchOnly *lnrpc.WatchOnly) (*HarnessNode, error) { - - node, err := n.newNode( - name, extraArgs, true, password, n.dbBackend, true, - ) - if err != nil { - return nil, err - } - - // With the seed created, construct the init request to the node, - // including the newly generated seed. - initReq := &lnrpc.InitWalletRequest{ - WalletPassword: password, - WatchOnly: watchOnly, - } - - // Pass the init request via rpc to finish unlocking the node. This will - // also initialize the macaroon-authenticated LightningClient. - _, err = node.Init(initReq) - if err != nil { - return nil, err - } - - // With the node started, we can now record its public key within the - // global mapping. - n.RegisterNode(node) - - return node, nil -} - -// RestoreNodeWithSeed fully initializes a HarnessNode using a chosen mnemonic, -// password, recovery window, and optionally a set of static channel backups. -// After providing the initialization request to unlock the node, this method -// will finish initializing the LightningClient such that the HarnessNode can -// be used for regular rpc operations. -func (n *NetworkHarness) RestoreNodeWithSeed(name string, extraArgs []string, - password []byte, mnemonic []string, rootKey string, recoveryWindow int32, - chanBackups *lnrpc.ChanBackupSnapshot, - opts ...NodeOption) (*HarnessNode, error) { - - node, err := n.newNode( - name, extraArgs, true, password, n.dbBackend, true, opts..., - ) - if err != nil { - return nil, err - } - - initReq := &lnrpc.InitWalletRequest{ - WalletPassword: password, - CipherSeedMnemonic: mnemonic, - AezeedPassphrase: password, - ExtendedMasterKey: rootKey, - RecoveryWindow: recoveryWindow, - ChannelBackups: chanBackups, - } - - _, err = node.Init(initReq) - if err != nil { - return nil, err - } - - // With the node started, we can now record its public key within the - // global mapping. - n.RegisterNode(node) - - return node, nil -} - -// newNode initializes a new HarnessNode, supporting the ability to initialize a -// wallet with or without a seed. If hasSeed is false, the returned harness node -// can be used immediately. Otherwise, the node will require an additional -// initialization phase where the wallet is either created or restored. -func (n *NetworkHarness) newNode(name string, extraArgs []string, hasSeed bool, - password []byte, dbBackend DatabaseBackend, wait bool, opts ...NodeOption) ( - *HarnessNode, error) { - - cfg := &BaseNodeConfig{ - Name: name, - LogFilenamePrefix: n.currentTestCase, - HasSeed: hasSeed, - Password: password, - BackendCfg: n.BackendCfg, - NetParams: n.netParams, - ExtraArgs: extraArgs, - FeeURL: n.feeService.url, - DbBackend: dbBackend, - } - for _, opt := range opts { - opt(cfg) - } - - node, err := newNode(cfg) - if err != nil { - return nil, err - } - - // Put node in activeNodes to ensure Shutdown is called even if Start - // returns an error. - n.mtx.Lock() - n.activeNodes[node.NodeID] = node - n.mtx.Unlock() - - err = node.start(n.lndBinary, n.lndErrorChan, wait) - if err != nil { - return nil, err - } - - // If this node is to have a seed, it will need to be unlocked or - // initialized via rpc. Delay registering it with the network until it - // can be driven via an unlocked rpc connection. - if node.Cfg.HasSeed { - return node, nil - } - - // With the node started, we can now record its public key within the - // global mapping. - n.RegisterNode(node) - - return node, nil -} - -// RegisterNode records a new HarnessNode in the NetworkHarnesses map of known -// nodes. This method should only be called with nodes that have successfully -// retrieved their public keys via FetchNodeInfo. -func (n *NetworkHarness) RegisterNode(node *HarnessNode) { - n.mtx.Lock() - n.nodesByPub[node.PubKeyStr] = node - n.mtx.Unlock() -} - -func (n *NetworkHarness) connect(ctx context.Context, - req *lnrpc.ConnectPeerRequest, a *HarnessNode) error { - - syncTimeout := time.After(DefaultTimeout) -tryconnect: - if _, err := a.ConnectPeer(ctx, req); err != nil { - // If the chain backend is still syncing, retry. - if strings.Contains(err.Error(), lnd.ErrServerNotActive.Error()) || - strings.Contains(err.Error(), "i/o timeout") { - - select { - case <-time.After(100 * time.Millisecond): - goto tryconnect - case <-syncTimeout: - return fmt.Errorf("chain backend did not " + - "finish syncing") - } - } - return err - } - - return nil -} - -// EnsureConnected will try to connect to two nodes, returning no error if they -// are already connected. If the nodes were not connected previously, this will -// behave the same as ConnectNodes. If a pending connection request has already -// been made, the method will block until the two nodes appear in each other's -// peers list, or until the 15s timeout expires. -func (n *NetworkHarness) EnsureConnected(t *testing.T, a, b *HarnessNode) { - ctx, cancel := context.WithTimeout(n.runCtx, DefaultTimeout*2) - defer cancel() - - // errConnectionRequested is used to signal that a connection was - // requested successfully, which is distinct from already being - // connected to the peer. - errConnectionRequested := errors.New("connection request in progress") - - tryConnect := func(a, b *HarnessNode) error { - bInfo, err := b.GetInfo(ctx, &lnrpc.GetInfoRequest{}) - if err != nil { - return err - } - - req := &lnrpc.ConnectPeerRequest{ - Addr: &lnrpc.LightningAddress{ - Pubkey: bInfo.IdentityPubkey, - Host: b.Cfg.P2PAddr(), - }, - } - - var predErr error - err = wait.Predicate(func() bool { - ctx, cancel := context.WithTimeout(ctx, DefaultTimeout) - defer cancel() - - err := n.connect(ctx, req, a) - switch { - // Request was successful, wait for both to display the - // connection. - case err == nil: - predErr = errConnectionRequested - return true - - // If the two are already connected, we return early - // with no error. - case strings.Contains( - err.Error(), "already connected to peer", - ): - predErr = nil - return true - - default: - predErr = err - return false - } - }, DefaultTimeout) - if err != nil { - return fmt.Errorf("connection not succeeded within 15 "+ - "seconds: %v", predErr) - } - - return predErr - } - - aErr := tryConnect(a, b) - bErr := tryConnect(b, a) - switch { - // If both reported already being connected to each other, we can exit - // early. - case aErr == nil && bErr == nil: - - // Return any critical errors returned by either alice. - case aErr != nil && aErr != errConnectionRequested: - t.Fatalf( - "ensure connection between %s and %s failed "+ - "with error from %s: %v", - a.Cfg.Name, b.Cfg.Name, a.Cfg.Name, aErr, - ) - - // Return any critical errors returned by either bob. - case bErr != nil && bErr != errConnectionRequested: - t.Fatalf("ensure connection between %s and %s failed "+ - "with error from %s: %v", - a.Cfg.Name, b.Cfg.Name, b.Cfg.Name, bErr, - ) - - // Otherwise one or both requested a connection, so we wait for the - // peers lists to reflect the connection. - default: - } - - findSelfInPeerList := func(a, b *HarnessNode) bool { - // If node B is seen in the ListPeers response from node A, - // then we can exit early as the connection has been fully - // established. - resp, err := b.ListPeers(ctx, &lnrpc.ListPeersRequest{}) - if err != nil { - return false - } - - for _, peer := range resp.Peers { - if peer.PubKey == a.PubKeyStr { - return true - } - } - - return false - } - - err := wait.Predicate(func() bool { - return findSelfInPeerList(a, b) && findSelfInPeerList(b, a) - }, DefaultTimeout) - - require.NoErrorf( - t, err, "unable to connect %s to %s, "+ - "got error: peers not connected within %v seconds", - a.Cfg.Name, b.Cfg.Name, DefaultTimeout, - ) -} - -// ConnectNodes attempts to create a connection between nodes a and b. -func (n *NetworkHarness) ConnectNodes(t *testing.T, a, b *HarnessNode) { - n.connectNodes(t, a, b, false) -} - -// ConnectNodesPerm attempts to connect nodes a and b and sets node b as -// a peer that node a should persistently attempt to reconnect to if they -// become disconnected. -func (n *NetworkHarness) ConnectNodesPerm(t *testing.T, - a, b *HarnessNode) { - - n.connectNodes(t, a, b, true) -} - -// connectNodes establishes an encrypted+authenticated p2p connection from node -// a towards node b. The function will return a non-nil error if the connection -// was unable to be established. If the perm parameter is set to true then -// node a will persistently attempt to reconnect to node b if they get -// disconnected. -// -// NOTE: This function may block for up to 15-seconds as it will not return -// until the new connection is detected as being known to both nodes. -func (n *NetworkHarness) connectNodes(t *testing.T, a, b *HarnessNode, - perm bool) { - - ctx, cancel := context.WithTimeout(n.runCtx, DefaultTimeout) - defer cancel() - - bobInfo, err := b.GetInfo(ctx, &lnrpc.GetInfoRequest{}) - require.NoErrorf( - t, err, "unable to connect %s to %s, got error: %v", - a.Cfg.Name, b.Cfg.Name, err, - ) - - req := &lnrpc.ConnectPeerRequest{ - Addr: &lnrpc.LightningAddress{ - Pubkey: bobInfo.IdentityPubkey, - Host: b.Cfg.P2PAddr(), - }, - Perm: perm, - } - - err = n.connect(ctx, req, a) - require.NoErrorf( - t, err, "unable to connect %s to %s, got error: %v", - a.Cfg.Name, b.Cfg.Name, err, - ) - - err = wait.Predicate(func() bool { - // If node B is seen in the ListPeers response from node A, - // then we can exit early as the connection has been fully - // established. - resp, err := a.ListPeers(ctx, &lnrpc.ListPeersRequest{}) - if err != nil { - return false - } - - for _, peer := range resp.Peers { - if peer.PubKey == b.PubKeyStr { - return true - } - } - - return false - }, DefaultTimeout) - - require.NoErrorf( - t, err, "unable to connect %s to %s, "+ - "got error: peers not connected within %v seconds", - a.Cfg.Name, b.Cfg.Name, DefaultTimeout, - ) -} - -// DisconnectNodes disconnects node a from node b by sending RPC message -// from a node to b node. -func (n *NetworkHarness) DisconnectNodes(a, b *HarnessNode) error { - ctx, cancel := context.WithTimeout(n.runCtx, DefaultTimeout) - defer cancel() - - bobInfo, err := b.GetInfo(ctx, &lnrpc.GetInfoRequest{}) - if err != nil { - return err - } - - req := &lnrpc.DisconnectPeerRequest{ - PubKey: bobInfo.IdentityPubkey, - } - - if _, err := a.DisconnectPeer(ctx, req); err != nil { - return err - } - - return nil -} - -// RestartNode attempts to restart a lightning node by shutting it down -// cleanly, then restarting the process. This function is fully blocking. Upon -// restart, the RPC connection to the node will be re-attempted, continuing iff -// the connection attempt is successful. If the callback parameter is non-nil, -// then the function will be executed after the node shuts down, but *before* -// the process has been started up again. -// -// This method can be useful when testing edge cases such as a node broadcast -// and invalidated prior state, or persistent state recovery, simulating node -// crashes, etc. Additionally, each time the node is restarted, the caller can -// pass a set of SCBs to pass in via the Unlock method allowing them to restore -// channels during restart. -func (n *NetworkHarness) RestartNode(node *HarnessNode, callback func() error, - chanBackups ...*lnrpc.ChanBackupSnapshot) error { - - err := n.RestartNodeNoUnlock(node, callback, true) - if err != nil { - return err - } - - // If the node doesn't have a password set, then we can exit here as we - // don't need to unlock it. - if len(node.Cfg.Password) == 0 { - return nil - } - - // Otherwise, we'll unlock the wallet, then complete the final steps - // for the node initialization process. - unlockReq := &lnrpc.UnlockWalletRequest{ - WalletPassword: node.Cfg.Password, - } - if len(chanBackups) != 0 { - unlockReq.ChannelBackups = chanBackups[0] - unlockReq.RecoveryWindow = 1000 - } - - if err := node.Unlock(unlockReq); err != nil { - return err - } - - // Give the node some time to catch up with the chain before we - // continue with the tests. - return node.WaitForBlockchainSync() -} - -// RestartNodeNoUnlock attempts to restart a lightning node by shutting it down -// cleanly, then restarting the process. In case the node was setup with a seed, -// it will be left in the unlocked state. This function is fully blocking. If -// the callback parameter is non-nil, then the function will be executed after -// the node shuts down, but *before* the process has been started up again. -func (n *NetworkHarness) RestartNodeNoUnlock(node *HarnessNode, - callback func() error, wait bool) error { - - if err := node.stop(); err != nil { - return err - } - - if callback != nil { - if err := callback(); err != nil { - return err - } - } - - return node.start(n.lndBinary, n.lndErrorChan, wait) -} - -// SuspendNode stops the given node and returns a callback that can be used to -// start it again. -func (n *NetworkHarness) SuspendNode(node *HarnessNode) (func() error, error) { - if err := node.stop(); err != nil { - return nil, err - } - - restart := func() error { - return node.start(n.lndBinary, n.lndErrorChan, true) - } - - return restart, nil -} - -// ShutdownNode stops an active lnd process and returns when the process has -// exited and any temporary directories have been cleaned up. -func (n *NetworkHarness) ShutdownNode(node *HarnessNode) error { - if err := node.shutdown(); err != nil { - return err - } - - delete(n.activeNodes, node.NodeID) - return nil -} - -// KillNode kills the node (but won't wait for the node process to stop). -func (n *NetworkHarness) KillNode(node *HarnessNode) error { - if err := node.kill(); err != nil { - return err - } - - delete(n.activeNodes, node.NodeID) - return nil -} - -// StopNode stops the target node, but doesn't yet clean up its directories. -// This can be used to temporarily bring a node down during a test, to be later -// started up again. -func (n *NetworkHarness) StopNode(node *HarnessNode) error { - return node.stop() -} - -// SaveProfilesPages hits profiles pages of all active nodes and writes it to -// disk using a similar naming scheme as to the regular set of logs. -func (n *NetworkHarness) SaveProfilesPages(t *testing.T) { - // Only write gorutine dumps if flag is active. - if !(*goroutineDump) { - return - } - - for _, node := range n.activeNodes { - if err := saveProfilesPage(node); err != nil { - t.Logf("Logging follow-up error only, see rest of "+ - "the log for actual cause: %v\n", err) - } - } -} - -// saveProfilesPage saves the profiles page for the given node to file. -func saveProfilesPage(node *HarnessNode) error { - resp, err := http.Get( - fmt.Sprintf( - "http://localhost:%d/debug/pprof/goroutine?debug=1", - node.Cfg.ProfilePort, - ), - ) - if err != nil { - return fmt.Errorf("failed to get profile page "+ - "(node_id=%d, name=%s): %v", - node.NodeID, node.Cfg.Name, err) - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("failed to read profile page "+ - "(node_id=%d, name=%s): %v", - node.NodeID, node.Cfg.Name, err) - } - - fileName := fmt.Sprintf( - "pprof-%d-%s-%s.log", node.NodeID, node.Cfg.Name, - hex.EncodeToString(node.PubKey[:logPubKeyBytes]), - ) - - logFile, err := os.Create(fileName) - if err != nil { - return fmt.Errorf("failed to create file for profile page "+ - "(node_id=%d, name=%s): %v", - node.NodeID, node.Cfg.Name, err) - } - defer logFile.Close() - - _, err = logFile.Write(body) - if err != nil { - return fmt.Errorf("failed to save profile page "+ - "(node_id=%d, name=%s): %v", - node.NodeID, node.Cfg.Name, err) - } - return nil -} - -// OpenChannelParams houses the params to specify when opening a new channel. -type OpenChannelParams struct { - // Amt is the local amount being put into the channel. - Amt btcutil.Amount - - // PushAmt is the amount that should be pushed to the remote when the - // channel is opened. - PushAmt btcutil.Amount - - // Private is a boolan indicating whether the opened channel should be - // private. - Private bool - - // SpendUnconfirmed is a boolean indicating whether we can utilize - // unconfirmed outputs to fund the channel. - SpendUnconfirmed bool - - // MinHtlc is the htlc_minimum_msat value set when opening the channel. - MinHtlc lnwire.MilliSatoshi - - // RemoteMaxHtlcs is the remote_max_htlcs value set when opening the - // channel, restricting the number of concurrent HTLCs the remote party - // can add to a commitment. - RemoteMaxHtlcs uint16 - - // FundingShim is an optional funding shim that the caller can specify - // in order to modify the channel funding workflow. - FundingShim *lnrpc.FundingShim - - // SatPerVByte is the amount of satoshis to spend in chain fees per virtual - // byte of the transaction. - SatPerVByte btcutil.Amount - - // CommitmentType is the commitment type that should be used for the - // channel to be opened. - CommitmentType lnrpc.CommitmentType - - // ZeroConf is used to determine if the channel will be a zero-conf - // channel. This only works if the explicit negotiation is used with - // anchors or script enforced leases. - ZeroConf bool - - // ScidAlias denotes whether the channel will be an option-scid-alias - // channel type negotiation. - ScidAlias bool - - // BaseFee is the channel base fee applied during the channel - // announcement phase. - BaseFee uint64 - - // FeeRate is the channel fee rate in ppm applied during the channel - // announcement phase. - FeeRate uint64 - - // UseBaseFee, if set, instructs the downstream logic to apply the - // user-specified channel base fee to the channel update announcement. - // If set to false it avoids applying a base fee of 0 and instead - // activates the default configured base fee. - UseBaseFee bool - - // UseFeeRate, if set, instructs the downstream logic to apply the - // user-specified channel fee rate to the channel update announcement. - // If set to false it avoids applying a fee rate of 0 and instead - // activates the default configured fee rate. - UseFeeRate bool -} - -// OpenChannel attempts to open a channel between srcNode and destNode with the -// passed channel funding parameters. If the passed context has a timeout, then -// if the timeout is reached before the channel pending notification is -// received, an error is returned. The confirmed boolean determines whether we -// should fund the channel with confirmed outputs or not. -func (n *NetworkHarness) OpenChannel(srcNode, destNode *HarnessNode, - p OpenChannelParams) (lnrpc.Lightning_OpenChannelClient, error) { - - // Wait until srcNode and destNode have the latest chain synced. - // Otherwise, we may run into a check within the funding manager that - // prevents any funding workflows from being kicked off if the chain - // isn't yet synced. - if err := srcNode.WaitForBlockchainSync(); err != nil { - return nil, fmt.Errorf("unable to sync srcNode chain: %v", err) - } - if err := destNode.WaitForBlockchainSync(); err != nil { - return nil, fmt.Errorf("unable to sync destNode chain: %v", err) - } - - minConfs := int32(1) - if p.SpendUnconfirmed { - minConfs = 0 - } - - openReq := &lnrpc.OpenChannelRequest{ - NodePubkey: destNode.PubKey[:], - LocalFundingAmount: int64(p.Amt), - PushSat: int64(p.PushAmt), - Private: p.Private, - MinConfs: minConfs, - SpendUnconfirmed: p.SpendUnconfirmed, - MinHtlcMsat: int64(p.MinHtlc), - RemoteMaxHtlcs: uint32(p.RemoteMaxHtlcs), - FundingShim: p.FundingShim, - SatPerByte: int64(p.SatPerVByte), - CommitmentType: p.CommitmentType, - ZeroConf: p.ZeroConf, - ScidAlias: p.ScidAlias, - BaseFee: p.BaseFee, - FeeRate: p.FeeRate, - UseBaseFee: p.UseBaseFee, - UseFeeRate: p.UseFeeRate, - } - - // We need to use n.runCtx here to keep the response stream alive after - // the function is returned. - respStream, err := srcNode.OpenChannel(n.runCtx, openReq) - if err != nil { - return nil, fmt.Errorf("unable to open channel between "+ - "alice and bob: %v", err) - } - - chanOpen := make(chan struct{}) - errChan := make(chan error) - go func() { - // Consume the "channel pending" update. This waits until the - // node notifies us that the final message in the channel - // funding workflow has been sent to the remote node. - resp, err := respStream.Recv() - if err != nil { - errChan <- err - return - } - _, ok := resp.Update.(*lnrpc.OpenStatusUpdate_ChanPending) - if !ok { - errChan <- fmt.Errorf("expected channel pending: "+ - "update, instead got %v", resp) - return - } - - close(chanOpen) - }() - - select { - case <-time.After(ChannelOpenTimeout): - return nil, fmt.Errorf("timeout reached before chan pending "+ - "update sent: %v", err) - case err := <-errChan: - return nil, err - case <-chanOpen: - return respStream, nil - } -} - -// OpenPendingChannel attempts to open a channel between srcNode and destNode -// with the passed channel funding parameters. If the passed context has a -// timeout, then if the timeout is reached before the channel pending -// notification is received, an error is returned. -func (n *NetworkHarness) OpenPendingChannel(srcNode, destNode *HarnessNode, - amt btcutil.Amount, - pushAmt btcutil.Amount) (*lnrpc.PendingUpdate, error) { - - // Wait until srcNode and destNode have blockchain synced - if err := srcNode.WaitForBlockchainSync(); err != nil { - return nil, fmt.Errorf("unable to sync srcNode chain: %v", err) - } - if err := destNode.WaitForBlockchainSync(); err != nil { - return nil, fmt.Errorf("unable to sync destNode chain: %v", err) - } - - openReq := &lnrpc.OpenChannelRequest{ - NodePubkey: destNode.PubKey[:], - LocalFundingAmount: int64(amt), - PushSat: int64(pushAmt), - Private: false, - } - - // We need to use n.runCtx here to keep the response stream alive after - // the function is returned. - respStream, err := srcNode.OpenChannel(n.runCtx, openReq) - if err != nil { - return nil, fmt.Errorf("unable to open channel between "+ - "alice and bob: %v", err) - } - - chanPending := make(chan *lnrpc.PendingUpdate) - errChan := make(chan error) - go func() { - // Consume the "channel pending" update. This waits until the - // node notifies us that the final message in the channel - // funding workflow has been sent to the remote node. - resp, err := respStream.Recv() - if err != nil { - errChan <- err - return - } - pendingResp, ok := resp.Update.(*lnrpc.OpenStatusUpdate_ChanPending) - if !ok { - errChan <- fmt.Errorf("expected channel pending "+ - "update, instead got %v", resp) - return - } - - chanPending <- pendingResp.ChanPending - }() - - select { - case <-time.After(ChannelOpenTimeout): - return nil, fmt.Errorf("timeout reached before chan pending " + - "update sent") - case err := <-errChan: - return nil, err - case pendingChan := <-chanPending: - return pendingChan, nil - } -} - -// WaitForChannelOpen waits for a notification that a channel is open by -// consuming a message from the past open channel stream. If the passed context -// has a timeout, then if the timeout is reached before the channel has been -// opened, then an error is returned. -func (n *NetworkHarness) WaitForChannelOpen( - openChanStream lnrpc.Lightning_OpenChannelClient) ( - *lnrpc.ChannelPoint, error) { - - ctx, cancel := context.WithTimeout(n.runCtx, ChannelOpenTimeout) - defer cancel() - - errChan := make(chan error) - respChan := make(chan *lnrpc.ChannelPoint) - go func() { - resp, err := openChanStream.Recv() - if err != nil { - errChan <- fmt.Errorf("unable to read rpc resp: %v", err) - return - } - fundingResp, ok := resp.Update.(*lnrpc.OpenStatusUpdate_ChanOpen) - if !ok { - errChan <- fmt.Errorf("expected channel open update, "+ - "instead got %v", resp) - return - } - - respChan <- fundingResp.ChanOpen.ChannelPoint - }() - - select { - case <-ctx.Done(): - return nil, fmt.Errorf("timeout reached while waiting for " + - "channel open") - case err := <-errChan: - return nil, err - case chanPoint := <-respChan: - return chanPoint, nil - } -} - -// CloseChannel attempts to close the channel indicated by the -// passed channel point, initiated by the passed lnNode. If the passed context -// has a timeout, an error is returned if that timeout is reached before the -// channel close is pending. -func (n *NetworkHarness) CloseChannel(lnNode *HarnessNode, - cp *lnrpc.ChannelPoint, force bool) (lnrpc.Lightning_CloseChannelClient, - *chainhash.Hash, error) { - - // The cancel is intentionally left out here because the returned - // item(close channel client) relies on the context being active. This - // will be fixed once we finish refactoring the NetworkHarness. - ctxt, cancel := context.WithTimeout(n.runCtx, ChannelCloseTimeout) - defer cancel() - - // Create a channel outpoint that we can use to compare to channels - // from the ListChannelsResponse. - txidHash, err := getChanPointFundingTxid(cp) - if err != nil { - return nil, nil, err - } - fundingTxID, err := chainhash.NewHash(txidHash) - if err != nil { - return nil, nil, err - } - chanPoint := wire.OutPoint{ - Hash: *fundingTxID, - Index: cp.OutputIndex, - } - - // We'll wait for *both* nodes to read the channel as active if we're - // performing a cooperative channel closure. - if !force { - timeout := DefaultTimeout - listReq := &lnrpc.ListChannelsRequest{} - - // We define two helper functions, one two locate a particular - // channel, and the other to check if a channel is active or - // not. - filterChannel := func(node *HarnessNode, - op wire.OutPoint) (*lnrpc.Channel, error) { - - listResp, err := node.ListChannels(ctxt, listReq) - if err != nil { - return nil, err - } - - for _, c := range listResp.Channels { - if c.ChannelPoint == op.String() { - return c, nil - } - } - - return nil, fmt.Errorf("unable to find channel") - } - activeChanPredicate := func(node *HarnessNode) func() bool { - return func() bool { - channel, err := filterChannel(node, chanPoint) - if err != nil { - return false - } - - return channel.Active - } - } - - // Next, we'll fetch the target channel in order to get the - // harness node that will be receiving the channel close - // request. - targetChan, err := filterChannel(lnNode, chanPoint) - if err != nil { - return nil, nil, err - } - receivingNode, err := n.LookUpNodeByPub(targetChan.RemotePubkey) - if err != nil { - return nil, nil, err - } - - // Before proceeding, we'll ensure that the channel is active - // for both nodes. - err = wait.Predicate(activeChanPredicate(lnNode), timeout) - if err != nil { - return nil, nil, fmt.Errorf("channel of closing " + - "node not active in time") - } - err = wait.Predicate( - activeChanPredicate(receivingNode), timeout, - ) - if err != nil { - return nil, nil, fmt.Errorf("channel of receiving " + - "node not active in time") - } - } - - var ( - closeRespStream lnrpc.Lightning_CloseChannelClient - closeTxid *chainhash.Hash - ) - - err = wait.NoError(func() error { - closeReq := &lnrpc.CloseChannelRequest{ - ChannelPoint: cp, Force: force, - } - // We need to use n.runCtx to keep the client stream alive - // after the function has returned. - closeRespStream, err = lnNode.CloseChannel(n.runCtx, closeReq) - if err != nil { - return fmt.Errorf("unable to close channel: %v", err) - } - - // Consume the "channel close" update in order to wait for the - // closing transaction to be broadcast, then wait for the - // closing tx to be seen within the network. - closeResp, err := closeRespStream.Recv() - if err != nil { - return fmt.Errorf("unable to recv() from close "+ - "stream: %v", err) - } - pendingClose, ok := closeResp.Update.(*lnrpc.CloseStatusUpdate_ClosePending) - if !ok { - return fmt.Errorf("expected channel close update, "+ - "instead got %v", pendingClose) - } - - closeTxid, err = chainhash.NewHash( - pendingClose.ClosePending.Txid, - ) - if err != nil { - return fmt.Errorf("unable to decode closeTxid: "+ - "%v", err) - } - if err := n.Miner.waitForTxInMempool(*closeTxid); err != nil { - return fmt.Errorf("error while waiting for "+ - "broadcast tx: %v", err) - } - return nil - }, ChannelCloseTimeout) - if err != nil { - return nil, nil, err - } - - return closeRespStream, closeTxid, nil -} - -// WaitForChannelClose waits for a notification from the passed channel close -// stream that the node has deemed the channel has been fully closed. If the -// passed context has a timeout, then if the timeout is reached before the -// notification is received then an error is returned. -func (n *NetworkHarness) WaitForChannelClose( - closeChanStream lnrpc.Lightning_CloseChannelClient) ( - *chainhash.Hash, error) { - - errChan := make(chan error) - updateChan := make(chan *lnrpc.CloseStatusUpdate_ChanClose) - go func() { - closeResp, err := closeChanStream.Recv() - if err != nil { - errChan <- err - return - } - - closeFin, ok := closeResp.Update.(*lnrpc.CloseStatusUpdate_ChanClose) - if !ok { - errChan <- fmt.Errorf("expected channel close update, "+ - "instead got %v", closeFin) - return - } - - updateChan <- closeFin - }() - - // Wait until either the deadline for the context expires, an error - // occurs, or the channel close update is received. - select { - case <-time.After(ChannelCloseTimeout): - return nil, fmt.Errorf("timeout reached before update sent") - case err := <-errChan: - return nil, err - case update := <-updateChan: - return chainhash.NewHash(update.ChanClose.ClosingTxid) - } -} - -// AssertChannelExists asserts that an active channel identified by the -// specified channel point exists from the point-of-view of the node. It takes -// an optional set of check functions which can be used to make further -// assertions using channel's values. These functions are responsible for -// failing the test themselves if they do not pass. -func (n *NetworkHarness) AssertChannelExists(node *HarnessNode, - chanPoint *wire.OutPoint, checks ...func(*lnrpc.Channel)) error { - - ctx, cancel := context.WithTimeout(n.runCtx, ChannelCloseTimeout) - defer cancel() - - req := &lnrpc.ListChannelsRequest{} - - return wait.NoError(func() error { - resp, err := node.ListChannels(ctx, req) - if err != nil { - return fmt.Errorf("unable fetch node's channels: %v", err) - } - - for _, channel := range resp.Channels { - if channel.ChannelPoint == chanPoint.String() { - // First check whether our channel is active, - // failing early if it is not. - if !channel.Active { - return fmt.Errorf("channel %s inactive", - chanPoint) - } - - // Apply any additional checks that we would - // like to verify. - for _, check := range checks { - check(channel) - } - - return nil - } - } - - return fmt.Errorf("channel %s not found", chanPoint) - }, DefaultTimeout) -} - -// DumpLogs reads the current logs generated by the passed node, and returns -// the logs as a single string. This function is useful for examining the logs -// of a particular node in the case of a test failure. -// Logs from lightning node being generated with delay - you should -// add time.Sleep() in order to get all logs. -func (n *NetworkHarness) DumpLogs(node *HarnessNode) (string, error) { - logFile := fmt.Sprintf("%v/simnet/lnd.log", node.Cfg.LogDir) - - buf, err := ioutil.ReadFile(logFile) - if err != nil { - return "", err - } - - return string(buf), nil -} - -// SendCoins attempts to send amt satoshis from the internal mining node to the -// targeted lightning node using a P2WKH address. 6 blocks are mined after in -// order to confirm the transaction. -func (n *NetworkHarness) SendCoins(t *testing.T, amt btcutil.Amount, - target *HarnessNode) { - - err := n.SendCoinsOfType( - amt, target, lnrpc.AddressType_WITNESS_PUBKEY_HASH, true, - ) - require.NoErrorf(t, err, "unable to send coins for %s", target.Cfg.Name) -} - -// SendCoinsUnconfirmed sends coins from the internal mining node to the target -// lightning node using a P2WPKH address. No blocks are mined after, so the -// transaction remains unconfirmed. -func (n *NetworkHarness) SendCoinsUnconfirmed(t *testing.T, amt btcutil.Amount, - target *HarnessNode) { - - err := n.SendCoinsOfType( - amt, target, lnrpc.AddressType_WITNESS_PUBKEY_HASH, false, - ) - require.NoErrorf( - t, err, "unable to send unconfirmed coins for %s", - target.Cfg.Name, - ) -} - -// SendCoinsNP2WKH attempts to send amt satoshis from the internal mining node -// to the targeted lightning node using a NP2WKH address. -func (n *NetworkHarness) SendCoinsNP2WKH(t *testing.T, amt btcutil.Amount, - target *HarnessNode) { - - err := n.SendCoinsOfType( - amt, target, lnrpc.AddressType_NESTED_PUBKEY_HASH, true, - ) - require.NoErrorf( - t, err, "unable to send NP2WKH coins for %s", - target.Cfg.Name, - ) -} - -// SendCoinsP2TR attempts to send amt satoshis from the internal mining node -// to the targeted lightning node using a P2TR address. -func (n *NetworkHarness) SendCoinsP2TR(t *testing.T, amt btcutil.Amount, - target *HarnessNode) { - - err := n.SendCoinsOfType( - amt, target, lnrpc.AddressType_TAPROOT_PUBKEY, true, - ) - require.NoErrorf( - t, err, "unable to send P2TR coins for %s", target.Cfg.Name, - ) -} - -// SendCoinsOfType attempts to send amt satoshis from the internal mining node -// to the targeted lightning node. The confirmed boolean indicates whether the -// transaction that pays to the target should confirm. -func (n *NetworkHarness) SendCoinsOfType(amt btcutil.Amount, target *HarnessNode, - addrType lnrpc.AddressType, confirmed bool) error { - - ctx, cancel := context.WithTimeout(n.runCtx, DefaultTimeout) - defer cancel() - - balReq := &lnrpc.WalletBalanceRequest{} - initialBalance, err := target.WalletBalance(ctx, balReq) - if err != nil { - return err - } - - // First, obtain an address from the target lightning node, preferring - // to receive a p2wkh address s.t the output can immediately be used as - // an input to a funding transaction. - addrReq := &lnrpc.NewAddressRequest{ - Type: addrType, - } - resp, err := target.NewAddress(ctx, addrReq) - if err != nil { - return err - } - addr, err := btcutil.DecodeAddress(resp.Address, n.netParams) - if err != nil { - return err - } - addrScript, err := txscript.PayToAddrScript(addr) - if err != nil { - return err - } - - // Generate a transaction which creates an output to the target - // pkScript of the desired amount. - output := &wire.TxOut{ - PkScript: addrScript, - Value: int64(amt), - } - _, err = n.Miner.SendOutputs([]*wire.TxOut{output}, 7500) - if err != nil { - return err - } - - // Encode the pkScript in hex as this the format that it will be - // returned via rpc. - expPkScriptStr := hex.EncodeToString(addrScript) - - // Now, wait for ListUnspent to show the unconfirmed transaction - // containing the correct pkscript. - err = wait.NoError(func() error { - // Since neutrino doesn't support unconfirmed outputs, skip - // this check. - if target.Cfg.BackendCfg.Name() == "neutrino" { - return nil - } - - req := &lnrpc.ListUnspentRequest{} - resp, err := target.ListUnspent(ctx, req) - if err != nil { - return err - } - - // When using this method, there should only ever be on - // unconfirmed transaction. - if len(resp.Utxos) != 1 { - return fmt.Errorf("number of unconfirmed utxos "+ - "should be 1, found %d", len(resp.Utxos)) - } - - // Assert that the lone unconfirmed utxo contains the same - // pkscript as the output generated above. - pkScriptStr := resp.Utxos[0].PkScript - if strings.Compare(pkScriptStr, expPkScriptStr) != 0 { - return fmt.Errorf("pkscript mismatch, want: %s, "+ - "found: %s", expPkScriptStr, pkScriptStr) - } - - return nil - }, DefaultTimeout) - if err != nil { - return fmt.Errorf("unconfirmed utxo was not found in "+ - "ListUnspent: %v", err) - } - - // If the transaction should remain unconfirmed, then we'll wait until - // the target node's unconfirmed balance reflects the expected balance - // and exit. - if !confirmed { - expectedBalance := btcutil.Amount(initialBalance.UnconfirmedBalance) + amt - return target.WaitForBalance(expectedBalance, false) - } - - // Otherwise, we'll generate 6 new blocks to ensure the output gains a - // sufficient number of confirmations and wait for the balance to - // reflect what's expected. - if _, err := n.Miner.Client.Generate(6); err != nil { - return err - } - - fullInitialBalance := initialBalance.ConfirmedBalance + - initialBalance.UnconfirmedBalance - expectedBalance := btcutil.Amount(fullInitialBalance) + amt - return target.WaitForBalance(expectedBalance, true) -} - -func (n *NetworkHarness) SetFeeEstimate(fee chainfee.SatPerKWeight) { - n.feeService.setFee(fee) -} - -func (n *NetworkHarness) SetFeeEstimateWithConf( - fee chainfee.SatPerKWeight, conf uint32) { - - n.feeService.setFeeWithConf(fee, conf) -} - -// copyAll copies all files and directories from srcDir to dstDir recursively. -// Note that this function does not support links. -func copyAll(dstDir, srcDir string) error { - entries, err := ioutil.ReadDir(srcDir) - if err != nil { - return err - } - - for _, entry := range entries { - srcPath := filepath.Join(srcDir, entry.Name()) - dstPath := filepath.Join(dstDir, entry.Name()) - - info, err := os.Stat(srcPath) - if err != nil { - return err - } - - if info.IsDir() { - err := os.Mkdir(dstPath, info.Mode()) - if err != nil && !os.IsExist(err) { - return err - } - - err = copyAll(dstPath, srcPath) - if err != nil { - return err - } - } else if err := CopyFile(dstPath, srcPath); err != nil { - return err - } - } - - return nil -} - -// BackupDb creates a backup of the current database. -func (n *NetworkHarness) BackupDb(hn *HarnessNode) error { - if hn.backupDbDir != "" { - return errors.New("backup already created") - } - - restart, err := n.SuspendNode(hn) - if err != nil { - return err - } - - if hn.postgresDbName != "" { - // Backup database. - backupDbName := hn.postgresDbName + "_backup" - err := executePgQuery( - "CREATE DATABASE " + backupDbName + " WITH TEMPLATE " + - hn.postgresDbName, - ) - if err != nil { - return err - } - } else { - // Backup files. - tempDir, err := ioutil.TempDir("", "past-state") - if err != nil { - return fmt.Errorf("unable to create temp db folder: %v", - err) - } - - if err := copyAll(tempDir, hn.DBDir()); err != nil { - return fmt.Errorf("unable to copy database files: %v", - err) - } - - hn.backupDbDir = tempDir - } - - err = restart() - if err != nil { - return err - } - - return nil -} - -// RestoreDb restores a database backup. -func (n *NetworkHarness) RestoreDb(hn *HarnessNode) error { - if hn.postgresDbName != "" { - // Restore database. - backupDbName := hn.postgresDbName + "_backup" - err := executePgQuery( - "DROP DATABASE " + hn.postgresDbName, - ) - if err != nil { - return err - } - err = executePgQuery( - "ALTER DATABASE " + backupDbName + " RENAME TO " + hn.postgresDbName, - ) - if err != nil { - return err - } - } else { - // Restore files. - if hn.backupDbDir == "" { - return errors.New("no database backup created") - } - - if err := copyAll(hn.DBDir(), hn.backupDbDir); err != nil { - return fmt.Errorf("unable to copy database files: %v", err) - } - - if err := os.RemoveAll(hn.backupDbDir); err != nil { - return fmt.Errorf("unable to remove backup dir: %v", err) - } - hn.backupDbDir = "" - } - - return nil -} - -// getChanPointFundingTxid returns the given channel point's funding txid in -// raw bytes. -func getChanPointFundingTxid(chanPoint *lnrpc.ChannelPoint) ([]byte, error) { - var txid []byte - - // A channel point's funding txid can be get/set as a byte slice or a - // string. In the case it is a string, decode it. - switch chanPoint.GetFundingTxid().(type) { - case *lnrpc.ChannelPoint_FundingTxidBytes: - txid = chanPoint.GetFundingTxidBytes() - case *lnrpc.ChannelPoint_FundingTxidStr: - s := chanPoint.GetFundingTxidStr() - h, err := chainhash.NewHashFromStr(s) - if err != nil { - return nil, err - } - - txid = h[:] - } - - return txid, nil -} diff --git a/lntest/harness_node.go b/lntest/harness_node.go deleted file mode 100644 index 26dc90498..000000000 --- a/lntest/harness_node.go +++ /dev/null @@ -1,1928 +0,0 @@ -package lntest - -import ( - "bytes" - "context" - "crypto/rand" - "encoding/hex" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path" - "path/filepath" - "strings" - "sync" - "time" - - "github.com/btcsuite/btcd/btcutil" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - "github.com/jackc/pgx/v4/pgxpool" - "github.com/lightningnetwork/lnd/chanbackup" - "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lnrpc/chainrpc" - "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" - "github.com/lightningnetwork/lnd/lnrpc/neutrinorpc" - "github.com/lightningnetwork/lnd/lnrpc/peersrpc" - "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lnrpc/signrpc" - "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lnrpc/watchtowerrpc" - "github.com/lightningnetwork/lnd/lnrpc/wtclientrpc" - "github.com/lightningnetwork/lnd/lntest/wait" - "github.com/lightningnetwork/lnd/macaroons" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/status" - "gopkg.in/macaroon.v2" -) - -const ( - // logPubKeyBytes is the number of bytes of the node's PubKey that will - // be appended to the log file name. The whole PubKey is too long and - // not really necessary to quickly identify what node produced which - // log file. - logPubKeyBytes = 4 - - // trickleDelay is the amount of time in milliseconds between each - // release of announcements by AuthenticatedGossiper to the network. - trickleDelay = 50 - - postgresDsn = "postgres://postgres:postgres@localhost:6432/%s?sslmode=disable" - - // commitInterval specifies the maximum interval the graph database - // will wait between attempting to flush a batch of modifications to - // disk(db.batch-commit-interval). - commitInterval = 10 * time.Millisecond - - DefaultTimeout = wait.DefaultTimeout - NodeStartTimeout = wait.NodeStartTimeout - ChannelOpenTimeout = wait.ChannelOpenTimeout - ChannelCloseTimeout = wait.ChannelCloseTimeout -) - -var ( - // numActiveNodes is the number of active nodes within the test network. - numActiveNodes = 0 - numActiveNodesMtx sync.Mutex -) - -func postgresDatabaseDsn(dbName string) string { - return fmt.Sprintf(postgresDsn, dbName) -} - -// BackendConfig is an interface that abstracts away the specific chain backend -// node implementation. -type BackendConfig interface { - // GenArgs returns the arguments needed to be passed to LND at startup - // for using this node as a chain backend. - GenArgs() []string - - // ConnectMiner is called to establish a connection to the test miner. - ConnectMiner() error - - // DisconnectMiner is called to disconnect the miner. - DisconnectMiner() error - - // Name returns the name of the backend type. - Name() string - - // Credentials returns the rpc username, password and host for the - // backend. - Credentials() (string, string, string, error) -} - -// NodeConfig is the basic interface a node configuration must implement. -type NodeConfig interface { - // BaseConfig returns the base node configuration struct. - BaseConfig() *BaseNodeConfig - - // GenerateListeningPorts generates the ports to listen on designated - // for the current lightning network test. - GenerateListeningPorts() - - // GenArgs generates a slice of command line arguments from the - // lightning node config struct. - GenArgs() []string -} - -// BaseNodeConfig is the base node configuration. -type BaseNodeConfig struct { - Name string - - // LogFilenamePrefix is used to prefix node log files. Can be used - // to store the current test case for simpler postmortem debugging. - LogFilenamePrefix string - - BackendCfg BackendConfig - NetParams *chaincfg.Params - BaseDir string - ExtraArgs []string - - DataDir string - LogDir string - TLSCertPath string - TLSKeyPath string - AdminMacPath string - ReadMacPath string - InvoiceMacPath string - - HasSeed bool - Password []byte - - P2PPort int - RPCPort int - RESTPort int - ProfilePort int - - AcceptKeySend bool - AcceptAMP bool - - FeeURL string - - DbBackend DatabaseBackend - PostgresDsn string -} - -func (cfg BaseNodeConfig) P2PAddr() string { - return fmt.Sprintf(ListenerFormat, cfg.P2PPort) -} - -func (cfg BaseNodeConfig) RPCAddr() string { - return fmt.Sprintf(ListenerFormat, cfg.RPCPort) -} - -func (cfg BaseNodeConfig) RESTAddr() string { - return fmt.Sprintf(ListenerFormat, cfg.RESTPort) -} - -// DBDir returns the holding directory path of the graph database. -func (cfg BaseNodeConfig) DBDir() string { - return filepath.Join(cfg.DataDir, "graph", cfg.NetParams.Name) -} - -func (cfg BaseNodeConfig) DBPath() string { - return filepath.Join(cfg.DBDir(), "channel.db") -} - -func (cfg BaseNodeConfig) ChanBackupPath() string { - return filepath.Join( - cfg.DataDir, "chain", "bitcoin", - fmt.Sprintf( - "%v/%v", cfg.NetParams.Name, - chanbackup.DefaultBackupFileName, - ), - ) -} - -// GenerateListeningPorts generates the ports to listen on designated for the -// current lightning network test. -func (cfg *BaseNodeConfig) GenerateListeningPorts() { - if cfg.P2PPort == 0 { - cfg.P2PPort = NextAvailablePort() - } - if cfg.RPCPort == 0 { - cfg.RPCPort = NextAvailablePort() - } - if cfg.RESTPort == 0 { - cfg.RESTPort = NextAvailablePort() - } - if cfg.ProfilePort == 0 { - cfg.ProfilePort = NextAvailablePort() - } -} - -// BaseConfig returns the base node configuration struct. -func (cfg *BaseNodeConfig) BaseConfig() *BaseNodeConfig { - return cfg -} - -// GenArgs generates a slice of command line arguments from the lightning node -// config struct. -func (cfg *BaseNodeConfig) GenArgs() []string { - var args []string - - switch cfg.NetParams { - case &chaincfg.TestNet3Params: - args = append(args, "--bitcoin.testnet") - case &chaincfg.SimNetParams: - args = append(args, "--bitcoin.simnet") - case &chaincfg.RegressionNetParams: - args = append(args, "--bitcoin.regtest") - } - - backendArgs := cfg.BackendCfg.GenArgs() - args = append(args, backendArgs...) - - nodeArgs := []string{ - "--bitcoin.active", - "--nobootstrap", - "--debuglevel=debug", - "--bitcoin.defaultchanconfs=1", - "--keep-failed-payment-attempts", - fmt.Sprintf("--db.batch-commit-interval=%v", commitInterval), - fmt.Sprintf("--bitcoin.defaultremotedelay=%v", DefaultCSV), - fmt.Sprintf("--rpclisten=%v", cfg.RPCAddr()), - fmt.Sprintf("--restlisten=%v", cfg.RESTAddr()), - fmt.Sprintf("--restcors=https://%v", cfg.RESTAddr()), - fmt.Sprintf("--listen=%v", cfg.P2PAddr()), - fmt.Sprintf("--externalip=%v", cfg.P2PAddr()), - fmt.Sprintf("--lnddir=%v", cfg.BaseDir), - fmt.Sprintf("--adminmacaroonpath=%v", cfg.AdminMacPath), - fmt.Sprintf("--readonlymacaroonpath=%v", cfg.ReadMacPath), - fmt.Sprintf("--invoicemacaroonpath=%v", cfg.InvoiceMacPath), - fmt.Sprintf("--trickledelay=%v", trickleDelay), - fmt.Sprintf("--profile=%d", cfg.ProfilePort), - fmt.Sprintf("--caches.rpc-graph-cache-duration=%d", 0), - } - args = append(args, nodeArgs...) - - if !cfg.HasSeed { - args = append(args, "--noseedbackup") - } - - if cfg.ExtraArgs != nil { - args = append(args, cfg.ExtraArgs...) - } - - if cfg.AcceptKeySend { - args = append(args, "--accept-keysend") - } - - if cfg.AcceptAMP { - args = append(args, "--accept-amp") - } - - switch cfg.DbBackend { - case BackendEtcd: - args = append(args, "--db.backend=etcd") - args = append(args, "--db.etcd.embedded") - args = append( - args, fmt.Sprintf( - "--db.etcd.embedded_client_port=%v", - NextAvailablePort(), - ), - ) - args = append( - args, fmt.Sprintf( - "--db.etcd.embedded_peer_port=%v", - NextAvailablePort(), - ), - ) - args = append( - args, fmt.Sprintf( - "--db.etcd.embedded_log_file=%v", - path.Join(cfg.LogDir, "etcd.log"), - ), - ) - - case BackendPostgres: - args = append(args, "--db.backend=postgres") - args = append(args, "--db.postgres.dsn="+cfg.PostgresDsn) - - case BackendSqlite: - args = append(args, "--db.backend=sqlite") - args = append(args, fmt.Sprintf("--db.sqlite.busytimeout=%v", - wait.SqliteBusyTimeout)) - } - - if cfg.FeeURL != "" { - args = append(args, "--feeurl="+cfg.FeeURL) - } - - return args -} - -// policyUpdateMap defines a type to store channel policy updates. It has the -// format, -// -// { -// "chanPoint1": { -// "advertisingNode1": [ -// policy1, policy2, ... -// ], -// "advertisingNode2": [ -// policy1, policy2, ... -// ] -// }, -// "chanPoint2": ... -// }. -type policyUpdateMap map[string]map[string][]*lnrpc.RoutingPolicy - -// HarnessNode represents an instance of lnd running within our test network -// harness. Each HarnessNode instance also fully embeds an RPC client in -// order to pragmatically drive the node. -type HarnessNode struct { - Cfg *BaseNodeConfig - - // NodeID is a unique identifier for the node within a NetworkHarness. - NodeID int - - // PubKey is the serialized compressed identity public key of the node. - // This field will only be populated once the node itself has been - // started via the start() method. - PubKey [33]byte - PubKeyStr string - - // rpc holds a list of RPC clients. - rpc *RPCClients - - // chanWatchRequests receives a request for watching a particular event - // for a given channel. - chanWatchRequests chan *chanWatchRequest - - // For each outpoint, we'll track an integer which denotes the number of - // edges seen for that channel within the network. When this number - // reaches 2, then it means that both edge advertisements has propagated - // through the network. - openChans map[wire.OutPoint]int - openChanWatchers map[wire.OutPoint][]chan struct{} - - closedChans map[wire.OutPoint]struct{} - closeChanWatchers map[wire.OutPoint][]chan struct{} - - // policyUpdates stores a slice of seen polices by each advertising - // node and the outpoint. - policyUpdates policyUpdateMap - - // backupDbDir is the path where a database backup is stored, if any. - backupDbDir string - - // postgresDbName is the name of the postgres database where lnd data is - // stored in. - postgresDbName string - - // runCtx is a context with cancel method. It's used to signal when the - // node needs to quit, and used as the parent context when spawning - // children contexts for RPC requests. - runCtx context.Context - cancel context.CancelFunc - - wg sync.WaitGroup - cmd *exec.Cmd - logFile *os.File - - // TODO(yy): remove - lnrpc.LightningClient - lnrpc.WalletUnlockerClient - invoicesrpc.InvoicesClient - peersrpc.PeersClient - SignerClient signrpc.SignerClient - RouterClient routerrpc.RouterClient - WalletKitClient walletrpc.WalletKitClient - Watchtower watchtowerrpc.WatchtowerClient - WatchtowerClient wtclientrpc.WatchtowerClientClient - StateClient lnrpc.StateClient - ChainClient chainrpc.ChainNotifierClient - ChainKit chainrpc.ChainKitClient - NeutrinoClient neutrinorpc.NeutrinoKitClient -} - -// RPCClients wraps a list of RPC clients into a single struct for easier -// access. -type RPCClients struct { - // conn is the underlying connection to the grpc endpoint of the node. - conn *grpc.ClientConn - - LN lnrpc.LightningClient - WalletUnlocker lnrpc.WalletUnlockerClient - Invoice invoicesrpc.InvoicesClient - Signer signrpc.SignerClient - Router routerrpc.RouterClient - WalletKit walletrpc.WalletKitClient - Watchtower watchtowerrpc.WatchtowerClient - WatchtowerClient wtclientrpc.WatchtowerClientClient - State lnrpc.StateClient - ChainClient chainrpc.ChainNotifierClient - ChainKit chainrpc.ChainKitClient - NeutrinoClient neutrinorpc.NeutrinoKitClient -} - -// Assert *HarnessNode implements the lnrpc.LightningClient interface. -var _ lnrpc.LightningClient = (*HarnessNode)(nil) -var _ lnrpc.WalletUnlockerClient = (*HarnessNode)(nil) -var _ invoicesrpc.InvoicesClient = (*HarnessNode)(nil) -var _ peersrpc.PeersClient = (*HarnessNode)(nil) - -// nextNodeID generates a unique sequence to be used as the node's ID. -func nextNodeID() int { - numActiveNodesMtx.Lock() - defer numActiveNodesMtx.Unlock() - nodeNum := numActiveNodes - numActiveNodes++ - - return nodeNum -} - -// newNode creates a new test lightning node instance from the passed config. -func newNode(cfg *BaseNodeConfig) (*HarnessNode, error) { - if cfg.BaseDir == "" { - var err error - cfg.BaseDir, err = ioutil.TempDir("", "lndtest-node") - if err != nil { - return nil, err - } - } - cfg.DataDir = filepath.Join(cfg.BaseDir, "data") - cfg.LogDir = filepath.Join(cfg.BaseDir, "logs") - cfg.TLSCertPath = filepath.Join(cfg.BaseDir, "tls.cert") - cfg.TLSKeyPath = filepath.Join(cfg.BaseDir, "tls.key") - - networkDir := filepath.Join( - cfg.DataDir, "chain", "bitcoin", cfg.NetParams.Name, - ) - cfg.AdminMacPath = filepath.Join(networkDir, "admin.macaroon") - cfg.ReadMacPath = filepath.Join(networkDir, "readonly.macaroon") - cfg.InvoiceMacPath = filepath.Join(networkDir, "invoice.macaroon") - - cfg.GenerateListeningPorts() - - // Run all tests with accept keysend. The keysend code is very isolated - // and it is highly unlikely that it would affect regular itests when - // enabled. - cfg.AcceptKeySend = true - - // Create temporary database. - var dbName string - if cfg.DbBackend == BackendPostgres { - var err error - dbName, err = createTempPgDb() - if err != nil { - return nil, err - } - cfg.PostgresDsn = postgresDatabaseDsn(dbName) - } - - return &HarnessNode{ - Cfg: cfg, - NodeID: nextNodeID(), - chanWatchRequests: make(chan *chanWatchRequest), - openChans: make(map[wire.OutPoint]int), - openChanWatchers: make(map[wire.OutPoint][]chan struct{}), - - closedChans: make(map[wire.OutPoint]struct{}), - closeChanWatchers: make(map[wire.OutPoint][]chan struct{}), - - policyUpdates: policyUpdateMap{}, - - postgresDbName: dbName, - }, nil -} - -func createTempPgDb() (string, error) { - // Create random database name. - randBytes := make([]byte, 8) - _, err := rand.Read(randBytes) - if err != nil { - return "", err - } - dbName := "itest_" + hex.EncodeToString(randBytes) - - // Create database. - err = executePgQuery("CREATE DATABASE " + dbName) - if err != nil { - return "", err - } - - return dbName, nil -} - -func executePgQuery(query string) error { - pool, err := pgxpool.Connect( - context.Background(), - postgresDatabaseDsn("postgres"), - ) - if err != nil { - return fmt.Errorf("unable to connect to database: %w", err) - } - defer pool.Close() - - _, err = pool.Exec(context.Background(), query) - return err -} - -// String gives the internal state of the node which is useful for debugging. -func (hn *HarnessNode) String() string { - type nodeCfg struct { - LogFilenamePrefix string - ExtraArgs []string - HasSeed bool - P2PPort int - RPCPort int - RESTPort int - ProfilePort int - AcceptKeySend bool - AcceptAMP bool - FeeURL string - } - - nodeState := struct { - NodeID int - Name string - PubKey string - OpenChans map[string]int - ClosedChans map[string]struct{} - NodeCfg nodeCfg - }{ - NodeID: hn.NodeID, - Name: hn.Cfg.Name, - PubKey: hn.PubKeyStr, - OpenChans: make(map[string]int), - ClosedChans: make(map[string]struct{}), - NodeCfg: nodeCfg{ - LogFilenamePrefix: hn.Cfg.LogFilenamePrefix, - ExtraArgs: hn.Cfg.ExtraArgs, - HasSeed: hn.Cfg.HasSeed, - P2PPort: hn.Cfg.P2PPort, - RPCPort: hn.Cfg.RPCPort, - RESTPort: hn.Cfg.RESTPort, - AcceptKeySend: hn.Cfg.AcceptKeySend, - AcceptAMP: hn.Cfg.AcceptAMP, - FeeURL: hn.Cfg.FeeURL, - }, - } - - for outpoint, count := range hn.openChans { - nodeState.OpenChans[outpoint.String()] = count - } - for outpoint, count := range hn.closedChans { - nodeState.ClosedChans[outpoint.String()] = count - } - - stateBytes, err := json.MarshalIndent(nodeState, "", "\t") - if err != nil { - return fmt.Sprintf("\n encode node state with err: %v", err) - } - - return fmt.Sprintf("\nnode state: %s", stateBytes) -} - -// DBPath returns the filepath to the channeldb database file for this node. -func (hn *HarnessNode) DBPath() string { - return hn.Cfg.DBPath() -} - -// DBDir returns the path for the directory holding channeldb file(s). -func (hn *HarnessNode) DBDir() string { - return hn.Cfg.DBDir() -} - -// Name returns the name of this node set during initialization. -func (hn *HarnessNode) Name() string { - return hn.Cfg.Name -} - -// TLSCertStr returns the path where the TLS certificate is stored. -func (hn *HarnessNode) TLSCertStr() string { - return hn.Cfg.TLSCertPath -} - -// TLSKeyStr returns the path where the TLS key is stored. -func (hn *HarnessNode) TLSKeyStr() string { - return hn.Cfg.TLSKeyPath -} - -// ChanBackupPath returns the fielpath to the on-disk channel.backup file for -// this node. -func (hn *HarnessNode) ChanBackupPath() string { - return hn.Cfg.ChanBackupPath() -} - -// AdminMacPath returns the filepath to the admin.macaroon file for this node. -func (hn *HarnessNode) AdminMacPath() string { - return hn.Cfg.AdminMacPath -} - -// ReadMacPath returns the filepath to the readonly.macaroon file for this node. -func (hn *HarnessNode) ReadMacPath() string { - return hn.Cfg.ReadMacPath -} - -// InvoiceMacPath returns the filepath to the invoice.macaroon file for this -// node. -func (hn *HarnessNode) InvoiceMacPath() string { - return hn.Cfg.InvoiceMacPath -} - -// startLnd handles the startup of lnd, creating log files, and possibly kills -// the process when needed. -func (hn *HarnessNode) startLnd(lndBinary string, lndError chan<- error) error { - args := hn.Cfg.GenArgs() - hn.cmd = exec.Command(lndBinary, args...) - - // Redirect stderr output to buffer - var errb bytes.Buffer - hn.cmd.Stderr = &errb - - // If the logoutput flag is passed, redirect output from the nodes to - // log files. - var ( - fileName string - err error - ) - if *LogOutput { - fileName, err = addLogFile(hn) - if err != nil { - return err - } - } - - if err := hn.cmd.Start(); err != nil { - return err - } - - // Launch a new goroutine which that bubbles up any potential fatal - // process errors to the goroutine running the tests. - hn.wg.Add(1) - go func() { - defer hn.wg.Done() - - err := hn.cmd.Wait() - if err != nil { - lndError <- fmt.Errorf("%v\n%v", err, errb.String()) - } - - // Make sure log file is closed and renamed if necessary. - finalizeLogfile(hn, fileName) - - // Rename the etcd.log file if the node was running on embedded - // etcd. - finalizeEtcdLog(hn) - }() - - return nil -} - -// Start launches a new process running lnd. Additionally, the PID of the -// launched process is saved in order to possibly kill the process forcibly -// later. -// -// This may not clean up properly if an error is returned, so the caller should -// call shutdown() regardless of the return value. -func (hn *HarnessNode) start(lndBinary string, lndError chan<- error, - wait bool) error { - - // Init the runCtx. - ctxt, cancel := context.WithCancel(context.Background()) - hn.runCtx = ctxt - hn.cancel = cancel - - // Start lnd and prepare logs. - if err := hn.startLnd(lndBinary, lndError); err != nil { - return err - } - - // We may want to skip waiting for the node to come up (eg. the node - // is waiting to become the leader). - if !wait { - return nil - } - - // Since Stop uses the LightningClient to stop the node, if we fail to - // get a connected client, we have to kill the process. - useMacaroons := !hn.Cfg.HasSeed - conn, err := hn.ConnectRPC(useMacaroons) - if err != nil { - err = fmt.Errorf("ConnectRPC err: %w", err) - cmdErr := hn.cmd.Process.Kill() - if cmdErr != nil { - err = fmt.Errorf("kill process got err: %w: %v", - cmdErr, err) - } - return err - } - - // Init all the RPC clients. - hn.InitRPCClients(conn) - - if err := hn.WaitUntilStarted(); err != nil { - return err - } - - // If the node was created with a seed, we will need to perform an - // additional step to unlock the wallet. The connection returned will - // only use the TLS certs, and can only perform operations necessary to - // unlock the daemon. - if hn.Cfg.HasSeed { - // TODO(yy): remove - hn.WalletUnlockerClient = lnrpc.NewWalletUnlockerClient(conn) - return nil - } - - return hn.initLightningClient() -} - -// WaitUntilStarted waits until the wallet state flips from "WAITING_TO_START". -func (hn *HarnessNode) WaitUntilStarted() error { - return hn.waitTillServerState(func(s lnrpc.WalletState) bool { - return s != lnrpc.WalletState_WAITING_TO_START - }) -} - -// WaitUntilStateReached waits until the given wallet state (or one of the -// states following it) has been reached. -func (hn *HarnessNode) WaitUntilStateReached( - desiredState lnrpc.WalletState) error { - - return hn.waitTillServerState(func(s lnrpc.WalletState) bool { - return s >= desiredState - }) -} - -// WaitUntilServerActive waits until the lnd daemon is fully started. -func (hn *HarnessNode) WaitUntilServerActive() error { - return hn.waitTillServerState(func(s lnrpc.WalletState) bool { - return s == lnrpc.WalletState_SERVER_ACTIVE - }) -} - -// WaitUntilLeader attempts to finish the start procedure by initiating an RPC -// connection and setting up the wallet unlocker client. This is needed when -// a node that has recently been started was waiting to become the leader and -// we're at the point when we expect that it is the leader now (awaiting -// unlock). -func (hn *HarnessNode) WaitUntilLeader(timeout time.Duration) error { - var ( - conn *grpc.ClientConn - connErr error - ) - - if err := wait.NoError(func() error { - conn, connErr = hn.ConnectRPC(!hn.Cfg.HasSeed) - return connErr - }, timeout); err != nil { - return err - } - - // Init all the RPC clients. - hn.InitRPCClients(conn) - - if err := hn.WaitUntilStarted(); err != nil { - return err - } - - // If the node was created with a seed, we will need to perform an - // additional step to unlock the wallet. The connection returned will - // only use the TLS certs, and can only perform operations necessary to - // unlock the daemon. - if hn.Cfg.HasSeed { - // TODO(yy): remove - hn.WalletUnlockerClient = lnrpc.NewWalletUnlockerClient(conn) - - return nil - } - - return hn.initLightningClient() -} - -// initClientWhenReady waits until the main gRPC server is detected as active, -// then complete the normal HarnessNode gRPC connection creation. If the node -// is initialized stateless, the macaroon is returned so that the client can -// use it. -func (hn *HarnessNode) initClientWhenReady(stateless bool, - macBytes []byte) error { - - // Wait for the wallet to finish unlocking, such that we can connect to - // it via a macaroon-authenticated rpc connection. - var ( - conn *grpc.ClientConn - err error - ) - if err = wait.NoError(func() error { - // If the node has been initialized stateless, we need to pass - // the macaroon to the client. - if stateless { - adminMac := &macaroon.Macaroon{} - err := adminMac.UnmarshalBinary(macBytes) - if err != nil { - return fmt.Errorf("unmarshal failed: %w", err) - } - conn, err = hn.ConnectRPCWithMacaroon(adminMac) - return err - } - - // Normal initialization, we expect a macaroon to be in the - // file system. - conn, err = hn.ConnectRPC(true) - return err - }, DefaultTimeout); err != nil { - return fmt.Errorf("timeout while init client: %w", err) - } - - // Init all the RPC clients. - hn.InitRPCClients(conn) - - return hn.initLightningClient() -} - -// Init initializes a harness node by passing the init request via rpc. After -// the request is submitted, this method will block until a -// macaroon-authenticated RPC connection can be established to the harness -// node. Once established, the new connection is used to initialize the -// LightningClient and subscribes the HarnessNode to topology changes. -func (hn *HarnessNode) Init( - initReq *lnrpc.InitWalletRequest) (*lnrpc.InitWalletResponse, error) { - - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - response, err := hn.rpc.WalletUnlocker.InitWallet(ctxt, initReq) - if err != nil { - return nil, fmt.Errorf("failed to init wallet: %w", err) - } - - err = hn.initClientWhenReady( - initReq.StatelessInit, response.AdminMacaroon, - ) - if err != nil { - return nil, fmt.Errorf("failed to init: %w", err) - } - - return response, nil -} - -// InitChangePassword initializes a harness node by passing the change password -// request via RPC. After the request is submitted, this method will block until -// a macaroon-authenticated RPC connection can be established to the harness -// node. Once established, the new connection is used to initialize the -// LightningClient and subscribes the HarnessNode to topology changes. -func (hn *HarnessNode) InitChangePassword( - chngPwReq *lnrpc.ChangePasswordRequest) (*lnrpc.ChangePasswordResponse, - error) { - - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - response, err := hn.rpc.WalletUnlocker.ChangePassword(ctxt, chngPwReq) - if err != nil { - return nil, err - } - err = hn.initClientWhenReady( - chngPwReq.StatelessInit, response.AdminMacaroon, - ) - if err != nil { - return nil, err - } - - return response, nil -} - -// Unlock attempts to unlock the wallet of the target HarnessNode. This method -// should be called after the restart of a HarnessNode that was created with a -// seed+password. Once this method returns, the HarnessNode will be ready to -// accept normal gRPC requests and harness command. -func (hn *HarnessNode) Unlock(unlockReq *lnrpc.UnlockWalletRequest) error { - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - // Otherwise, we'll need to unlock the node before it's able to start - // up properly. - _, err := hn.rpc.WalletUnlocker.UnlockWallet(ctxt, unlockReq) - if err != nil { - return err - } - - // Now that the wallet has been unlocked, we'll wait for the RPC client - // to be ready, then establish the normal gRPC connection. - return hn.initClientWhenReady(false, nil) -} - -// waitTillServerState makes a subscription to the server's state change and -// blocks until the server is in the targeted state. -func (hn *HarnessNode) waitTillServerState( - predicate func(state lnrpc.WalletState) bool) error { - - ctxt, cancel := context.WithTimeout(hn.runCtx, NodeStartTimeout) - defer cancel() - - client, err := hn.rpc.State.SubscribeState( - ctxt, &lnrpc.SubscribeStateRequest{}, - ) - if err != nil { - return fmt.Errorf("failed to subscribe to state: %w", err) - } - - errChan := make(chan error, 1) - done := make(chan struct{}) - go func() { - for { - resp, err := client.Recv() - if err != nil { - errChan <- err - return - } - - if predicate(resp.State) { - close(done) - return - } - } - }() - - var lastErr error - for { - select { - case err := <-errChan: - lastErr = err - - case <-done: - return nil - - case <-time.After(NodeStartTimeout): - return fmt.Errorf("timeout waiting for state, "+ - "got err from stream: %v", lastErr) - } - } -} - -// InitRPCClients initializes a list of RPC clients for the node. -func (hn *HarnessNode) InitRPCClients(c *grpc.ClientConn) { - hn.rpc = &RPCClients{ - conn: c, - LN: lnrpc.NewLightningClient(c), - Invoice: invoicesrpc.NewInvoicesClient(c), - Router: routerrpc.NewRouterClient(c), - WalletKit: walletrpc.NewWalletKitClient(c), - WalletUnlocker: lnrpc.NewWalletUnlockerClient(c), - Watchtower: watchtowerrpc.NewWatchtowerClient(c), - WatchtowerClient: wtclientrpc.NewWatchtowerClientClient(c), - Signer: signrpc.NewSignerClient(c), - State: lnrpc.NewStateClient(c), - ChainClient: chainrpc.NewChainNotifierClient(c), - ChainKit: chainrpc.NewChainKitClient(c), - NeutrinoClient: neutrinorpc.NewNeutrinoKitClient(c), - } -} - -// initLightningClient blocks until the lnd server is fully started and -// subscribes the harness node to graph topology updates. This method also -// spawns a lightning network watcher for this node, which watches for topology -// changes. -func (hn *HarnessNode) initLightningClient() error { - // TODO(yy): remove - // Construct the LightningClient that will allow us to use the - // HarnessNode directly for normal rpc operations. - conn := hn.rpc.conn - hn.LightningClient = lnrpc.NewLightningClient(conn) - hn.InvoicesClient = invoicesrpc.NewInvoicesClient(conn) - hn.RouterClient = routerrpc.NewRouterClient(conn) - hn.WalletKitClient = walletrpc.NewWalletKitClient(conn) - hn.Watchtower = watchtowerrpc.NewWatchtowerClient(conn) - hn.WatchtowerClient = wtclientrpc.NewWatchtowerClientClient(conn) - hn.SignerClient = signrpc.NewSignerClient(conn) - hn.PeersClient = peersrpc.NewPeersClient(conn) - hn.StateClient = lnrpc.NewStateClient(conn) - hn.ChainClient = chainrpc.NewChainNotifierClient(conn) - hn.ChainKit = chainrpc.NewChainKitClient(conn) - hn.NeutrinoClient = neutrinorpc.NewNeutrinoKitClient(conn) - - // Wait until the server is fully started. - if err := hn.WaitUntilServerActive(); err != nil { - return err - } - - // Set the harness node's pubkey to what the node claims in GetInfo. - // The RPC must have been started at this point. - if err := hn.FetchNodeInfo(); err != nil { - return err - } - - // Launch the watcher that will hook into graph related topology change - // from the PoV of this node. - hn.wg.Add(1) - go hn.lightningNetworkWatcher() - - return nil -} - -// FetchNodeInfo queries an unlocked node to retrieve its public key. -func (hn *HarnessNode) FetchNodeInfo() error { - // Obtain the lnid of this node for quick identification purposes. - info, err := hn.rpc.LN.GetInfo(hn.runCtx, &lnrpc.GetInfoRequest{}) - if err != nil { - return err - } - - hn.PubKeyStr = info.IdentityPubkey - - pubkey, err := hex.DecodeString(info.IdentityPubkey) - if err != nil { - return err - } - copy(hn.PubKey[:], pubkey) - - return nil -} - -// AddToLogf adds a line of choice to the node's logfile. This is useful -// to interleave test output with output from the node. -func (hn *HarnessNode) AddToLogf(format string, a ...interface{}) { - // If this node was not set up with a log file, just return early. - if hn.logFile == nil { - return - } - - desc := fmt.Sprintf("itest: %s\n", fmt.Sprintf(format, a...)) - if _, err := hn.logFile.WriteString(desc); err != nil { - hn.PrintErrf("write to log err: %v", err) - } -} - -// ReadMacaroon waits a given duration for the macaroon file to be created. If -// the file is readable within the timeout, its content is de-serialized as a -// macaroon and returned. -func (hn *HarnessNode) ReadMacaroon(macPath string, timeout time.Duration) ( - *macaroon.Macaroon, error) { - - // Wait until macaroon file is created and has valid content before - // using it. - var mac *macaroon.Macaroon - err := wait.NoError(func() error { - macBytes, err := ioutil.ReadFile(macPath) - if err != nil { - return fmt.Errorf("error reading macaroon file: %v", - err) - } - - newMac := &macaroon.Macaroon{} - if err = newMac.UnmarshalBinary(macBytes); err != nil { - return fmt.Errorf("error unmarshalling macaroon "+ - "file: %v", err) - } - mac = newMac - - return nil - }, timeout) - - return mac, err -} - -// ConnectRPCWithMacaroon uses the TLS certificate and given macaroon to -// create a gRPC client connection. -func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) ( - *grpc.ClientConn, error) { - - // Wait until TLS certificate is created and has valid content before - // using it, up to 30 sec. - var tlsCreds credentials.TransportCredentials - err := wait.NoError(func() error { - var err error - tlsCreds, err = credentials.NewClientTLSFromFile( - hn.Cfg.TLSCertPath, "", - ) - return err - }, DefaultTimeout) - if err != nil { - return nil, fmt.Errorf("error reading TLS cert: %v", err) - } - - opts := []grpc.DialOption{ - grpc.WithBlock(), - grpc.WithTransportCredentials(tlsCreds), - } - - ctx, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - if mac == nil { - return grpc.DialContext(ctx, hn.Cfg.RPCAddr(), opts...) - } - macCred, err := macaroons.NewMacaroonCredential(mac) - if err != nil { - return nil, fmt.Errorf("error cloning mac: %v", err) - } - opts = append(opts, grpc.WithPerRPCCredentials(macCred)) - - return grpc.DialContext(ctx, hn.Cfg.RPCAddr(), opts...) -} - -// ConnectRPC uses the TLS certificate and admin macaroon files written by the -// lnd node to create a gRPC client connection. -func (hn *HarnessNode) ConnectRPC(useMacs bool) (*grpc.ClientConn, error) { - // If we don't want to use macaroons, just pass nil, the next method - // will handle it correctly. - if !useMacs { - return hn.ConnectRPCWithMacaroon(nil) - } - - // If we should use a macaroon, always take the admin macaroon as a - // default. - mac, err := hn.ReadMacaroon(hn.Cfg.AdminMacPath, DefaultTimeout) - if err != nil { - return nil, err - } - return hn.ConnectRPCWithMacaroon(mac) -} - -// SetExtraArgs assigns the ExtraArgs field for the node's configuration. The -// changes will take effect on restart. -func (hn *HarnessNode) SetExtraArgs(extraArgs []string) { - hn.Cfg.ExtraArgs = extraArgs -} - -// cleanup cleans up all the temporary files created by the node's process. -func (hn *HarnessNode) cleanup() error { - if hn.backupDbDir != "" { - err := os.RemoveAll(hn.backupDbDir) - if err != nil { - return fmt.Errorf("unable to remove backup dir: %v", - err) - } - } - - return os.RemoveAll(hn.Cfg.BaseDir) -} - -// Stop attempts to stop the active lnd process. -func (hn *HarnessNode) stop() error { - // Do nothing if the process is not running. - if hn.runCtx == nil { - return nil - } - - // If start() failed before creating clients, we will just wait for the - // child process to die. - if hn.rpc != nil && hn.rpc.LN != nil { - // Don't watch for error because sometimes the RPC connection - // gets closed before a response is returned. - req := lnrpc.StopRequest{} - - err := wait.NoError(func() error { - _, err := hn.rpc.LN.StopDaemon(hn.runCtx, &req) - switch { - case err == nil: - return nil - - // Try again if a recovery/rescan is in progress. - case strings.Contains( - err.Error(), "recovery in progress", - ): - return err - - default: - return nil - } - }, DefaultTimeout) - if err != nil { - return err - } - } - - // Stop the runCtx and wait for goroutines to finish. - hn.cancel() - - // Wait for lnd process to exit. - err := wait.NoError(func() error { - if hn.cmd.ProcessState == nil { - return fmt.Errorf("process did not exit") - } - - if !hn.cmd.ProcessState.Exited() { - return fmt.Errorf("process did not exit") - } - - // Wait for goroutines to be finished. - hn.wg.Wait() - - return nil - }, DefaultTimeout*2) - if err != nil { - return err - } - - hn.LightningClient = nil - hn.WalletUnlockerClient = nil - hn.Watchtower = nil - hn.WatchtowerClient = nil - hn.NeutrinoClient = nil - - // Close any attempts at further grpc connections. - if hn.rpc.conn != nil { - err := status.Code(hn.rpc.conn.Close()) - switch err { - case codes.OK: - return nil - - // When the context is canceled above, we might get the - // following error as the context is no longer active. - case codes.Canceled: - return nil - - case codes.Unknown: - return fmt.Errorf("unknown error attempting to stop "+ - "grpc client: %v", err) - - default: - return fmt.Errorf("error attempting to stop "+ - "grpc client: %v", err) - } - } - - return nil -} - -// shutdown stops the active lnd process and cleans up any temporary -// directories created along the way. -func (hn *HarnessNode) shutdown() error { - if err := hn.stop(); err != nil { - return err - } - if err := hn.cleanup(); err != nil { - return err - } - return nil -} - -// kill kills the lnd process. -func (hn *HarnessNode) kill() error { - return hn.cmd.Process.Kill() -} - -type chanWatchType uint8 - -const ( - // watchOpenChannel specifies that this is a request to watch an open - // channel event. - watchOpenChannel chanWatchType = iota - - // watchCloseChannel specifies that this is a request to watch a close - // channel event. - watchCloseChannel - - // watchPolicyUpdate specifies that this is a request to watch a policy - // update event. - watchPolicyUpdate -) - -// closeChanWatchRequest is a request to the lightningNetworkWatcher to be -// notified once it's detected within the test Lightning Network, that a -// channel has either been added or closed. -type chanWatchRequest struct { - chanPoint wire.OutPoint - - chanWatchType chanWatchType - - eventChan chan struct{} - - advertisingNode string - policy *lnrpc.RoutingPolicy - includeUnannounced bool -} - -func (hn *HarnessNode) checkChanPointInGraph(chanPoint wire.OutPoint) bool { - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - chanGraph, err := hn.DescribeGraph(ctxt, &lnrpc.ChannelGraphRequest{}) - if err != nil { - return false - } - - targetChanPoint := chanPoint.String() - for _, chanEdge := range chanGraph.Edges { - candidateChanPoint := chanEdge.ChanPoint - if targetChanPoint == candidateChanPoint { - return true - } - } - - return false -} - -// lightningNetworkWatcher is a goroutine which is able to dispatch -// notifications once it has been observed that a target channel has been -// closed or opened within the network. In order to dispatch these -// notifications, the GraphTopologySubscription client exposed as part of the -// gRPC interface is used. -func (hn *HarnessNode) lightningNetworkWatcher() { - defer hn.wg.Done() - - graphUpdates := make(chan *lnrpc.GraphTopologyUpdate) - - // Start a goroutine to receive graph updates. - hn.wg.Add(1) - go func() { - defer hn.wg.Done() - err := hn.receiveTopologyClientStream(graphUpdates) - - if err != nil { - hn.PrintErrf("receive topology client stream "+ - "got err:%v", err) - } - }() - - for { - select { - // A new graph update has just been received, so we'll examine - // the current set of registered clients to see if we can - // dispatch any requests. - case graphUpdate := <-graphUpdates: - hn.handleChannelEdgeUpdates(graphUpdate.ChannelUpdates) - hn.handleClosedChannelUpdate(graphUpdate.ClosedChans) - // TODO(yy): handle node updates too - - // A new watch request, has just arrived. We'll either be able - // to dispatch immediately, or need to add the client for - // processing later. - case watchRequest := <-hn.chanWatchRequests: - switch watchRequest.chanWatchType { - case watchOpenChannel: - // TODO(roasbeef): add update type also, checks - // for multiple of 2 - hn.handleOpenChannelWatchRequest(watchRequest) - - case watchCloseChannel: - hn.handleCloseChannelWatchRequest(watchRequest) - - case watchPolicyUpdate: - hn.handlePolicyUpdateWatchRequest(watchRequest) - } - - case <-hn.runCtx.Done(): - return - } - } -} - -// WaitForNetworkChannelOpen will block until a channel with the target -// outpoint is seen as being fully advertised within the network. A channel is -// considered "fully advertised" once both of its directional edges have been -// advertised within the test Lightning Network. -func (hn *HarnessNode) WaitForNetworkChannelOpen( - chanPoint *lnrpc.ChannelPoint) error { - - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - eventChan := make(chan struct{}) - - op, err := MakeOutpoint(chanPoint) - if err != nil { - return fmt.Errorf("failed to create outpoint for %v "+ - "got err: %v", chanPoint, err) - } - - hn.chanWatchRequests <- &chanWatchRequest{ - chanPoint: op, - eventChan: eventChan, - chanWatchType: watchOpenChannel, - } - - select { - case <-eventChan: - return nil - case <-ctxt.Done(): - return fmt.Errorf("channel:%s not opened before timeout: %s", - op, hn) - } -} - -// WaitForNetworkChannelClose will block until a channel with the target -// outpoint is seen as closed within the network. A channel is considered -// closed once a transaction spending the funding outpoint is seen within a -// confirmed block. -func (hn *HarnessNode) WaitForNetworkChannelClose( - chanPoint *lnrpc.ChannelPoint) error { - - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - eventChan := make(chan struct{}) - - op, err := MakeOutpoint(chanPoint) - if err != nil { - return fmt.Errorf("failed to create outpoint for %v "+ - "got err: %v", chanPoint, err) - } - - hn.chanWatchRequests <- &chanWatchRequest{ - chanPoint: op, - eventChan: eventChan, - chanWatchType: watchCloseChannel, - } - - select { - case <-eventChan: - return nil - case <-ctxt.Done(): - return fmt.Errorf("channel:%s not closed before timeout: "+ - "%s", op, hn) - } -} - -// WaitForChannelPolicyUpdate will block until a channel policy with the target -// outpoint and advertisingNode is seen within the network. -func (hn *HarnessNode) WaitForChannelPolicyUpdate( - advertisingNode string, policy *lnrpc.RoutingPolicy, - chanPoint *lnrpc.ChannelPoint, includeUnannounced bool) error { - - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - eventChan := make(chan struct{}) - - op, err := MakeOutpoint(chanPoint) - if err != nil { - return fmt.Errorf("failed to create outpoint for %v"+ - "got err: %v", chanPoint, err) - } - - ticker := time.NewTicker(wait.PollInterval) - defer ticker.Stop() - - for { - select { - // Send a watch request every second. - case <-ticker.C: - // Did the event can close in the meantime? We want to - // avoid a "close of closed channel" panic since we're - // re-using the same event chan for multiple requests. - select { - case <-eventChan: - return nil - default: - } - - hn.chanWatchRequests <- &chanWatchRequest{ - chanPoint: op, - eventChan: eventChan, - chanWatchType: watchPolicyUpdate, - policy: policy, - advertisingNode: advertisingNode, - includeUnannounced: includeUnannounced, - } - - case <-eventChan: - return nil - - case <-ctxt.Done(): - return fmt.Errorf("channel:%s policy not updated "+ - "before timeout: [%s:%v] %s", op, - advertisingNode, policy, hn.String()) - } - } -} - -// WaitForBlockchainSync waits for the target node to be fully synchronized -// with the blockchain. If the passed context object has a set timeout, it will -// continually poll until the timeout has elapsed. In the case that the chain -// isn't synced before the timeout is up, this function will return an error. -func (hn *HarnessNode) WaitForBlockchainSync() error { - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - ticker := time.NewTicker(time.Millisecond * 100) - defer ticker.Stop() - - for { - resp, err := hn.rpc.LN.GetInfo(ctxt, &lnrpc.GetInfoRequest{}) - if err != nil { - return err - } - if resp.SyncedToChain { - return nil - } - - select { - case <-ctxt.Done(): - return fmt.Errorf("timeout while waiting for " + - "blockchain sync") - case <-hn.runCtx.Done(): - return nil - case <-ticker.C: - } - } -} - -// WaitForBalance waits until the node sees the expected confirmed/unconfirmed -// balance within their wallet. -func (hn *HarnessNode) WaitForBalance(expectedBalance btcutil.Amount, - confirmed bool) error { - - req := &lnrpc.WalletBalanceRequest{} - - var lastBalance btcutil.Amount - doesBalanceMatch := func() bool { - balance, err := hn.rpc.LN.WalletBalance(hn.runCtx, req) - if err != nil { - return false - } - - if confirmed { - lastBalance = btcutil.Amount(balance.ConfirmedBalance) - return btcutil.Amount(balance.ConfirmedBalance) == - expectedBalance - } - - lastBalance = btcutil.Amount(balance.UnconfirmedBalance) - return btcutil.Amount(balance.UnconfirmedBalance) == - expectedBalance - } - - err := wait.Predicate(doesBalanceMatch, DefaultTimeout) - if err != nil { - return fmt.Errorf("balances not synced after deadline: "+ - "expected %v, only have %v", expectedBalance, - lastBalance) - } - - return nil -} - -// PrintErrf prints an error to the console. -func (hn *HarnessNode) PrintErrf(format string, a ...interface{}) { - fmt.Printf("itest error from [node:%s]: %s\n", // nolint:forbidigo - hn.Cfg.Name, fmt.Sprintf(format, a...)) -} - -// handleChannelEdgeUpdates takes a series of channel edge updates, extracts -// the outpoints, and saves them to harness node's internal state. -func (hn *HarnessNode) handleChannelEdgeUpdates( - updates []*lnrpc.ChannelEdgeUpdate) { - - // For each new channel, we'll increment the number of - // edges seen by one. - for _, newChan := range updates { - op, err := MakeOutpoint(newChan.ChanPoint) - if err != nil { - hn.PrintErrf("failed to create outpoint for %v "+ - "got err: %v", newChan.ChanPoint, err) - return - } - hn.openChans[op]++ - - // For this new channel, if the number of edges seen is less - // than two, then the channel hasn't been fully announced yet. - if numEdges := hn.openChans[op]; numEdges < 2 { - return - } - - // Otherwise, we'll notify all the registered watchers and - // remove the dispatched watchers. - for _, eventChan := range hn.openChanWatchers[op] { - close(eventChan) - } - delete(hn.openChanWatchers, op) - - // Check whether there's a routing policy update. If so, save - // it to the node state. - if newChan.RoutingPolicy == nil { - continue - } - - // Append the policy to the slice. - node := newChan.AdvertisingNode - policies := hn.policyUpdates[op.String()] - - // If the map[op] is nil, we need to initialize the map first. - if policies == nil { - policies = make(map[string][]*lnrpc.RoutingPolicy) - } - policies[node] = append( - policies[node], newChan.RoutingPolicy, - ) - hn.policyUpdates[op.String()] = policies - } -} - -// handleOpenChannelWatchRequest processes a watch open channel request by -// checking the number of the edges seen for a given channel point. If the -// number is no less than 2 then the channel is considered open. Otherwise, we -// will attempt to find it in its channel graph. If neither can be found, the -// request is added to a watch request list than will be handled by -// handleChannelEdgeUpdates. -func (hn *HarnessNode) handleOpenChannelWatchRequest(req *chanWatchRequest) { - targetChan := req.chanPoint - - // If this is an open request, then it can be dispatched if the number - // of edges seen for the channel is at least two. - if numEdges := hn.openChans[targetChan]; numEdges >= 2 { - close(req.eventChan) - return - } - - // Before we add the channel to our set of open clients, we'll check to - // see if the channel is already in the channel graph of the target - // node. This lets us handle the case where a node has already seen a - // channel before a notification has been requested, causing us to miss - // it. - chanFound := hn.checkChanPointInGraph(targetChan) - if chanFound { - close(req.eventChan) - return - } - - // Otherwise, we'll add this to the list of open channel watchers for - // this out point. - hn.openChanWatchers[targetChan] = append( - hn.openChanWatchers[targetChan], - req.eventChan, - ) -} - -// handleClosedChannelUpdate takes a series of closed channel updates, extracts -// the outpoints, saves them to harness node's internal state, and notifies all -// registered clients. -func (hn *HarnessNode) handleClosedChannelUpdate( - updates []*lnrpc.ClosedChannelUpdate) { - - // For each channel closed, we'll mark that we've detected a channel - // closure while lnd was pruning the channel graph. - for _, closedChan := range updates { - op, err := MakeOutpoint(closedChan.ChanPoint) - if err != nil { - hn.PrintErrf("failed to create outpoint for %v "+ - "got err: %v", closedChan.ChanPoint, err) - return - } - - hn.closedChans[op] = struct{}{} - - // As the channel has been closed, we'll notify all register - // watchers. - for _, eventChan := range hn.closeChanWatchers[op] { - close(eventChan) - } - delete(hn.closeChanWatchers, op) - } -} - -// handleCloseChannelWatchRequest processes a watch close channel request by -// checking whether the given channel point can be found in the node's internal -// state. If not, the request is added to a watch request list than will be -// handled by handleCloseChannelWatchRequest. -func (hn *HarnessNode) handleCloseChannelWatchRequest(req *chanWatchRequest) { - targetChan := req.chanPoint - - // If this is a close request, then it can be immediately dispatched if - // we've already seen a channel closure for this channel. - if _, ok := hn.closedChans[targetChan]; ok { - close(req.eventChan) - return - } - - // Otherwise, we'll add this to the list of close channel watchers for - // this out point. - hn.closeChanWatchers[targetChan] = append( - hn.closeChanWatchers[targetChan], - req.eventChan, - ) -} - -type topologyClient lnrpc.Lightning_SubscribeChannelGraphClient - -// newTopologyClient creates a topology client. -func (hn *HarnessNode) newTopologyClient( - ctx context.Context) (topologyClient, error) { - - req := &lnrpc.GraphTopologySubscription{} - client, err := hn.rpc.LN.SubscribeChannelGraph(ctx, req) - if err != nil { - return nil, fmt.Errorf("%s(%d): unable to create topology "+ - "client: %v (%s)", hn.Name(), hn.NodeID, err, - time.Now().String()) - } - - return client, nil -} - -// receiveTopologyClientStream initializes a topologyClient to subscribe -// topology update events. Due to a race condition between the ChannelRouter -// starting and us making the subscription request, it's possible for our graph -// subscription to fail. In that case, we will retry the subscription until it -// succeeds or fail after 10 seconds. -// -// NOTE: must be run as a goroutine. -func (hn *HarnessNode) receiveTopologyClientStream( - receiver chan *lnrpc.GraphTopologyUpdate) error { - - // Create a topology client to receive graph updates. - client, err := hn.newTopologyClient(hn.runCtx) - if err != nil { - return fmt.Errorf("create topologyClient failed: %w", err) - } - - // We use the context to time out when retrying graph subscription. - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - for { - update, err := client.Recv() - - switch { - case err == nil: - // Good case. We will send the update to the receiver. - - case strings.Contains(err.Error(), "router not started"): - // If the router hasn't been started, we will retry - // every 200 ms until it has been started or fail - // after the ctxt is timed out. - select { - case <-ctxt.Done(): - return fmt.Errorf("graph subscription: " + - "router not started before timeout") - case <-time.After(wait.PollInterval): - case <-hn.runCtx.Done(): - return nil - } - - // Re-create the topology client. - client, err = hn.newTopologyClient(hn.runCtx) - if err != nil { - return fmt.Errorf("create topologyClient "+ - "failed: %v", err) - } - - continue - - case strings.Contains(err.Error(), "EOF"): - // End of subscription stream. Do nothing and quit. - return nil - - case strings.Contains(err.Error(), context.Canceled.Error()): - // End of subscription stream. Do nothing and quit. - return nil - - default: - // An expected error is returned, return and leave it - // to be handled by the caller. - return fmt.Errorf("graph subscription err: %w", err) - } - - // Send the update or quit. - select { - case receiver <- update: - case <-hn.runCtx.Done(): - return nil - } - } -} - -// handlePolicyUpdateWatchRequest checks that if the expected policy can be -// found either in the node's interval state or describe graph response. If -// found, it will signal the request by closing the event channel. Otherwise it -// does nothing but returns nil. -func (hn *HarnessNode) handlePolicyUpdateWatchRequest(req *chanWatchRequest) { - op := req.chanPoint - - // Get a list of known policies for this chanPoint+advertisingNode - // combination. Start searching in the node state first. - policies, ok := hn.policyUpdates[op.String()][req.advertisingNode] - - if !ok { - // If it cannot be found in the node state, try searching it - // from the node's DescribeGraph. - policyMap := hn.getChannelPolicies(req.includeUnannounced) - policies, ok = policyMap[op.String()][req.advertisingNode] - if !ok { - return - } - } - - // Check if there's a matched policy. - for _, policy := range policies { - if CheckChannelPolicy(policy, req.policy) == nil { - close(req.eventChan) - return - } - } -} - -// getChannelPolicies queries the channel graph and formats the policies into -// the format defined in type policyUpdateMap. -func (hn *HarnessNode) getChannelPolicies(include bool) policyUpdateMap { - ctxt, cancel := context.WithTimeout(hn.runCtx, DefaultTimeout) - defer cancel() - - graph, err := hn.rpc.LN.DescribeGraph(ctxt, &lnrpc.ChannelGraphRequest{ - IncludeUnannounced: include, - }) - if err != nil { - hn.PrintErrf("DescribeGraph got err: %v", err) - return nil - } - - policyUpdates := policyUpdateMap{} - - for _, e := range graph.Edges { - policies := policyUpdates[e.ChanPoint] - - // If the map[op] is nil, we need to initialize the map first. - if policies == nil { - policies = make(map[string][]*lnrpc.RoutingPolicy) - } - - if e.Node1Policy != nil { - policies[e.Node1Pub] = append( - policies[e.Node1Pub], e.Node1Policy, - ) - } - - if e.Node2Policy != nil { - policies[e.Node2Pub] = append( - policies[e.Node2Pub], e.Node2Policy, - ) - } - - policyUpdates[e.ChanPoint] = policies - } - - return policyUpdates -} - -// renameFile is a helper to rename (log) files created during integration -// tests. -func renameFile(fromFileName, toFileName string) { - err := os.Rename(fromFileName, toFileName) - if err != nil { - fmt.Printf("could not rename %s to %s: %v\n", // nolint:forbidigo - fromFileName, toFileName, err) - } -} - -// getFinalizedLogFilePrefix returns the finalize log filename. -func getFinalizedLogFilePrefix(hn *HarnessNode) string { - pubKeyHex := hex.EncodeToString( - hn.PubKey[:logPubKeyBytes], - ) - - return fmt.Sprintf("%s/%d-%s-%s-%s", - GetLogDir(), hn.NodeID, - hn.Cfg.LogFilenamePrefix, - hn.Cfg.Name, pubKeyHex) -} - -// finalizeLogfile makes sure the log file cleanup function is initialized, -// even if no log file is created. -func finalizeLogfile(hn *HarnessNode, fileName string) { - if hn.logFile != nil { - hn.logFile.Close() - - // If logoutput flag is not set, return early. - if !*LogOutput { - return - } - - newFileName := fmt.Sprintf("%v.log", - getFinalizedLogFilePrefix(hn), - ) - - renameFile(fileName, newFileName) - } -} - -func finalizeEtcdLog(hn *HarnessNode) { - if hn.Cfg.DbBackend != BackendEtcd { - return - } - - etcdLogFileName := fmt.Sprintf("%s/etcd.log", hn.Cfg.LogDir) - newEtcdLogFileName := fmt.Sprintf("%v-etcd.log", - getFinalizedLogFilePrefix(hn), - ) - - renameFile(etcdLogFileName, newEtcdLogFileName) -} - -func addLogFile(hn *HarnessNode) (string, error) { - var fileName string - - dir := GetLogDir() - fileName = fmt.Sprintf("%s/%d-%s-%s-%s.log", dir, hn.NodeID, - hn.Cfg.LogFilenamePrefix, hn.Cfg.Name, - hex.EncodeToString(hn.PubKey[:logPubKeyBytes])) - - // If the node's PubKey is not yet initialized, create a - // temporary file name. Later, after the PubKey has been - // initialized, the file can be moved to its final name with - // the PubKey included. - if bytes.Equal(hn.PubKey[:4], []byte{0, 0, 0, 0}) { - fileName = fmt.Sprintf("%s/%d-%s-%s-tmp__.log", dir, - hn.NodeID, hn.Cfg.LogFilenamePrefix, - hn.Cfg.Name) - } - - // Create file if not exists, otherwise append. - file, err := os.OpenFile(fileName, - os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) - if err != nil { - return fileName, err - } - - // Pass node's stderr to both errb and the file. - w := io.MultiWriter(hn.cmd.Stderr, file) - hn.cmd.Stderr = w - - // Pass the node's stdout only to the file. - hn.cmd.Stdout = file - - // Let the node keep a reference to this file, such - // that we can add to it if necessary. - hn.logFile = file - - return fileName, nil -} diff --git a/lntest/neutrino.go b/lntest/neutrino.go index 64e880372..9ea18a4db 100644 --- a/lntest/neutrino.go +++ b/lntest/neutrino.go @@ -7,6 +7,7 @@ import ( "fmt" "github.com/btcsuite/btcd/chaincfg" + "github.com/lightningnetwork/lnd/lntemp/node" ) // NeutrinoBackendConfig is an implementation of the BackendConfig interface @@ -17,7 +18,7 @@ type NeutrinoBackendConfig struct { // A compile time assertion to ensure NeutrinoBackendConfig meets the // BackendConfig interface. -var _ BackendConfig = (*NeutrinoBackendConfig)(nil) +var _ node.BackendConfig = (*NeutrinoBackendConfig)(nil) // GenArgs returns the arguments needed to be passed to LND at startup for // using this node as a chain backend. diff --git a/lntest/test_common.go b/lntest/test_common.go deleted file mode 100644 index 1cab0ad5c..000000000 --- a/lntest/test_common.go +++ /dev/null @@ -1,190 +0,0 @@ -package lntest - -import ( - "errors" - "flag" - "fmt" - "io" - "net" - "os" - "sync/atomic" - - "github.com/btcsuite/btcd/wire" - "github.com/lightningnetwork/lnd/lnrpc" -) - -const ( - // defaultNodePort is the start of the range for listening ports of - // harness nodes. Ports are monotonically increasing starting from this - // number and are determined by the results of nextAvailablePort(). - defaultNodePort = 5555 - - // ListenerFormat is the format string that is used to generate local - // listener addresses. - ListenerFormat = "127.0.0.1:%d" - - // NeutrinoBackendName is the name of the neutrino backend. - NeutrinoBackendName = "neutrino" -) - -type DatabaseBackend int - -const ( - BackendBbolt DatabaseBackend = iota - BackendEtcd - BackendPostgres - BackendSqlite -) - -var ( - // lastPort is the last port determined to be free for use by a new - // node. It should be used atomically. - lastPort uint32 = defaultNodePort - - // logOutput is a flag that can be set to append the output from the - // seed nodes to log files. - // - // TODO(yy): remove the export. - LogOutput = flag.Bool("logoutput", false, - "log output from node n to file output-n.log") - - // logSubDir is the default directory where the logs are written to if - // logOutput is true. - logSubDir = flag.String("logdir", ".", "default dir to write logs to") - - // goroutineDump is a flag that can be set to dump the active - // goroutines of test nodes on failure. - goroutineDump = flag.Bool("goroutinedump", false, - "write goroutine dump from node n to file pprof-n.log") - - // btcdExecutable is the full path to the btcd binary. - btcdExecutable = flag.String( - "btcdexec", "", "full path to btcd binary", - ) -) - -// NextAvailablePort returns the first port that is available for listening by -// a new node. It panics if no port is found and the maximum available TCP port -// is reached. -func NextAvailablePort() int { - port := atomic.AddUint32(&lastPort, 1) - for port < 65535 { - // If there are no errors while attempting to listen on this - // port, close the socket and return it as available. While it - // could be the case that some other process picks up this port - // between the time the socket is closed and it's reopened in - // the harness node, in practice in CI servers this seems much - // less likely than simply some other process already being - // bound at the start of the tests. - addr := fmt.Sprintf(ListenerFormat, port) - l, err := net.Listen("tcp4", addr) - if err == nil { - err := l.Close() - if err == nil { - return int(port) - } - } - port = atomic.AddUint32(&lastPort, 1) - } - - // No ports available? Must be a mistake. - panic("no ports available for listening") -} - -// ApplyPortOffset adds the given offset to the lastPort variable, making it -// possible to run the tests in parallel without colliding on the same ports. -func ApplyPortOffset(offset uint32) { - _ = atomic.AddUint32(&lastPort, offset) -} - -// GetLogDir returns the passed --logdir flag or the default value if it wasn't -// set. -func GetLogDir() string { - if logSubDir != nil && *logSubDir != "" { - return *logSubDir - } - return "." -} - -// GetBtcdBinary returns the full path to the binary of the custom built btcd -// executable or an empty string if none is set. -func GetBtcdBinary() string { - if btcdExecutable != nil { - return *btcdExecutable - } - - return "" -} - -// GenerateBtcdListenerAddresses is a function that returns two listener -// addresses with unique ports and should be used to overwrite rpctest's -// default generator which is prone to use colliding ports. -func GenerateBtcdListenerAddresses() (string, string) { - return fmt.Sprintf(ListenerFormat, NextAvailablePort()), - fmt.Sprintf(ListenerFormat, NextAvailablePort()) -} - -// MakeOutpoint returns the outpoint of the channel's funding transaction. -func MakeOutpoint(chanPoint *lnrpc.ChannelPoint) (wire.OutPoint, error) { - fundingTxID, err := lnrpc.GetChanPointFundingTxid(chanPoint) - if err != nil { - return wire.OutPoint{}, err - } - - return wire.OutPoint{ - Hash: *fundingTxID, - Index: chanPoint.OutputIndex, - }, nil -} - -// CheckChannelPolicy checks that the policy matches the expected one. -func CheckChannelPolicy(policy, expectedPolicy *lnrpc.RoutingPolicy) error { - if policy.FeeBaseMsat != expectedPolicy.FeeBaseMsat { - return fmt.Errorf("expected base fee %v, got %v", - expectedPolicy.FeeBaseMsat, policy.FeeBaseMsat) - } - if policy.FeeRateMilliMsat != expectedPolicy.FeeRateMilliMsat { - return fmt.Errorf("expected fee rate %v, got %v", - expectedPolicy.FeeRateMilliMsat, - policy.FeeRateMilliMsat) - } - if policy.TimeLockDelta != expectedPolicy.TimeLockDelta { - return fmt.Errorf("expected time lock delta %v, got %v", - expectedPolicy.TimeLockDelta, - policy.TimeLockDelta) - } - if policy.MinHtlc != expectedPolicy.MinHtlc { - return fmt.Errorf("expected min htlc %v, got %v", - expectedPolicy.MinHtlc, policy.MinHtlc) - } - if policy.MaxHtlcMsat != expectedPolicy.MaxHtlcMsat { - return fmt.Errorf("expected max htlc %v, got %v", - expectedPolicy.MaxHtlcMsat, policy.MaxHtlcMsat) - } - if policy.Disabled != expectedPolicy.Disabled { - return errors.New("edge should be disabled but isn't") - } - - return nil -} - -// CopyFile copies the file src to dest. -func CopyFile(dest, src string) error { - s, err := os.Open(src) - if err != nil { - return err - } - defer s.Close() - - d, err := os.Create(dest) - if err != nil { - return err - } - - if _, err := io.Copy(d, s); err != nil { - d.Close() - return err - } - - return d.Close() -} From d7307978806391b9b1f342a128f9167674dd2453 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 12 Aug 2022 13:10:14 +0800 Subject: [PATCH 07/45] itest: remove unused flag `goroutineDump` --- lntemp/node/config.go | 5 ----- scripts/itest_part.sh | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lntemp/node/config.go b/lntemp/node/config.go index e398cad48..4e632ec7e 100644 --- a/lntemp/node/config.go +++ b/lntemp/node/config.go @@ -45,11 +45,6 @@ var ( // logOutput is true. logSubDir = flag.String("logdir", ".", "default dir to write logs to") - // goroutineDump is a flag that can be set to dump the active - // goroutines of test nodes on failure. - goroutineDump = flag.Bool("goroutinedump", false, - "write goroutine dump from node n to file pprof-n.log") - // btcdExecutable is the full path to the btcd binary. btcdExecutable = flag.String( "btcdexec", "", "full path to btcd binary", diff --git a/scripts/itest_part.sh b/scripts/itest_part.sh index 37a8a4659..312e13a01 100755 --- a/scripts/itest_part.sh +++ b/scripts/itest_part.sh @@ -16,9 +16,9 @@ shift EXEC="$WORKDIR"/itest.test"$EXEC_SUFFIX" LND_EXEC="$WORKDIR"/lnd-itest"$EXEC_SUFFIX" BTCD_EXEC="$WORKDIR"/btcd-itest"$EXEC_SUFFIX" -echo $EXEC -test.v "$@" -logoutput -goroutinedump -logdir=.logs-tranche$TRANCHE -lndexec=$LND_EXEC -btcdexec=$BTCD_EXEC -splittranches=$NUM_TRANCHES -runtranche=$TRANCHE +echo $EXEC -test.v "$@" -logoutput -logdir=.logs-tranche$TRANCHE -lndexec=$LND_EXEC -btcdexec=$BTCD_EXEC -splittranches=$NUM_TRANCHES -runtranche=$TRANCHE # Exit code 255 causes the parallel jobs to abort, so if one part fails the # other is aborted too. cd "$WORKDIR" || exit 255 -$EXEC -test.v "$@" -logoutput -goroutinedump -logdir=.logs-tranche$TRANCHE -lndexec=$LND_EXEC -btcdexec=$BTCD_EXEC -splittranches=$NUM_TRANCHES -runtranche=$TRANCHE || exit 255 +$EXEC -test.v "$@" -logoutput -logdir=.logs-tranche$TRANCHE -lndexec=$LND_EXEC -btcdexec=$BTCD_EXEC -splittranches=$NUM_TRANCHES -runtranche=$TRANCHE || exit 255 From edba93899647afde968e09690bd557d19722e5d0 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 12 Aug 2022 15:16:35 +0800 Subject: [PATCH 08/45] multi: add new build tag `integration` This commit adds a new build tag `integration` and removes the old tag `rpctest` for clarity. Multiple unnecessary usages of `build !rpctest` is also removed. --- .golangci.yml | 1 + Makefile | 8 ++++---- ...ed_rpctest.go => cipherseed_integration.go} | 3 +-- contractcourt/breacharbiter_test.go | 3 --- contractcourt/nursery_store_test.go | 3 --- contractcourt/utxonursery_test.go | 3 --- ...config_rpctest.go => config_integration.go} | 2 +- funding/manager_test.go | 3 --- itest/list_off_test.go | 3 +-- itest/list_on_test.go | 3 +-- itest/lnd_max_channel_size_test.go | 3 --- itest/lnd_test.go | 2 +- lncfg/address_test.go | 3 --- lncfg/protocol.go | 3 +-- ...ocol_rpctest.go => protocol_integration.go} | 5 +++-- ...let_rpctest.go => btcwallet_integration.go} | 3 +-- lnwallet/revocation_producer.go | 3 +-- lnwallet/revocation_producer_itest.go | 3 +-- macaroons/security.go | 3 --- ...rity_rpctest.go => security_integration.go} | 7 +++---- make/testing_flags.mk | 2 +- server_test.go | 3 --- sweep/defaults.go | 3 --- sweep/defaults_rpctest.go | 18 ------------------ 24 files changed, 21 insertions(+), 72 deletions(-) rename aezeed/{cipherseed_rpctest.go => cipherseed_integration.go} (88%) rename funding/{config_rpctest.go => config_integration.go} (90%) rename lncfg/{protocol_rpctest.go => protocol_integration.go} (97%) rename lnwallet/btcwallet/{btcwallet_rpctest.go => btcwallet_integration.go} (90%) rename macaroons/{security_rpctest.go => security_integration.go} (89%) delete mode 100644 sweep/defaults_rpctest.go diff --git a/.golangci.yml b/.golangci.yml index 2c5092588..e6316815d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -27,6 +27,7 @@ run: - kvdb_etcd - kvdb_postgres - kvdb_sqlite + - integration linters-settings: govet: diff --git a/Makefile b/Makefile index 9e4b174dc..a45e86817 100644 --- a/Makefile +++ b/Makefile @@ -93,19 +93,19 @@ build: build-itest: @$(call print, "Building itest btcd and lnd.") - CGO_ENABLED=0 $(GOBUILD) -tags="rpctest" -o itest/btcd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(BTCD_PKG) + CGO_ENABLED=0 $(GOBUILD) -tags="integration" -o itest/btcd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(BTCD_PKG) CGO_ENABLED=0 $(GOBUILD) -tags="$(ITEST_TAGS)" -o itest/lnd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(PKG)/cmd/lnd @$(call print, "Building itest binary for ${backend} backend.") - CGO_ENABLED=0 $(GOTEST) -v ./itest -tags="$(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)" -c -o itest/itest.test$(EXEC_SUFFIX) + CGO_ENABLED=0 $(GOTEST) -v ./itest -tags="$(DEV_TAGS) $(RPC_TAGS) integration $(backend)" -c -o itest/itest.test$(EXEC_SUFFIX) build-itest-race: @$(call print, "Building itest btcd and lnd with race detector.") - CGO_ENABLED=0 $(GOBUILD) -tags="rpctest" -o itest/btcd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(BTCD_PKG) + CGO_ENABLED=0 $(GOBUILD) -tags="integration" -o itest/btcd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(BTCD_PKG) CGO_ENABLED=1 $(GOBUILD) -race -tags="$(ITEST_TAGS)" -o itest/lnd-itest$(EXEC_SUFFIX) $(DEV_LDFLAGS) $(PKG)/cmd/lnd @$(call print, "Building itest binary for ${backend} backend.") - CGO_ENABLED=0 $(GOTEST) -v ./itest -tags="$(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)" -c -o itest/itest.test$(EXEC_SUFFIX) + CGO_ENABLED=0 $(GOTEST) -v ./itest -tags="$(DEV_TAGS) $(RPC_TAGS) integration $(backend)" -c -o itest/itest.test$(EXEC_SUFFIX) install: @$(call print, "Installing lnd and lncli.") diff --git a/aezeed/cipherseed_rpctest.go b/aezeed/cipherseed_integration.go similarity index 88% rename from aezeed/cipherseed_rpctest.go rename to aezeed/cipherseed_integration.go index 1fb25e31f..50d29cb79 100644 --- a/aezeed/cipherseed_rpctest.go +++ b/aezeed/cipherseed_integration.go @@ -1,5 +1,4 @@ -//go:build rpctest -// +build rpctest +//go:build integration package aezeed diff --git a/contractcourt/breacharbiter_test.go b/contractcourt/breacharbiter_test.go index 3dbbca3f9..263ab45ea 100644 --- a/contractcourt/breacharbiter_test.go +++ b/contractcourt/breacharbiter_test.go @@ -1,6 +1,3 @@ -//go:build !rpctest -// +build !rpctest - package contractcourt import ( diff --git a/contractcourt/nursery_store_test.go b/contractcourt/nursery_store_test.go index f82758901..ca537693c 100644 --- a/contractcourt/nursery_store_test.go +++ b/contractcourt/nursery_store_test.go @@ -1,6 +1,3 @@ -//go:build !rpctest -// +build !rpctest - package contractcourt import ( diff --git a/contractcourt/utxonursery_test.go b/contractcourt/utxonursery_test.go index 99b139ea4..3f5026ddc 100644 --- a/contractcourt/utxonursery_test.go +++ b/contractcourt/utxonursery_test.go @@ -1,6 +1,3 @@ -//go:build !rpctest -// +build !rpctest - package contractcourt import ( diff --git a/funding/config_rpctest.go b/funding/config_integration.go similarity index 90% rename from funding/config_rpctest.go rename to funding/config_integration.go index 44a2c939c..06bb6e173 100644 --- a/funding/config_rpctest.go +++ b/funding/config_integration.go @@ -1,4 +1,4 @@ -//go:build rpctest +//go:build integration package funding diff --git a/funding/manager_test.go b/funding/manager_test.go index dedbb2efa..f386e3de5 100644 --- a/funding/manager_test.go +++ b/funding/manager_test.go @@ -1,6 +1,3 @@ -//go:build !rpctest -// +build !rpctest - package funding import ( diff --git a/itest/list_off_test.go b/itest/list_off_test.go index c2e2f67aa..bb54b2546 100644 --- a/itest/list_off_test.go +++ b/itest/list_off_test.go @@ -1,5 +1,4 @@ -//go:build !rpctest -// +build !rpctest +//go:build !integration package itest diff --git a/itest/list_on_test.go b/itest/list_on_test.go index 7f2ed6f0d..4572a94f1 100644 --- a/itest/list_on_test.go +++ b/itest/list_on_test.go @@ -1,5 +1,4 @@ -//go:build rpctest -// +build rpctest +//go:build integration package itest diff --git a/itest/lnd_max_channel_size_test.go b/itest/lnd_max_channel_size_test.go index d795fb2e8..320ccabe4 100644 --- a/itest/lnd_max_channel_size_test.go +++ b/itest/lnd_max_channel_size_test.go @@ -1,6 +1,3 @@ -//go:build rpctest -// +build rpctest - package itest import ( diff --git a/itest/lnd_test.go b/itest/lnd_test.go index 195890ac2..5aa39f059 100644 --- a/itest/lnd_test.go +++ b/itest/lnd_test.go @@ -57,7 +57,7 @@ var ( func TestLightningNetworkDaemon(t *testing.T) { // If no tests are registered, then we can exit early. if len(allTestCases) == 0 { - t.Skip("integration tests not selected with flag 'rpctest'") + t.Skip("integration tests not selected with flag 'integration'") } // Get the test cases to be run in this tranche. diff --git a/lncfg/address_test.go b/lncfg/address_test.go index a738523a8..2066aecc3 100644 --- a/lncfg/address_test.go +++ b/lncfg/address_test.go @@ -1,6 +1,3 @@ -//go:build !rpctest -// +build !rpctest - package lncfg import ( diff --git a/lncfg/protocol.go b/lncfg/protocol.go index 238e8c485..876b009c1 100644 --- a/lncfg/protocol.go +++ b/lncfg/protocol.go @@ -1,5 +1,4 @@ -//go:build !rpctest -// +build !rpctest +//go:build !integration package lncfg diff --git a/lncfg/protocol_rpctest.go b/lncfg/protocol_integration.go similarity index 97% rename from lncfg/protocol_rpctest.go rename to lncfg/protocol_integration.go index 7fca60f10..b2c64cb47 100644 --- a/lncfg/protocol_rpctest.go +++ b/lncfg/protocol_integration.go @@ -1,5 +1,4 @@ -//go:build rpctest -// +build rpctest +//go:build integration package lncfg @@ -7,6 +6,8 @@ package lncfg // compatibility of protocol additions, while defaulting to the latest within // lnd, or to enable experimental protocol changes. // +// TODO(yy): delete this build flag to unify with `lncfg/protocol.go`. +// //nolint:lll type ProtocolOptions struct { // LegacyProtocol is a sub-config that houses all the legacy protocol diff --git a/lnwallet/btcwallet/btcwallet_rpctest.go b/lnwallet/btcwallet/btcwallet_integration.go similarity index 90% rename from lnwallet/btcwallet/btcwallet_rpctest.go rename to lnwallet/btcwallet/btcwallet_integration.go index 938aef303..de53433f8 100644 --- a/lnwallet/btcwallet/btcwallet_rpctest.go +++ b/lnwallet/btcwallet/btcwallet_integration.go @@ -1,5 +1,4 @@ -//go:build rpctest || lowscrypt -// +build rpctest lowscrypt +//go:build integration || lowscrypt package btcwallet diff --git a/lnwallet/revocation_producer.go b/lnwallet/revocation_producer.go index fc8bde0fa..413e33d0a 100644 --- a/lnwallet/revocation_producer.go +++ b/lnwallet/revocation_producer.go @@ -1,5 +1,4 @@ -//go:build !rpctest -// +build !rpctest +//go:build !integration package lnwallet diff --git a/lnwallet/revocation_producer_itest.go b/lnwallet/revocation_producer_itest.go index 853a87760..d4b04152b 100644 --- a/lnwallet/revocation_producer_itest.go +++ b/lnwallet/revocation_producer_itest.go @@ -1,5 +1,4 @@ -//go:build rpctest -// +build rpctest +//go:build integration package lnwallet diff --git a/macaroons/security.go b/macaroons/security.go index cdc409b34..e4e3ffb9e 100644 --- a/macaroons/security.go +++ b/macaroons/security.go @@ -1,6 +1,3 @@ -//go:build !rpctest -// +build !rpctest - package macaroons import "github.com/btcsuite/btcwallet/snacl" diff --git a/macaroons/security_rpctest.go b/macaroons/security_integration.go similarity index 89% rename from macaroons/security_rpctest.go rename to macaroons/security_integration.go index 83792c383..f7d039fd0 100644 --- a/macaroons/security_rpctest.go +++ b/macaroons/security_integration.go @@ -1,15 +1,14 @@ -//go:build rpctest -// +build rpctest +//go:build integration package macaroons import "github.com/btcsuite/btcwallet/waddrmgr" -var ( +func init() { // Below are the reduced scrypt parameters that are used when creating // the encryption key for the macaroon database with snacl.NewSecretKey. // We use very low values for our itest/rpctest to speed things up. scryptN = waddrmgr.FastScryptOptions.N scryptR = waddrmgr.FastScryptOptions.R scryptP = waddrmgr.FastScryptOptions.P -) +} diff --git a/make/testing_flags.mk b/make/testing_flags.mk index d18a04881..d17ae58a6 100644 --- a/make/testing_flags.mk +++ b/make/testing_flags.mk @@ -115,4 +115,4 @@ backend = btcd endif # Construct the integration test command with the added build flags. -ITEST_TAGS := $(DEV_TAGS) $(RPC_TAGS) rpctest $(backend) +ITEST_TAGS := $(DEV_TAGS) $(RPC_TAGS) integration $(backend) diff --git a/server_test.go b/server_test.go index a60d0d6a1..5c4bebca4 100644 --- a/server_test.go +++ b/server_test.go @@ -1,6 +1,3 @@ -//go:build !rpctest -// +build !rpctest - package lnd import ( diff --git a/sweep/defaults.go b/sweep/defaults.go index def74a3a2..2f53cdb0a 100644 --- a/sweep/defaults.go +++ b/sweep/defaults.go @@ -1,6 +1,3 @@ -//go:build !rpctest -// +build !rpctest - package sweep import ( diff --git a/sweep/defaults_rpctest.go b/sweep/defaults_rpctest.go deleted file mode 100644 index 24789de09..000000000 --- a/sweep/defaults_rpctest.go +++ /dev/null @@ -1,18 +0,0 @@ -//go:build rpctest -// +build rpctest - -package sweep - -import ( - "time" -) - -var ( - // DefaultBatchWindowDuration specifies duration of the sweep batch - // window. The sweep is held back during the batch window to allow more - // inputs to be added and thereby lower the fee per input. - // - // To speed up integration tests waiting for a sweep to happen, the - // batch window is shortened. - DefaultBatchWindowDuration = 8 * time.Second -) From 4a9c3449a6867bee532bc12252cf21002b6b2526 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 12 Aug 2022 15:41:00 +0800 Subject: [PATCH 09/45] lntemp+itest: move utils function into `lntemp` --- itest/lnd_channel_backup_test.go | 8 +++---- itest/lnd_channel_force_close_test.go | 4 ++-- itest/lnd_funding_test.go | 4 ++-- itest/lnd_multi-hop_test.go | 20 ++++++++-------- itest/lnd_onchain_test.go | 4 ++-- itest/lnd_psbt_test.go | 2 +- itest/utils.go | 33 +-------------------------- lntemp/utils.go | 31 +++++++++++++++++++++++++ 8 files changed, 53 insertions(+), 53 deletions(-) diff --git a/itest/lnd_channel_backup_test.go b/itest/lnd_channel_backup_test.go index d254bb9f2..58ebc949e 100644 --- a/itest/lnd_channel_backup_test.go +++ b/itest/lnd_channel_backup_test.go @@ -70,7 +70,7 @@ func newChanRestoreScenario(ht *lntemp.HarnessTest, ct lnrpc.CommitmentType, } if ct != lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE { - args := nodeArgsForCommitType(ct) + args := lntemp.NodeArgsForCommitType(ct) nodeArgs = append(nodeArgs, args...) } @@ -99,7 +99,7 @@ func newChanRestoreScenario(ht *lntemp.HarnessTest, ct lnrpc.CommitmentType, // For the anchor output case we need two UTXOs for Carol so she can // sweep both the local and remote anchor. - if commitTypeHasAnchors(ct) { + if lntemp.CommitTypeHasAnchors(ct) { ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) } @@ -212,7 +212,7 @@ func (c *chanRestoreScenario) testScenario(ht *lntemp.HarnessTest, // let's start up Carol again. require.NoError(ht, restartCarol(), "restart carol failed") - if commitTypeHasAnchors(c.params.CommitmentType) { + if lntemp.CommitTypeHasAnchors(c.params.CommitmentType) { ht.AssertNumUTXOs(carol, 2) } else { ht.AssertNumUTXOs(carol, 1) @@ -1467,7 +1467,7 @@ func assertDLPExecuted(ht *lntemp.HarnessTest, // Upon reconnection, the nodes should detect that Dave is out of sync. // Carol should force close the channel using her latest commitment. expectedTxes := 1 - if commitTypeHasAnchors(commitType) { + if lntemp.CommitTypeHasAnchors(commitType) { expectedTxes = 2 } ht.Miner.AssertNumTxsInMempool(expectedTxes) diff --git a/itest/lnd_channel_force_close_test.go b/itest/lnd_channel_force_close_test.go index 03b1955ab..8db63cb1a 100644 --- a/itest/lnd_channel_force_close_test.go +++ b/itest/lnd_channel_force_close_test.go @@ -72,7 +72,7 @@ func testCommitmentTransactionDeadline(ht *lntemp.HarnessTest) { setupNode := func(name string) *node.HarnessNode { // Create the node. args := []string{"--hodl.exit-settle"} - args = append(args, nodeArgsForCommitType( + args = append(args, lntemp.NodeArgsForCommitType( lnrpc.CommitmentType_ANCHORS)..., ) node := ht.NewNode(name, args) @@ -209,7 +209,7 @@ func testChannelForceClosure(ht *lntemp.HarnessTest) { success := ht.Run(testName, func(t *testing.T) { st := ht.Subtest(t) - args := nodeArgsForCommitType(channelType) + args := lntemp.NodeArgsForCommitType(channelType) alice := st.NewNode("Alice", args) defer st.Shutdown(alice) diff --git a/itest/lnd_funding_test.go b/itest/lnd_funding_test.go index d9e66d792..b4d3271e7 100644 --- a/itest/lnd_funding_test.go +++ b/itest/lnd_funding_test.go @@ -41,14 +41,14 @@ func testBasicChannelFunding(ht *lntemp.HarnessTest) { // Based on the current tweak variable for Carol, we'll // preferentially signal the legacy commitment format. We do // the same for Dave shortly below. - carolArgs := nodeArgsForCommitType(carolCommitType) + carolArgs := lntemp.NodeArgsForCommitType(carolCommitType) carol := ht.NewNode("Carol", carolArgs) // Each time, we'll send Carol a new set of coins in order to // fund the channel. ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) - daveArgs := nodeArgsForCommitType(daveCommitType) + daveArgs := lntemp.NodeArgsForCommitType(daveCommitType) dave := ht.NewNode("Dave", daveArgs) // Before we start the test, we'll ensure both sides are diff --git a/itest/lnd_multi-hop_test.go b/itest/lnd_multi-hop_test.go index 287444ac9..c156cf482 100644 --- a/itest/lnd_multi-hop_test.go +++ b/itest/lnd_multi-hop_test.go @@ -65,7 +65,7 @@ func runMultiHopHtlcClaimTest(ht *lntemp.HarnessTest, tester caseRunner) { // Create the nodes here so that separate logs will be created // for Alice and Bob. - args := nodeArgsForCommitType(typeAndConf.commitType) + args := lntemp.NodeArgsForCommitType(typeAndConf.commitType) if typeAndConf.zeroConf { args = append( args, "--protocol.option-scid-alias", @@ -171,7 +171,7 @@ func runMultiHopHtlcLocalTimeout(ht *lntemp.HarnessTest, // Bob's force close transaction should now be found in the mempool. If // there are anchors, we also expect Bob's anchor sweep. expectedTxes := 1 - hasAnchors := commitTypeHasAnchors(c) + hasAnchors := lntemp.CommitTypeHasAnchors(c) if hasAnchors { expectedTxes = 2 } @@ -348,7 +348,7 @@ func runMultiHopReceiverChainClaim(ht *lntemp.HarnessTest, // transaction in order to go to the chain and sweep her HTLC. If there // are anchors, Carol also sweeps hers. expectedTxes := 1 - hasAnchors := commitTypeHasAnchors(c) + hasAnchors := lntemp.CommitTypeHasAnchors(c) if hasAnchors { expectedTxes = 2 } @@ -517,7 +517,7 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest, // Now that all parties have the HTLC locked in, we'll immediately // force close the Bob -> Carol channel. This should trigger contract // resolution mode for both of them. - hasAnchors := commitTypeHasAnchors(c) + hasAnchors := lntemp.CommitTypeHasAnchors(c) stream, _ := ht.CloseChannelAssertPending(bob, bobChanPoint, true) closeTx := ht.AssertStreamChannelForceClosed( bob, bobChanPoint, hasAnchors, stream, @@ -682,7 +682,7 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest, // transaction. This will let us exercise that Bob is able to sweep the // expired HTLC on Carol's version of the commitment transaction. If // Carol has an anchor, it will be swept too. - hasAnchors := commitTypeHasAnchors(c) + hasAnchors := lntemp.CommitTypeHasAnchors(c) closeStream, _ := ht.CloseChannelAssertPending( carol, bobChanPoint, true, ) @@ -840,7 +840,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntemp.HarnessTest, // At this point, Bob decides that he wants to exit the channel // immediately, so he force closes his commitment transaction. - hasAnchors := commitTypeHasAnchors(c) + hasAnchors := lntemp.CommitTypeHasAnchors(c) closeStream, _ := ht.CloseChannelAssertPending( bob, aliceChanPoint, true, ) @@ -888,7 +888,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntemp.HarnessTest, // Carol's commitment transaction should now be in the mempool. If // there is an anchor, Carol will sweep that too. - if commitTypeHasAnchors(c) { + if lntemp.CommitTypeHasAnchors(c) { expectedTxes = 2 } ht.Miner.AssertNumTxsInMempool(expectedTxes) @@ -1135,7 +1135,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntemp.HarnessTest, // Next, Alice decides that she wants to exit the channel, so she'll // immediately force close the channel by broadcast her commitment // transaction. - hasAnchors := commitTypeHasAnchors(c) + hasAnchors := lntemp.CommitTypeHasAnchors(c) closeStream, _ := ht.CloseChannelAssertPending( alice, aliceChanPoint, true, ) @@ -1489,7 +1489,7 @@ func runMultiHopHtlcAggregation(ht *lntemp.HarnessTest, // Bob's force close transaction should now be found in the mempool. If // there are anchors, we also expect Bob's anchor sweep. - hasAnchors := commitTypeHasAnchors(c) + hasAnchors := lntemp.CommitTypeHasAnchors(c) expectedTxes := 1 if hasAnchors { expectedTxes = 2 @@ -1738,7 +1738,7 @@ func createThreeHopNetwork(ht *lntemp.HarnessTest, // We'll create a new node "carol" and have Bob connect to her. // If the carolHodl flag is set, we'll make carol always hold onto the // HTLC, this way it'll force Bob to go to chain to resolve the HTLC. - carolFlags := nodeArgsForCommitType(c) + carolFlags := lntemp.NodeArgsForCommitType(c) if carolHodl { carolFlags = append(carolFlags, "--hodl.exit-settle") } diff --git a/itest/lnd_onchain_test.go b/itest/lnd_onchain_test.go index 2b6b3200e..2d56d2429 100644 --- a/itest/lnd_onchain_test.go +++ b/itest/lnd_onchain_test.go @@ -182,7 +182,7 @@ func runCPFP(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode) { // wallet. func testAnchorReservedValue(ht *lntemp.HarnessTest) { // Start two nodes supporting anchor channels. - args := nodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) + args := lntemp.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) // NOTE: we cannot reuse the standby node here as the test requires the // node to start with no UTXOs. @@ -353,7 +353,7 @@ func testAnchorThirdPartySpend(ht *lntemp.HarnessTest) { // // NOTE: The itests differ here as anchors is default off vs the normal // lnd binary. - args := nodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) + args := lntemp.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) alice := ht.NewNode("Alice", args) defer ht.Shutdown(alice) diff --git a/itest/lnd_psbt_test.go b/itest/lnd_psbt_test.go index 5cc0865bc..0395a3ac7 100644 --- a/itest/lnd_psbt_test.go +++ b/itest/lnd_psbt_test.go @@ -415,7 +415,7 @@ func testPsbtChanFundingExternal(ht *lntemp.HarnessTest) { func testPsbtChanFundingSingleStep(ht *lntemp.HarnessTest) { const chanSize = funding.MaxBtcFundingAmount - args := nodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) + args := lntemp.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) // First, we'll create two new nodes that we'll use to open channels // between for this test. But in this case both nodes have an empty diff --git a/itest/utils.go b/itest/utils.go index 828ee04e3..9ab8706f4 100644 --- a/itest/utils.go +++ b/itest/utils.go @@ -38,37 +38,6 @@ var ( ) ) -// commitTypeHasAnchors returns whether commitType uses anchor outputs. -func commitTypeHasAnchors(commitType lnrpc.CommitmentType) bool { - switch commitType { - case lnrpc.CommitmentType_ANCHORS, - lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE: - return true - default: - return false - } -} - -// nodeArgsForCommitType returns the command line flag to supply to enable this -// commitment type. -func nodeArgsForCommitType(commitType lnrpc.CommitmentType) []string { - switch commitType { - case lnrpc.CommitmentType_LEGACY: - return []string{"--protocol.legacy.committweak"} - case lnrpc.CommitmentType_STATIC_REMOTE_KEY: - return []string{} - case lnrpc.CommitmentType_ANCHORS: - return []string{"--protocol.anchors"} - case lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE: - return []string{ - "--protocol.anchors", - "--protocol.script-enforced-lease", - } - } - - 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. @@ -87,7 +56,7 @@ func calcStaticFee(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { // 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) { + if lntemp.CommitTypeHasAnchors(c) { feePerKw = chainfee.SatPerKVByte( defaultSatPerVByte * 1000).FeePerKWeight() commitWeight = input.AnchorCommitWeight diff --git a/lntemp/utils.go b/lntemp/utils.go index b1a5f00d4..ecf460fc6 100644 --- a/lntemp/utils.go +++ b/lntemp/utils.go @@ -121,3 +121,34 @@ func channelPointStr(chanPoint *lnrpc.ChannelPoint) string { return cp.String() } + +// CommitTypeHasAnchors returns whether commitType uses anchor outputs. +func CommitTypeHasAnchors(commitType lnrpc.CommitmentType) bool { + switch commitType { + case lnrpc.CommitmentType_ANCHORS, + lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE: + return true + default: + return false + } +} + +// NodeArgsForCommitType returns the command line flag to supply to enable this +// commitment type. +func NodeArgsForCommitType(commitType lnrpc.CommitmentType) []string { + switch commitType { + case lnrpc.CommitmentType_LEGACY: + return []string{"--protocol.legacy.committweak"} + case lnrpc.CommitmentType_STATIC_REMOTE_KEY: + return []string{} + case lnrpc.CommitmentType_ANCHORS: + return []string{"--protocol.anchors"} + case lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE: + return []string{ + "--protocol.anchors", + "--protocol.script-enforced-lease", + } + } + + return nil +} From ee0790493ce93c67059845c97d2faea1d22fbba4 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 12 Aug 2022 16:02:32 +0800 Subject: [PATCH 10/45] itest+lntemp: move calculation functions into `lntemp` Functions that can be useful to other tests are now moved into the package `lntemp`. --- itest/lnd_channel_balance_test.go | 15 ++-- itest/lnd_channel_graph_test.go | 2 +- itest/lnd_channel_policy_test.go | 4 +- itest/lnd_funding_test.go | 6 +- itest/lnd_multi-hop-error-propagation_test.go | 2 +- itest/lnd_multi-hop-payments_test.go | 2 +- itest/lnd_open_channel_test.go | 2 +- itest/lnd_routing_test.go | 2 +- itest/lnd_test.go | 25 ++++++ itest/lnd_zero_conf_test.go | 8 +- itest/utils.go | 77 ------------------- lntemp/utils.go | 46 +++++++++++ 12 files changed, 95 insertions(+), 96 deletions(-) delete mode 100644 itest/utils.go 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) +} From 9d1d6290010406d7a34fa2d0169e9a500e798a6a Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 12 Aug 2022 17:03:44 +0800 Subject: [PATCH 11/45] itest+lntest: migrate `lntemp` to `lntest` This commit performs the takeover that `lntemp` is now promoted to be `lntest`, and the scaffolding is now removed as all the refactoring is finished! --- itest/list_off_test.go | 4 +- itest/list_on_test.go | 4 +- itest/lnd_amp_test.go | 16 ++-- itest/lnd_channel_backup_test.go | 74 +++++++++---------- itest/lnd_channel_balance_test.go | 22 +++--- itest/lnd_channel_force_close_test.go | 28 +++---- itest/lnd_channel_graph_test.go | 34 ++++----- itest/lnd_channel_policy_test.go | 34 ++++----- itest/lnd_custom_message.go | 8 +- itest/lnd_etcd_failover_test.go | 12 +-- itest/lnd_forward_interceptor_test.go | 20 ++--- itest/lnd_funding_test.go | 53 +++++++------ itest/lnd_hold_invoice_force_test.go | 6 +- itest/lnd_hold_persistence_test.go | 10 +-- itest/lnd_macaroons_test.go | 12 +-- itest/lnd_max_channel_size_test.go | 8 +- itest/lnd_max_htlcs_test.go | 12 +-- itest/lnd_misc_test.go | 58 +++++++-------- itest/lnd_mpp_test.go | 24 +++--- itest/lnd_multi-hop-error-propagation_test.go | 44 +++++------ itest/lnd_multi-hop-payments_test.go | 16 ++-- itest/lnd_multi-hop_test.go | 64 ++++++++-------- itest/lnd_network_test.go | 12 +-- itest/lnd_neutrino_test.go | 4 +- itest/lnd_no_etcd_dummy_failover_test.go | 4 +- itest/lnd_nonstd_sweep_test.go | 6 +- itest/lnd_onchain_test.go | 38 +++++----- itest/lnd_open_channel_test.go | 32 ++++---- itest/lnd_payment_test.go | 32 ++++---- itest/lnd_psbt_test.go | 48 ++++++------ itest/lnd_recovery_test.go | 10 +-- itest/lnd_remote_signer_test.go | 32 ++++---- itest/lnd_res_handoff_test.go | 6 +- itest/lnd_rest_api_test.go | 18 ++--- itest/lnd_revocation_test.go | 24 +++--- itest/lnd_routing_test.go | 74 +++++++++---------- itest/lnd_rpc_middleware_interceptor_test.go | 10 +-- itest/lnd_send_multi_path_payment_test.go | 4 +- itest/lnd_signer_test.go | 18 ++--- itest/lnd_single_hop_invoice_test.go | 6 +- itest/lnd_switch_test.go | 24 +++--- itest/lnd_taproot_test.go | 54 +++++++------- itest/lnd_test.go | 10 +-- itest/lnd_trackpayments_test.go | 6 +- itest/lnd_wallet_import_test.go | 30 ++++---- itest/lnd_wipe_fwdpkgs_test.go | 8 +- itest/lnd_wumbo_channels_test.go | 8 +- itest/lnd_zero_conf_test.go | 48 ++++++------ {lntemp => lntest}/README.md | 0 lntest/bitcoind_common.go | 2 +- lntest/btcd.go | 2 +- {lntemp => lntest}/fee_service.go | 4 +- {lntemp => lntest}/harness.go | 6 +- {lntemp => lntest}/harness_assertion.go | 6 +- {lntemp => lntest}/harness_miner.go | 4 +- {lntemp => lntest}/harness_node_manager.go | 4 +- {lntemp => lntest}/harness_setup.go | 7 +- lntest/neutrino.go | 2 +- {lntemp => lntest}/node/config.go | 0 {lntemp => lntest}/node/harness_node.go | 2 +- {lntemp => lntest}/node/state.go | 2 +- {lntemp => lntest}/node/watcher.go | 2 +- {lntemp => lntest}/rpc/chain_kit.go | 0 {lntemp => lntest}/rpc/chain_notifier.go | 0 {lntemp => lntest}/rpc/harness_rpc.go | 0 {lntemp => lntest}/rpc/invoices.go | 0 {lntemp => lntest}/rpc/lnd.go | 0 {lntemp => lntest}/rpc/neutrino_kit.go | 0 {lntemp => lntest}/rpc/peers.go | 0 {lntemp => lntest}/rpc/router.go | 0 {lntemp => lntest}/rpc/signer.go | 0 {lntemp => lntest}/rpc/state.go | 0 {lntemp => lntest}/rpc/wallet_kit.go | 0 {lntemp => lntest}/rpc/wallet_unlocker.go | 0 {lntemp => lntest}/rpc/watchtower.go | 0 {lntemp => lntest}/utils.go | 2 +- 76 files changed, 590 insertions(+), 584 deletions(-) rename {lntemp => lntest}/README.md (100%) rename {lntemp => lntest}/fee_service.go (98%) rename {lntemp => lntest}/harness.go (99%) rename {lntemp => lntest}/harness_assertion.go (99%) rename {lntemp => lntest}/harness_miner.go (99%) rename {lntemp => lntest}/harness_node_manager.go (99%) rename {lntemp => lntest}/harness_setup.go (95%) rename {lntemp => lntest}/node/config.go (100%) rename {lntemp => lntest}/node/harness_node.go (99%) rename {lntemp => lntest}/node/state.go (99%) rename {lntemp => lntest}/node/watcher.go (99%) rename {lntemp => lntest}/rpc/chain_kit.go (100%) rename {lntemp => lntest}/rpc/chain_notifier.go (100%) rename {lntemp => lntest}/rpc/harness_rpc.go (100%) rename {lntemp => lntest}/rpc/invoices.go (100%) rename {lntemp => lntest}/rpc/lnd.go (100%) rename {lntemp => lntest}/rpc/neutrino_kit.go (100%) rename {lntemp => lntest}/rpc/peers.go (100%) rename {lntemp => lntest}/rpc/router.go (100%) rename {lntemp => lntest}/rpc/signer.go (100%) rename {lntemp => lntest}/rpc/state.go (100%) rename {lntemp => lntest}/rpc/wallet_kit.go (100%) rename {lntemp => lntest}/rpc/wallet_unlocker.go (100%) rename {lntemp => lntest}/rpc/watchtower.go (100%) rename {lntemp => lntest}/utils.go (99%) diff --git a/itest/list_off_test.go b/itest/list_off_test.go index bb54b2546..a510747e8 100644 --- a/itest/list_off_test.go +++ b/itest/list_off_test.go @@ -2,6 +2,6 @@ package itest -import "github.com/lightningnetwork/lnd/lntemp" +import "github.com/lightningnetwork/lnd/lntest" -var allTestCases = []*lntemp.TestCase{} +var allTestCases = []*lntest.TestCase{} diff --git a/itest/list_on_test.go b/itest/list_on_test.go index 4572a94f1..4a9b2baec 100644 --- a/itest/list_on_test.go +++ b/itest/list_on_test.go @@ -2,9 +2,9 @@ package itest -import "github.com/lightningnetwork/lnd/lntemp" +import "github.com/lightningnetwork/lnd/lntest" -var allTestCases = []*lntemp.TestCase{ +var allTestCases = []*lntest.TestCase{ { Name: "update channel status", TestFunc: testUpdateChanStatus, diff --git a/itest/lnd_amp_test.go b/itest/lnd_amp_test.go index 46dddbd08..a76aedd99 100644 --- a/itest/lnd_amp_test.go +++ b/itest/lnd_amp_test.go @@ -11,15 +11,15 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntypes" "github.com/stretchr/testify/require" ) // testSendPaymentAMPInvoice tests that we can send an AMP payment to a // specified AMP invoice using SendPaymentV2. -func testSendPaymentAMPInvoice(ht *lntemp.HarnessTest) { +func testSendPaymentAMPInvoice(ht *lntest.HarnessTest) { succeed := ht.Run("native payaddr", func(t *testing.T) { tt := ht.Subtest(t) testSendPaymentAMPInvoiceCase(tt, false) @@ -36,7 +36,7 @@ func testSendPaymentAMPInvoice(ht *lntemp.HarnessTest) { }) } -func testSendPaymentAMPInvoiceCase(ht *lntemp.HarnessTest, +func testSendPaymentAMPInvoiceCase(ht *lntest.HarnessTest, useExternalPayAddr bool) { mts := newMppTestScenario(ht) @@ -196,7 +196,7 @@ func testSendPaymentAMPInvoiceCase(ht *lntemp.HarnessTest, // testSendPaymentAMPInvoiceRepeat tests that it's possible to pay an AMP // invoice multiple times by having the client generate a new setID each time. -func testSendPaymentAMPInvoiceRepeat(ht *lntemp.HarnessTest) { +func testSendPaymentAMPInvoiceRepeat(ht *lntest.HarnessTest) { // In this basic test, we'll only need two nodes as we want to // primarily test the recurring payment feature. So we'll re-use the carol := ht.NewNode("Carol", nil) @@ -218,7 +218,7 @@ func testSendPaymentAMPInvoiceRepeat(ht *lntemp.HarnessTest) { // Establish a channel between Carol and Dave. chanAmt := btcutil.Amount(100_000) ht.OpenChannel( - carol, dave, lntemp.OpenChannelParams{Amt: chanAmt}, + carol, dave, lntest.OpenChannelParams{Amt: chanAmt}, ) // Create an AMP invoice of a trivial amount, that we'll pay repeatedly @@ -353,7 +353,7 @@ func testSendPaymentAMPInvoiceRepeat(ht *lntemp.HarnessTest) { // testSendPaymentAMP tests that we can send an AMP payment to a specified // destination using SendPaymentV2. -func testSendPaymentAMP(ht *lntemp.HarnessTest) { +func testSendPaymentAMP(ht *lntest.HarnessTest) { mts := newMppTestScenario(ht) const paymentAmt = btcutil.Amount(300000) @@ -460,7 +460,7 @@ func testSendPaymentAMP(ht *lntemp.HarnessTest) { mts.closeChannels() } -func testSendToRouteAMP(ht *lntemp.HarnessTest) { +func testSendToRouteAMP(ht *lntest.HarnessTest) { mts := newMppTestScenario(ht) const ( paymentAmt = btcutil.Amount(300000) diff --git a/itest/lnd_channel_backup_test.go b/itest/lnd_channel_backup_test.go index 58ebc949e..acd4b9c5b 100644 --- a/itest/lnd_channel_backup_test.go +++ b/itest/lnd_channel_backup_test.go @@ -18,8 +18,8 @@ import ( "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) @@ -34,7 +34,7 @@ type ( // that'll return the same node, but with its state restored via a // custom method. We use this to abstract away _how_ a node is restored // from our assertions once the node has been fully restored itself. - restoreMethodType func(ht *lntemp.HarnessTest, + restoreMethodType func(ht *lntest.HarnessTest, oldNode *node.HarnessNode, backupFilePath string, password []byte, mnemonic []string) nodeRestorer ) @@ -50,12 +50,12 @@ type chanRestoreScenario struct { dave *node.HarnessNode password []byte mnemonic []string - params lntemp.OpenChannelParams + params lntest.OpenChannelParams } // newChanRestoreScenario creates a new scenario that has two nodes, Carol and // Dave, connected and funded. -func newChanRestoreScenario(ht *lntemp.HarnessTest, ct lnrpc.CommitmentType, +func newChanRestoreScenario(ht *lntest.HarnessTest, ct lnrpc.CommitmentType, zeroConf bool) *chanRestoreScenario { const ( @@ -70,7 +70,7 @@ func newChanRestoreScenario(ht *lntemp.HarnessTest, ct lnrpc.CommitmentType, } if ct != lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE { - args := lntemp.NodeArgsForCommitType(ct) + args := lntest.NodeArgsForCommitType(ct) nodeArgs = append(nodeArgs, args...) } @@ -99,7 +99,7 @@ func newChanRestoreScenario(ht *lntemp.HarnessTest, ct lnrpc.CommitmentType, // For the anchor output case we need two UTXOs for Carol so she can // sweep both the local and remote anchor. - if lntemp.CommitTypeHasAnchors(ct) { + if lntest.CommitTypeHasAnchors(ct) { ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) } @@ -112,7 +112,7 @@ func newChanRestoreScenario(ht *lntemp.HarnessTest, ct lnrpc.CommitmentType, dave: dave, mnemonic: mnemonic, password: password, - params: lntemp.OpenChannelParams{ + params: lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, ZeroConf: zeroConf, @@ -123,7 +123,7 @@ func newChanRestoreScenario(ht *lntemp.HarnessTest, ct lnrpc.CommitmentType, // restoreDave will call the `nodeRestorer` and asserts Dave is restored by // checking his wallet balance against zero. -func (c *chanRestoreScenario) restoreDave(ht *lntemp.HarnessTest, +func (c *chanRestoreScenario) restoreDave(ht *lntest.HarnessTest, restoredNodeFunc nodeRestorer) *node.HarnessNode { // Next, we'll make a new Dave and start the bulk of our recovery @@ -154,7 +154,7 @@ func (c *chanRestoreScenario) restoreDave(ht *lntemp.HarnessTest, // 4. validate pending channel state and check we cannot force close it. // 5. validate Carol's UTXOs. // 6. assert DLP is executed. -func (c *chanRestoreScenario) testScenario(ht *lntemp.HarnessTest, +func (c *chanRestoreScenario) testScenario(ht *lntest.HarnessTest, restoredNodeFunc nodeRestorer) { carol, dave := c.carol, c.dave @@ -212,7 +212,7 @@ func (c *chanRestoreScenario) testScenario(ht *lntemp.HarnessTest, // let's start up Carol again. require.NoError(ht, restartCarol(), "restart carol failed") - if lntemp.CommitTypeHasAnchors(c.params.CommitmentType) { + if lntest.CommitTypeHasAnchors(c.params.CommitmentType) { ht.AssertNumUTXOs(carol, 2) } else { ht.AssertNumUTXOs(carol, 1) @@ -232,7 +232,7 @@ func (c *chanRestoreScenario) testScenario(ht *lntemp.HarnessTest, // restoring from initial wallet creation. We'll also alternate between // restoring form the on disk file, and restoring from the exported RPC command // as well. -func testChannelBackupRestoreBasic(ht *lntemp.HarnessTest) { +func testChannelBackupRestoreBasic(ht *lntest.HarnessTest) { var testCases = []struct { name string restoreMethod restoreMethodType @@ -241,7 +241,7 @@ func testChannelBackupRestoreBasic(ht *lntemp.HarnessTest) { // was the initiator, of the non-advertised channel. { name: "restore from RPC backup", - restoreMethod: func(st *lntemp.HarnessTest, + restoreMethod: func(st *lntest.HarnessTest, oldNode *node.HarnessNode, backupFilePath string, password []byte, @@ -269,7 +269,7 @@ func testChannelBackupRestoreBasic(ht *lntemp.HarnessTest) { // interface. { name: "restore from backup file", - restoreMethod: func(st *lntemp.HarnessTest, + restoreMethod: func(st *lntest.HarnessTest, oldNode *node.HarnessNode, backupFilePath string, password []byte, @@ -293,7 +293,7 @@ func testChannelBackupRestoreBasic(ht *lntemp.HarnessTest) { // prior mnemonic and new backup seed. { name: "restore during creation", - restoreMethod: func(st *lntemp.HarnessTest, + restoreMethod: func(st *lntest.HarnessTest, oldNode *node.HarnessNode, backupFilePath string, password []byte, @@ -325,7 +325,7 @@ func testChannelBackupRestoreBasic(ht *lntemp.HarnessTest) { // re-created, using the Unlock call. { name: "restore during unlock", - restoreMethod: func(st *lntemp.HarnessTest, + restoreMethod: func(st *lntest.HarnessTest, oldNode *node.HarnessNode, backupFilePath string, password []byte, @@ -362,7 +362,7 @@ func testChannelBackupRestoreBasic(ht *lntemp.HarnessTest) { // make sure imports can be canceled and later resumed. { name: "restore from backup file twice", - restoreMethod: func(st *lntemp.HarnessTest, + restoreMethod: func(st *lntest.HarnessTest, oldNode *node.HarnessNode, backupFilePath string, password []byte, @@ -420,7 +420,7 @@ func testChannelBackupRestoreBasic(ht *lntemp.HarnessTest) { // ensuring that after Dave restores his channel state according to the // testCase, the DLP protocol is executed properly and both nodes are made // whole. -func runChanRestoreScenarioBasic(ht *lntemp.HarnessTest, +func runChanRestoreScenarioBasic(ht *lntest.HarnessTest, restoreMethod restoreMethodType) { // Create a new retore scenario. @@ -445,7 +445,7 @@ func runChanRestoreScenarioBasic(ht *lntemp.HarnessTest, // testChannelBackupRestoreUnconfirmed tests that we're able to restore from // disk file and the exported RPC command for unconfirmed channel. -func testChannelBackupRestoreUnconfirmed(ht *lntemp.HarnessTest) { +func testChannelBackupRestoreUnconfirmed(ht *lntest.HarnessTest) { // Use the channel backup file that contains an unconfirmed channel and // make sure recovery works as well. ht.Run("restore unconfirmed channel file", func(t *testing.T) { @@ -463,7 +463,7 @@ func testChannelBackupRestoreUnconfirmed(ht *lntemp.HarnessTest) { // runChanRestoreScenarioUnConfirmed checks that Dave is able to restore for an // unconfirmed channel. -func runChanRestoreScenarioUnConfirmed(ht *lntemp.HarnessTest, useFile bool) { +func runChanRestoreScenarioUnConfirmed(ht *lntest.HarnessTest, useFile bool) { // Create a new retore scenario. crs := newChanRestoreScenario( ht, lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE, false, @@ -527,7 +527,7 @@ func runChanRestoreScenarioUnConfirmed(ht *lntemp.HarnessTest, useFile bool) { // testChannelBackupRestoreCommitTypes tests that we're able to recover from, // and initiate the DLP protocol for different channel commitment types and // zero-conf channel. -func testChannelBackupRestoreCommitTypes(ht *lntemp.HarnessTest) { +func testChannelBackupRestoreCommitTypes(ht *lntest.HarnessTest) { var testCases = []struct { name string ct lnrpc.CommitmentType @@ -584,7 +584,7 @@ func testChannelBackupRestoreCommitTypes(ht *lntemp.HarnessTest) { // runChanRestoreScenarioCommitTypes tests that the DLP is applied for // different channel commitment types and zero-conf channel. -func runChanRestoreScenarioCommitTypes(ht *lntemp.HarnessTest, +func runChanRestoreScenarioCommitTypes(ht *lntest.HarnessTest, ct lnrpc.CommitmentType, zeroConf bool) { // Create a new retore scenario. @@ -639,7 +639,7 @@ func runChanRestoreScenarioCommitTypes(ht *lntemp.HarnessTest, // testChannelBackupRestoreLegacy checks a channel with the legacy revocation // producer format and makes sure old SCBs can still be recovered. -func testChannelBackupRestoreLegacy(ht *lntemp.HarnessTest) { +func testChannelBackupRestoreLegacy(ht *lntest.HarnessTest) { // Create a new retore scenario. crs := newChanRestoreScenario( ht, lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE, false, @@ -668,7 +668,7 @@ func testChannelBackupRestoreLegacy(ht *lntemp.HarnessTest) { // testChannelBackupRestoreForceClose checks that Dave can restore from force // closed channels. -func testChannelBackupRestoreForceClose(ht *lntemp.HarnessTest) { +func testChannelBackupRestoreForceClose(ht *lntest.HarnessTest) { // Restore a channel that was force closed by dave just before going // offline. success := ht.Run("from backup file anchors", func(t *testing.T) { @@ -691,7 +691,7 @@ func testChannelBackupRestoreForceClose(ht *lntemp.HarnessTest) { // runChanRestoreScenarioForceClose creates anchor-enabled force close channels // and checks that Dave is able to restore from them. -func runChanRestoreScenarioForceClose(ht *lntemp.HarnessTest, zeroConf bool) { +func runChanRestoreScenarioForceClose(ht *lntest.HarnessTest, zeroConf bool) { crs := newChanRestoreScenario( ht, lnrpc.CommitmentType_ANCHORS, zeroConf, ) @@ -792,7 +792,7 @@ func runChanRestoreScenarioForceClose(ht *lntemp.HarnessTest, zeroConf bool) { // testChannelBackupUpdates tests that both the streaming channel update RPC, // and the on-disk channel.backup are updated each time a channel is // opened/closed. -func testChannelBackupUpdates(ht *lntemp.HarnessTest) { +func testChannelBackupUpdates(ht *lntest.HarnessTest) { alice := ht.Alice // First, we'll make a temp directory that we'll use to store our @@ -850,7 +850,7 @@ func testChannelBackupUpdates(ht *lntemp.HarnessTest) { chanAmt := btcutil.Amount(1000000) for i := 0; i < numChans; i++ { chanPoint := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) chanPoints = append(chanPoints, chanPoint) } @@ -962,7 +962,7 @@ func testChannelBackupUpdates(ht *lntemp.HarnessTest) { // testExportChannelBackup tests that we're able to properly export either a // targeted channel's backup, or export backups of all the currents open // channels. -func testExportChannelBackup(ht *lntemp.HarnessTest) { +func testExportChannelBackup(ht *lntest.HarnessTest) { // First, we'll create our primary test node: Carol. We'll use Carol to // open channels and also export backups that we'll examine throughout // the test. @@ -979,7 +979,7 @@ func testExportChannelBackup(ht *lntemp.HarnessTest) { chanAmt := btcutil.Amount(1000000) for i := 0; i < numChans; i++ { chanPoint := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) chanPoints = append(chanPoints, chanPoint) } @@ -1086,7 +1086,7 @@ func testExportChannelBackup(ht *lntemp.HarnessTest) { // relationship lost state, they will detect this during channel sync, and the // up-to-date party will force close the channel, giving the outdated party the // opportunity to sweep its output. -func testDataLossProtection(ht *lntemp.HarnessTest) { +func testDataLossProtection(ht *lntest.HarnessTest) { const ( chanAmt = funding.MaxBtcFundingAmount paymentAmt = 10000 @@ -1122,7 +1122,7 @@ func testDataLossProtection(ht *lntemp.HarnessTest) { // We'll first open up a channel between them with a 0.5 BTC // value. chanPoint := ht.OpenChannel( - carol, node, lntemp.OpenChannelParams{ + carol, node, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -1255,7 +1255,7 @@ func testDataLossProtection(ht *lntemp.HarnessTest) { // createLegacyRevocationChannel creates a single channel using the legacy // revocation producer format by using PSBT to signal a special pending channel // ID. -func createLegacyRevocationChannel(ht *lntemp.HarnessTest, +func createLegacyRevocationChannel(ht *lntest.HarnessTest, chanAmt, pushAmt btcutil.Amount, from, to *node.HarnessNode) { // We'll signal to the wallet that we also want to create a channel @@ -1277,7 +1277,7 @@ func createLegacyRevocationChannel(ht *lntemp.HarnessTest, }, }, } - openChannelReq := lntemp.OpenChannelParams{ + openChannelReq := lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, FundingShim: shim, @@ -1345,7 +1345,7 @@ func createLegacyRevocationChannel(ht *lntemp.HarnessTest, // chanRestoreViaRPC is a helper test method that returns a nodeRestorer // instance which will restore the target node from a password+seed, then // trigger a SCB restore using the RPC interface. -func chanRestoreViaRPC(ht *lntemp.HarnessTest, password []byte, +func chanRestoreViaRPC(ht *lntest.HarnessTest, password []byte, mnemonic []string, multi []byte, oldNode *node.HarnessNode) nodeRestorer { @@ -1382,7 +1382,7 @@ func copyPorts(oldNode *node.HarnessNode) node.Option { // // Note: this function is only used in this test file and has been made // specifically for testChanRestoreScenario. -func assertTimeLockSwept(ht *lntemp.HarnessTest, carol, dave *node.HarnessNode, +func assertTimeLockSwept(ht *lntest.HarnessTest, carol, dave *node.HarnessNode, carolStartingBalance, daveStartingBalance int64) { // We expect Carol to sweep her funds and also the anchor tx. @@ -1450,7 +1450,7 @@ func assertTimeLockSwept(ht *lntemp.HarnessTest, carol, dave *node.HarnessNode, // funds immediately, and Carol sweeping her fund after her CSV delay is up. If // the blankSlate value is true, then this means that Dave won't need to sweep // on chain as he has no funds in the channel. -func assertDLPExecuted(ht *lntemp.HarnessTest, +func assertDLPExecuted(ht *lntest.HarnessTest, carol *node.HarnessNode, carolStartingBalance int64, dave *node.HarnessNode, daveStartingBalance int64, commitType lnrpc.CommitmentType) { @@ -1467,7 +1467,7 @@ func assertDLPExecuted(ht *lntemp.HarnessTest, // Upon reconnection, the nodes should detect that Dave is out of sync. // Carol should force close the channel using her latest commitment. expectedTxes := 1 - if lntemp.CommitTypeHasAnchors(commitType) { + if lntest.CommitTypeHasAnchors(commitType) { expectedTxes = 2 } ht.Miner.AssertNumTxsInMempool(expectedTxes) diff --git a/itest/lnd_channel_balance_test.go b/itest/lnd_channel_balance_test.go index d54258e11..72dd16ea3 100644 --- a/itest/lnd_channel_balance_test.go +++ b/itest/lnd_channel_balance_test.go @@ -7,8 +7,8 @@ import ( "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/require" @@ -16,7 +16,7 @@ import ( // testChannelBalance creates a new channel between Alice and Bob, then checks // channel balance to be equal amount specified while creation of channel. -func testChannelBalance(ht *lntemp.HarnessTest) { +func testChannelBalance(ht *lntest.HarnessTest) { // Open a channel with 0.16 BTC between Alice and Bob, ensuring the // channel has been opened properly. amount := funding.MaxBtcFundingAmount @@ -52,16 +52,16 @@ func testChannelBalance(ht *lntemp.HarnessTest) { ht.EnsureConnected(alice, bob) chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: amount}, + alice, bob, lntest.OpenChannelParams{Amt: amount}, ) cType := ht.GetChannelCommitType(alice, chanPoint) // 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-lntemp.CalcStaticFee(cType, 0), 0) + checkChannelBalance(alice, amount-lntest.CalcStaticFee(cType, 0), 0) // Ensure Bob currently has no available balance within the channel. - checkChannelBalance(bob, 0, amount-lntemp.CalcStaticFee(cType, 0)) + checkChannelBalance(bob, 0, amount-lntest.CalcStaticFee(cType, 0)) // Finally close the channel between Alice and Bob, asserting that the // channel has been properly closed on-chain. @@ -73,7 +73,7 @@ func testChannelBalance(ht *lntemp.HarnessTest) { // Alice will send Htlcs to Carol while she is in hodl mode. This will result // in a build of pending Htlcs. We expect the channels unsettled balance to // equal the sum of all the Pending Htlcs. -func testChannelUnsettledBalance(ht *lntemp.HarnessTest) { +func testChannelUnsettledBalance(ht *lntest.HarnessTest) { const chanAmt = btcutil.Amount(1000000) // Creates a helper closure to be used below which asserts the proper @@ -123,20 +123,20 @@ func testChannelUnsettledBalance(ht *lntemp.HarnessTest) { // Open a channel between Alice and Carol. chanPointAlice := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) cType := ht.GetChannelCommitType(alice, chanPointAlice) // Check alice's channel balance, which should have zero remote and zero // pending balance. checkChannelBalance( - alice, chanAmt-lntemp.CalcStaticFee(cType, 0), 0, 0, 0, + alice, chanAmt-lntest.CalcStaticFee(cType, 0), 0, 0, 0, ) // Check carol's channel balance, which should have zero local and zero // pending balance. checkChannelBalance( - carol, 0, chanAmt-lntemp.CalcStaticFee(cType, 0), 0, 0, + carol, 0, chanAmt-lntest.CalcStaticFee(cType, 0), 0, 0, ) // Channel should be ready for payments. @@ -199,7 +199,7 @@ 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. - fee := lntemp.CalcStaticFee(cType, 0) + fee := lntest.CalcStaticFee(cType, 0) aliceLocal := chanAmt - fee - numInvoices*payAmt checkChannelBalance(alice, aliceLocal, 0, 0, numInvoices*payAmt) diff --git a/itest/lnd_channel_force_close_test.go b/itest/lnd_channel_force_close_test.go index 8db63cb1a..f7b77ec88 100644 --- a/itest/lnd_channel_force_close_test.go +++ b/itest/lnd_channel_force_close_test.go @@ -13,8 +13,8 @@ import ( "github.com/lightningnetwork/lnd/chainreg" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/chainfee" @@ -30,7 +30,7 @@ import ( // // Note that whether the deadline is used or not is implicitly checked by its // corresponding fee rates. -func testCommitmentTransactionDeadline(ht *lntemp.HarnessTest) { +func testCommitmentTransactionDeadline(ht *lntest.HarnessTest) { // Get the default max fee rate used in sweeping the commitment // transaction. defaultMax := lnwallet.DefaultAnchorsCommitMaxFeeRateSatPerVByte @@ -72,7 +72,7 @@ func testCommitmentTransactionDeadline(ht *lntemp.HarnessTest) { setupNode := func(name string) *node.HarnessNode { // Create the node. args := []string{"--hodl.exit-settle"} - args = append(args, lntemp.NodeArgsForCommitType( + args = append(args, lntest.NodeArgsForCommitType( lnrpc.CommitmentType_ANCHORS)..., ) node := ht.NewNode(name, args) @@ -104,7 +104,7 @@ func testCommitmentTransactionDeadline(ht *lntemp.HarnessTest) { // Open a channel between Alice and Bob. chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: 10e6, PushAmt: 5e6, }, @@ -194,7 +194,7 @@ func testCommitmentTransactionDeadline(ht *lntemp.HarnessTest) { // process. // // TODO(roasbeef): also add an unsettled HTLC before force closing. -func testChannelForceClosure(ht *lntemp.HarnessTest) { +func testChannelForceClosure(ht *lntest.HarnessTest) { // We'll test the scenario for some of the commitment types, to ensure // outputs can be swept. commitTypes := []lnrpc.CommitmentType{ @@ -209,7 +209,7 @@ func testChannelForceClosure(ht *lntemp.HarnessTest) { success := ht.Run(testName, func(t *testing.T) { st := ht.Subtest(t) - args := lntemp.NodeArgsForCommitType(channelType) + args := lntest.NodeArgsForCommitType(channelType) alice := st.NewNode("Alice", args) defer st.Shutdown(alice) @@ -237,7 +237,7 @@ func testChannelForceClosure(ht *lntemp.HarnessTest) { } } -func channelForceClosureTest(ht *lntemp.HarnessTest, +func channelForceClosureTest(ht *lntest.HarnessTest, alice, carol *node.HarnessNode, channelType lnrpc.CommitmentType) { const ( @@ -268,7 +268,7 @@ func channelForceClosureTest(ht *lntemp.HarnessTest, carolStartingBalance := carolBalResp.ConfirmedBalance chanPoint := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{ + alice, carol, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, }, @@ -600,6 +600,8 @@ func channelForceClosureTest(ht *lntemp.HarnessTest, // Update current height _, curHeight = ht.Miner.GetBestBlock() + // checkForceClosedChannelNumHtlcs verifies that a force closed channel + // has the proper number of htlcs. err = wait.NoError(func() error { // Now that the commit output has been fully swept, check to // see that the channel remains open for the pending htlc @@ -986,7 +988,7 @@ func padCLTV(cltv uint32) uint32 { // testFailingChannel tests that we will fail the channel by force closing it // in the case where a counterparty tries to settle an HTLC with the wrong // preimage. -func testFailingChannel(ht *lntemp.HarnessTest) { +func testFailingChannel(ht *lntest.HarnessTest) { const paymentAmt = 10000 chanAmt := lnd.MaxFundingAmount @@ -999,7 +1001,7 @@ func testFailingChannel(ht *lntemp.HarnessTest) { ht.ConnectNodes(alice, carol) // Let Alice connect and open a channel to Carol, - ht.OpenChannel(alice, carol, lntemp.OpenChannelParams{Amt: chanAmt}) + ht.OpenChannel(alice, carol, lntest.OpenChannelParams{Amt: chanAmt}) // With the channel open, we'll create a invoice for Carol that Alice // will attempt to pay. @@ -1058,7 +1060,7 @@ func testFailingChannel(ht *lntemp.HarnessTest) { // type matches a set of expected resolutions. // // NOTE: only used in current test file. -func assertReports(ht *lntemp.HarnessTest, hn *node.HarnessNode, +func assertReports(ht *lntest.HarnessTest, hn *node.HarnessNode, chanPoint *lnrpc.ChannelPoint, expected map[string]*lnrpc.Resolution) { op := ht.OutPointFromChannelPoint(chanPoint) @@ -1092,7 +1094,7 @@ func assertReports(ht *lntemp.HarnessTest, hn *node.HarnessNode, // maturity height are as expected. // // NOTE: only used in current test file. -func checkCommitmentMaturity(forceClose lntemp.PendingForceClose, +func checkCommitmentMaturity(forceClose lntest.PendingForceClose, maturityHeight uint32, blocksTilMaturity int32) error { if forceClose.MaturityHeight != maturityHeight { diff --git a/itest/lnd_channel_graph_test.go b/itest/lnd_channel_graph_test.go index 0bfc31b7c..b01879c18 100644 --- a/itest/lnd_channel_graph_test.go +++ b/itest/lnd_channel_graph_test.go @@ -11,8 +11,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/peersrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) @@ -40,7 +40,7 @@ import ( // take more than 5 seconds to finish, the channel will be marked as disabled, // thus a following operation will fail if it relies on the channel being // enabled. -func testUpdateChanStatus(ht *lntemp.HarnessTest) { +func testUpdateChanStatus(ht *lntest.HarnessTest) { // Create two fresh nodes and open a channel between them. alice, bob := ht.Alice, ht.Bob args := []string{ @@ -57,7 +57,7 @@ func testUpdateChanStatus(ht *lntemp.HarnessTest) { // being the sole funder of the channel. chanAmt := btcutil.Amount(100000) chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) defer ht.CloseChannel(alice, chanPoint) @@ -141,7 +141,7 @@ func testUpdateChanStatus(ht *lntemp.HarnessTest) { FeeRateMilliMsat: int64(chainreg.DefaultBitcoinFeeRate), TimeLockDelta: chainreg.DefaultBitcoinTimeLockDelta, MinHtlc: 1000, // default value - MaxHtlcMsat: lntemp.CalculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntest.CalculateMaxHtlc(chanAmt), } // Manually disable the channel and ensure that a "Disabled = true" @@ -217,14 +217,14 @@ func testUpdateChanStatus(ht *lntemp.HarnessTest) { // testUnannouncedChannels checks unannounced channels are not returned by // describeGraph RPC request unless explicitly asked for. -func testUnannouncedChannels(ht *lntemp.HarnessTest) { +func testUnannouncedChannels(ht *lntest.HarnessTest) { amount := funding.MaxBtcFundingAmount alice, bob := ht.Alice, ht.Bob // Open a channel between Alice and Bob, ensuring the // channel has been opened properly. chanOpenUpdate := ht.OpenChannelAssertStream( - alice, bob, lntemp.OpenChannelParams{Amt: amount}, + alice, bob, lntest.OpenChannelParams{Amt: amount}, ) // Mine 2 blocks, and check that the channel is opened but not yet @@ -252,7 +252,7 @@ func testUnannouncedChannels(ht *lntemp.HarnessTest) { ht.CloseChannel(alice, fundingChanPoint) } -func testGraphTopologyNotifications(ht *lntemp.HarnessTest) { +func testGraphTopologyNotifications(ht *lntest.HarnessTest) { ht.Run("pinned", func(t *testing.T) { subT := ht.Subtest(t) testGraphTopologyNtfns(subT, true) @@ -263,7 +263,7 @@ func testGraphTopologyNotifications(ht *lntemp.HarnessTest) { }) } -func testGraphTopologyNtfns(ht *lntemp.HarnessTest, pinned bool) { +func testGraphTopologyNtfns(ht *lntest.HarnessTest, pinned bool) { const chanAmt = funding.MaxBtcFundingAmount // Spin up Bob first, since we will need to grab his pubkey when @@ -305,7 +305,7 @@ func testGraphTopologyNtfns(ht *lntemp.HarnessTest, pinned bool) { // Open a new channel between Alice and Bob. chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) // The channel opening above should have triggered a few notifications @@ -343,7 +343,7 @@ func testGraphTopologyNtfns(ht *lntemp.HarnessTest, pinned bool) { carol := ht.NewNode("Carol", nil) ht.ConnectNodes(bob, carol) chanPoint = ht.OpenChannel( - bob, carol, lntemp.OpenChannelParams{Amt: chanAmt}, + bob, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) // Reconnect Alice and Bob. This should result in the nodes syncing up @@ -366,7 +366,7 @@ func testGraphTopologyNtfns(ht *lntemp.HarnessTest, pinned bool) { // testNodeAnnouncement ensures that when a node is started with one or more // external IP addresses specified on the command line, that those addresses // announced to the network and reported in the network graph. -func testNodeAnnouncement(ht *lntemp.HarnessTest) { +func testNodeAnnouncement(ht *lntest.HarnessTest) { alice, bob := ht.Alice, ht.Bob advertisedAddrs := []string{ @@ -392,7 +392,7 @@ func testNodeAnnouncement(ht *lntemp.HarnessTest) { // ensures that Alice receives the node announcement from Bob as part of // the announcement broadcast. chanPoint := ht.OpenChannel( - bob, dave, lntemp.OpenChannelParams{Amt: 1000000}, + bob, dave, lntest.OpenChannelParams{Amt: 1000000}, ) assertAddrs := func(addrsFound []string, targetAddrs ...string) { @@ -421,7 +421,7 @@ func testNodeAnnouncement(ht *lntemp.HarnessTest) { // testUpdateNodeAnnouncement ensures that the RPC endpoint validates // the requests correctly and that the new node announcement is brodcasted // with the right information after updating our node. -func testUpdateNodeAnnouncement(ht *lntemp.HarnessTest) { +func testUpdateNodeAnnouncement(ht *lntest.HarnessTest) { alice, bob := ht.Alice, ht.Bob var lndArgs []string @@ -500,7 +500,7 @@ func testUpdateNodeAnnouncement(ht *lntemp.HarnessTest) { // ensures that Alice receives the node announcement from Bob as part of // the announcement broadcast. chanPoint := ht.OpenChannel( - bob, dave, lntemp.OpenChannelParams{ + bob, dave, lntest.OpenChannelParams{ Amt: 1000000, }, ) @@ -637,7 +637,7 @@ func testUpdateNodeAnnouncement(ht *lntemp.HarnessTest) { // assertSyncType asserts that the peer has an expected syncType. // // NOTE: only made for tests in this file. -func assertSyncType(ht *lntemp.HarnessTest, hn *node.HarnessNode, +func assertSyncType(ht *lntest.HarnessTest, hn *node.HarnessNode, peer string, syncType lnrpc.Peer_SyncType) { resp := hn.RPC.ListPeers() @@ -693,7 +693,7 @@ func compareNodeAnns(n1, n2 *lnrpc.NodeUpdate) error { // the response expected values. // // NOTE: only used for tests in this file. -func assertUpdateNodeAnnouncementResponse(ht *lntemp.HarnessTest, +func assertUpdateNodeAnnouncementResponse(ht *lntest.HarnessTest, response *peersrpc.NodeAnnouncementUpdateResponse, expectedOps map[string]int) { diff --git a/itest/lnd_channel_policy_test.go b/itest/lnd_channel_policy_test.go index 1d2f75e1e..876e8fd68 100644 --- a/itest/lnd_channel_policy_test.go +++ b/itest/lnd_channel_policy_test.go @@ -10,22 +10,22 @@ import ( "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/require" ) // testUpdateChannelPolicy tests that policy updates made to a channel // gets propagated to other nodes in the network. -func testUpdateChannelPolicy(ht *lntemp.HarnessTest) { +func testUpdateChannelPolicy(ht *lntest.HarnessTest) { const ( defaultFeeBase = 1000 defaultFeeRate = 1 defaultTimeLockDelta = chainreg.DefaultBitcoinTimeLockDelta defaultMinHtlc = 1000 ) - defaultMaxHtlc := lntemp.CalculateMaxHtlc(funding.MaxBtcFundingAmount) + defaultMaxHtlc := lntest.CalculateMaxHtlc(funding.MaxBtcFundingAmount) chanAmt := funding.MaxBtcFundingAmount pushAmt := chanAmt / 2 @@ -34,7 +34,7 @@ func testUpdateChannelPolicy(ht *lntemp.HarnessTest) { // Create a channel Alice->Bob. chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, }, @@ -87,7 +87,7 @@ func testUpdateChannelPolicy(ht *lntemp.HarnessTest) { // part of his ChannelUpdate. const customMinHtlc = 5000 chanPoint2 := ht.OpenChannel( - carol, bob, lntemp.OpenChannelParams{ + carol, bob, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, MinHtlc: customMinHtlc, @@ -283,7 +283,7 @@ func testUpdateChannelPolicy(ht *lntemp.HarnessTest) { // We'll now open a channel from Alice directly to Carol. ht.ConnectNodes(alice, carol) chanPoint3 := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{ + alice, carol, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, }, @@ -424,7 +424,7 @@ func testUpdateChannelPolicy(ht *lntemp.HarnessTest) { // chan-disable-timeout flags here. For instance, if some operations take more // than 6 seconds to finish, the channel will be marked as disabled, thus a // following operation will fail if it relies on the channel being enabled. -func testSendUpdateDisableChannel(ht *lntemp.HarnessTest) { +func testSendUpdateDisableChannel(ht *lntest.HarnessTest) { const chanAmt = 100000 alice, bob := ht.Alice, ht.Bob @@ -467,8 +467,8 @@ func testSendUpdateDisableChannel(ht *lntemp.HarnessTest) { // We now proceed to open channels: Alice=>Bob, Alice=>Carol and // Eve=>Carol. - p := lntemp.OpenChannelParams{Amt: chanAmt} - reqs := []*lntemp.OpenChannelRequest{ + p := lntest.OpenChannelParams{Amt: chanAmt} + reqs := []*lntest.OpenChannelRequest{ {Local: alice, Remote: bob, Param: p}, {Local: alice, Remote: carol, Param: p}, {Local: eve, Remote: carol, Param: p}, @@ -513,7 +513,7 @@ func testSendUpdateDisableChannel(ht *lntemp.HarnessTest) { FeeRateMilliMsat: int64(chainreg.DefaultBitcoinFeeRate), TimeLockDelta: chainreg.DefaultBitcoinTimeLockDelta, MinHtlc: 1000, // default value - MaxHtlcMsat: lntemp.CalculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntest.CalculateMaxHtlc(chanAmt), Disabled: true, } @@ -655,7 +655,7 @@ func testSendUpdateDisableChannel(ht *lntemp.HarnessTest) { // Bob will update the base fee via UpdateChannelPolicy, we will test that // Alice will not fail the payment and send it using the updated channel // policy. -func testUpdateChannelPolicyForPrivateChannel(ht *lntemp.HarnessTest) { +func testUpdateChannelPolicyForPrivateChannel(ht *lntest.HarnessTest) { const ( chanAmt = btcutil.Amount(100000) paymentAmt = 20000 @@ -668,7 +668,7 @@ func testUpdateChannelPolicyForPrivateChannel(ht *lntemp.HarnessTest) { // Open a channel with 100k satoshis between Alice and Bob. chanPointAliceBob := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -681,7 +681,7 @@ func testUpdateChannelPolicyForPrivateChannel(ht *lntemp.HarnessTest) { // Open a channel with 100k satoshis between Bob and Carol. chanPointBobCarol := ht.OpenChannel( - bob, carol, lntemp.OpenChannelParams{ + bob, carol, lntest.OpenChannelParams{ Amt: chanAmt, Private: true, }, @@ -755,14 +755,14 @@ func testUpdateChannelPolicyForPrivateChannel(ht *lntemp.HarnessTest) { // testUpdateChannelPolicyFeeRateAccuracy tests that updating the channel policy // rounds fee rate values correctly as well as setting fee rate with ppm works // as expected. -func testUpdateChannelPolicyFeeRateAccuracy(ht *lntemp.HarnessTest) { +func testUpdateChannelPolicyFeeRateAccuracy(ht *lntest.HarnessTest) { chanAmt := funding.MaxBtcFundingAmount pushAmt := chanAmt / 2 // Create a channel Alice -> Bob. alice, bob := ht.Alice, ht.Bob chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, }, @@ -826,7 +826,7 @@ func testUpdateChannelPolicyFeeRateAccuracy(ht *lntemp.HarnessTest) { // assertNodesPolicyUpdate checks that a given policy update has been received // by a list of given nodes. -func assertNodesPolicyUpdate(ht *lntemp.HarnessTest, nodes []*node.HarnessNode, +func assertNodesPolicyUpdate(ht *lntest.HarnessTest, nodes []*node.HarnessNode, advertisingNode *node.HarnessNode, policy *lnrpc.RoutingPolicy, chanPoint *lnrpc.ChannelPoint) { diff --git a/itest/lnd_custom_message.go b/itest/lnd_custom_message.go index 5faf425a1..14a4e7949 100644 --- a/itest/lnd_custom_message.go +++ b/itest/lnd_custom_message.go @@ -5,7 +5,7 @@ import ( "time" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/require" ) @@ -13,7 +13,7 @@ import ( // testCustomMessage tests sending and receiving of overridden custom message // types (within the message type range usually reserved for protocol messages) // via the send and subscribe custom message APIs. -func testCustomMessage(ht *lntemp.HarnessTest) { +func testCustomMessage(ht *lntest.HarnessTest) { alice, bob := ht.Alice, ht.Bob var ( @@ -82,7 +82,7 @@ func testCustomMessage(ht *lntemp.HarnessTest) { require.Equal(ht, bob.PubKey[:], msg.Peer, "first msg "+ "peer wrong") - case <-time.After(defaultTimeout): + case <-time.After(lntest.DefaultTimeout): ht.Fatalf("alice did not receive first custom message: %v", msgType) } @@ -151,7 +151,7 @@ func testCustomMessage(ht *lntemp.HarnessTest) { require.Equal(ht, bob.PubKey[:], msg.Peer, "second "+ "message peer") - case <-time.After(defaultTimeout): + case <-time.After(lntest.DefaultTimeout): ht.Fatalf("alice did not receive second custom message") } } diff --git a/itest/lnd_etcd_failover_test.go b/itest/lnd_etcd_failover_test.go index 0488191f8..81021572e 100644 --- a/itest/lnd_etcd_failover_test.go +++ b/itest/lnd_etcd_failover_test.go @@ -12,12 +12,12 @@ import ( "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/stretchr/testify/require" ) -func assertLeader(ht *lntemp.HarnessTest, observer cluster.LeaderElector, +func assertLeader(ht *lntest.HarnessTest, observer cluster.LeaderElector, expected string) { leader, err := observer.Leader(ht.Context()) @@ -29,7 +29,7 @@ func assertLeader(ht *lntemp.HarnessTest, observer cluster.LeaderElector, // testEtcdFailover tests that in a cluster setup where two LND nodes form a // single cluster (sharing the same identity) one can hand over the leader role // to the other (failing over after graceful shutdown or forceful abort). -func testEtcdFailover(ht *lntemp.HarnessTest) { +func testEtcdFailover(ht *lntest.HarnessTest) { testCases := []struct { name string kill bool @@ -54,7 +54,7 @@ func testEtcdFailover(ht *lntemp.HarnessTest) { } } -func testEtcdFailoverCase(ht *lntemp.HarnessTest, kill bool) { +func testEtcdFailoverCase(ht *lntest.HarnessTest, kill bool) { etcdCfg, cleanup, err := kvdb.StartEtcdTestBackend( ht.T.TempDir(), uint16(node.NextAvailablePort()), uint16(node.NextAvailablePort()), "", @@ -91,7 +91,7 @@ func testEtcdFailoverCase(ht *lntemp.HarnessTest, kill bool) { // Open a channel with 100k satoshis between Carol and Alice with Alice // being the sole funder of the channel. chanAmt := btcutil.Amount(100_000) - ht.OpenChannel(alice, carol1, lntemp.OpenChannelParams{Amt: chanAmt}) + ht.OpenChannel(alice, carol1, lntest.OpenChannelParams{Amt: chanAmt}) // At this point Carol-1 is the elected leader, while Carol-2 will wait // to become the leader when Carol-1 stops. diff --git a/itest/lnd_forward_interceptor_test.go b/itest/lnd_forward_interceptor_test.go index 4f667552b..f0ea5b6c5 100644 --- a/itest/lnd_forward_interceptor_test.go +++ b/itest/lnd_forward_interceptor_test.go @@ -9,8 +9,8 @@ import ( "github.com/lightningnetwork/lnd/chainreg" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/routing/route" @@ -34,7 +34,7 @@ type interceptorTestCase struct { // testForwardInterceptorDedupHtlc tests that upon reconnection, duplicate // HTLCs aren't re-notified using the HTLC interceptor API. -func testForwardInterceptorDedupHtlc(ht *lntemp.HarnessTest) { +func testForwardInterceptorDedupHtlc(ht *lntest.HarnessTest) { // Initialize the test context with 3 connected nodes. ts := newInterceptorTestScenario(ht) @@ -42,8 +42,8 @@ func testForwardInterceptorDedupHtlc(ht *lntemp.HarnessTest) { // Open and wait for channels. const chanAmt = btcutil.Amount(300000) - p := lntemp.OpenChannelParams{Amt: chanAmt} - reqs := []*lntemp.OpenChannelRequest{ + p := lntest.OpenChannelParams{Amt: chanAmt} + reqs := []*lntest.OpenChannelRequest{ {Local: alice, Remote: bob, Param: p}, {Local: bob, Remote: carol, Param: p}, } @@ -185,15 +185,15 @@ func testForwardInterceptorDedupHtlc(ht *lntemp.HarnessTest) { // 3. Intercepted held htlcs result in no payment (invoice is not settled). // 4. When Interceptor disconnects it resumes all held htlcs, which result in // valid payment (invoice is settled). -func testForwardInterceptorBasic(ht *lntemp.HarnessTest) { +func testForwardInterceptorBasic(ht *lntest.HarnessTest) { ts := newInterceptorTestScenario(ht) alice, bob, carol := ts.alice, ts.bob, ts.carol // Open and wait for channels. const chanAmt = btcutil.Amount(300000) - p := lntemp.OpenChannelParams{Amt: chanAmt} - reqs := []*lntemp.OpenChannelRequest{ + p := lntest.OpenChannelParams{Amt: chanAmt} + reqs := []*lntest.OpenChannelRequest{ {Local: alice, Remote: bob, Param: p}, {Local: bob, Remote: carol, Param: p}, } @@ -345,7 +345,7 @@ func testForwardInterceptorBasic(ht *lntemp.HarnessTest) { // interceptorTestScenario is a helper struct to hold the test context and // provide the needed functionality. type interceptorTestScenario struct { - ht *lntemp.HarnessTest + ht *lntest.HarnessTest alice, bob, carol *node.HarnessNode } @@ -356,7 +356,7 @@ type interceptorTestScenario struct { // // Among them, Alice and Bob are standby nodes and Carol is a new node. func newInterceptorTestScenario( - ht *lntemp.HarnessTest) *interceptorTestScenario { + ht *lntest.HarnessTest) *interceptorTestScenario { alice, bob := ht.Alice, ht.Bob carol := ht.NewNode("carol", nil) diff --git a/itest/lnd_funding_test.go b/itest/lnd_funding_test.go index 1bfb733af..432261ffb 100644 --- a/itest/lnd_funding_test.go +++ b/itest/lnd_funding_test.go @@ -13,8 +13,8 @@ import ( "github.com/lightningnetwork/lnd/labels" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/signrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/require" ) @@ -24,7 +24,7 @@ import ( // Bob, then immediately closes the channel after asserting some expected post // conditions. Finally, the chain itself is checked to ensure the closing // transaction was mined. -func testBasicChannelFunding(ht *lntemp.HarnessTest) { +func testBasicChannelFunding(ht *lntest.HarnessTest) { // Run through the test with combinations of all the different // commitment types. allTypes := []lnrpc.CommitmentType{ @@ -35,20 +35,20 @@ func testBasicChannelFunding(ht *lntemp.HarnessTest) { // testFunding is a function closure that takes Carol and Dave's // commitment types and test the funding flow. - testFunding := func(ht *lntemp.HarnessTest, carolCommitType, + testFunding := func(ht *lntest.HarnessTest, carolCommitType, daveCommitType lnrpc.CommitmentType) { // Based on the current tweak variable for Carol, we'll // preferentially signal the legacy commitment format. We do // the same for Dave shortly below. - carolArgs := lntemp.NodeArgsForCommitType(carolCommitType) + carolArgs := lntest.NodeArgsForCommitType(carolCommitType) carol := ht.NewNode("Carol", carolArgs) // Each time, we'll send Carol a new set of coins in order to // fund the channel. ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) - daveArgs := lntemp.NodeArgsForCommitType(daveCommitType) + daveArgs := lntest.NodeArgsForCommitType(daveCommitType) dave := ht.NewNode("Dave", daveArgs) // Before we start the test, we'll ensure both sides are @@ -140,7 +140,7 @@ test: // test. Given two nodes: Alice and Bob, it'll assert proper channel creation, // then return a function closure that should be called to assert proper // channel closure. -func basicChannelFundingTest(ht *lntemp.HarnessTest, +func basicChannelFundingTest(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, fundingShim *lnrpc.FundingShim) (*lnrpc.Channel, *lnrpc.Channel, func()) { @@ -181,7 +181,7 @@ func basicChannelFundingTest(ht *lntemp.HarnessTest, // assertions will be executed to ensure the funding process completed // successfully. chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, FundingShim: fundingShim, @@ -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 - lntemp.CalcStaticFee(cType, 0) + aliceLocalBalance := chanAmt - pushAmt - lntest.CalcStaticFee(cType, 0) checkChannelBalance( alice, aliceChannelBalance, aliceLocalBalance, pushAmt, ) @@ -216,7 +216,7 @@ func basicChannelFundingTest(ht *lntemp.HarnessTest, // testUnconfirmedChannelFunding tests that our unconfirmed change outputs can // be used to fund channels. -func testUnconfirmedChannelFunding(ht *lntemp.HarnessTest) { +func testUnconfirmedChannelFunding(ht *lntest.HarnessTest) { const ( chanAmt = funding.MaxBtcFundingAmount pushAmt = btcutil.Amount(100000) @@ -236,7 +236,7 @@ func testUnconfirmedChannelFunding(ht *lntemp.HarnessTest) { ht.ConnectNodes(carol, alice) chanOpenUpdate := ht.OpenChannelAssertStream( - carol, alice, lntemp.OpenChannelParams{ + carol, alice, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, SpendUnconfirmed: true, @@ -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 - lntemp.CalcStaticFee(cType, 0) + carolLocalBalance := chanAmt - pushAmt - lntest.CalcStaticFee(cType, 0) checkChannelBalance(carol, 0, 0, carolLocalBalance, pushAmt) // For Alice, her local/remote balances should be zero, and the @@ -329,7 +329,12 @@ func testUnconfirmedChannelFunding(ht *lntemp.HarnessTest) { // testChannelFundingInputTypes tests that any type of supported input type can // be used to fund channels. -func testChannelFundingInputTypes(ht *lntemp.HarnessTest) { +func testChannelFundingInputTypes(ht *lntest.HarnessTest) { + const ( + chanAmt = funding.MaxBtcFundingAmount + burnAddr = "bcrt1qxsnqpdc842lu8c0xlllgvejt6rhy49u6fmpgyz" + ) + // We'll start off by creating a node for Carol. carol := ht.NewNode("Carol", nil) @@ -342,7 +347,7 @@ func testChannelFundingInputTypes(ht *lntemp.HarnessTest) { // runChannelFundingInputTypes tests that any type of supported input type can // be used to fund channels. -func runChannelFundingInputTypes(ht *lntemp.HarnessTest, alice, +func runChannelFundingInputTypes(ht *lntest.HarnessTest, alice, carol *node.HarnessNode) { const ( @@ -411,7 +416,7 @@ func runChannelFundingInputTypes(ht *lntemp.HarnessTest, alice, funder((chanAmt*11)/10, carol) chanOpenUpdate := ht.OpenChannelAssertStream( - carol, alice, lntemp.OpenChannelParams{ + carol, alice, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -423,7 +428,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 - lntemp.CalcStaticFee(cType, 0) + carolLocalBalance := chanAmt - lntest.CalcStaticFee(cType, 0) checkChannelBalance(carol, 0, 0, carolLocalBalance, 0) // For Alice, her local/remote balances should be zero, and the @@ -463,7 +468,7 @@ func runChannelFundingInputTypes(ht *lntemp.HarnessTest, alice, // sendAllCoinsConfirm sends all coins of the node's wallet to the given address // and awaits one confirmation. -func sendAllCoinsConfirm(ht *lntemp.HarnessTest, node *node.HarnessNode, +func sendAllCoinsConfirm(ht *lntest.HarnessTest, node *node.HarnessNode, addr string) { sweepReq := &lnrpc.SendCoinsRequest{ @@ -477,7 +482,7 @@ func sendAllCoinsConfirm(ht *lntemp.HarnessTest, node *node.HarnessNode, // testExternalFundingChanPoint tests that we're able to carry out a normal // channel funding workflow given a channel point that was constructed outside // the main daemon. -func testExternalFundingChanPoint(ht *lntemp.HarnessTest) { +func testExternalFundingChanPoint(ht *lntest.HarnessTest) { // First, we'll create two new nodes that we'll use to open channel // between for this test. carol := ht.NewNode("carol", nil) @@ -500,7 +505,7 @@ func testExternalFundingChanPoint(ht *lntemp.HarnessTest) { ht, carol, dave, chanSize, thawHeight, false, ) ht.OpenChannelAssertPending( - carol, dave, lntemp.OpenChannelParams{ + carol, dave, lntest.OpenChannelParams{ Amt: chanSize, FundingShim: fundingShim1, }, @@ -591,7 +596,7 @@ func testExternalFundingChanPoint(ht *lntemp.HarnessTest) { // representation of channels if the system is restarted or disconnected. // testFundingPersistence mirrors testBasicChannelFunding, but adds restarts // and checks for the state of channels with unconfirmed funding transactions. -func testChannelFundingPersistence(ht *lntemp.HarnessTest) { +func testChannelFundingPersistence(ht *lntest.HarnessTest) { chanAmt := funding.MaxBtcFundingAmount pushAmt := btcutil.Amount(0) @@ -609,7 +614,7 @@ func testChannelFundingPersistence(ht *lntemp.HarnessTest) { // Create a new channel that requires 5 confs before it's considered // open, then broadcast the funding transaction - param := lntemp.OpenChannelParams{ + param := lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, } @@ -676,7 +681,7 @@ func testChannelFundingPersistence(ht *lntemp.HarnessTest) { // The channel should be listed in the peer information returned by // both peers. - chanPoint := lntemp.ChanPointFromPendingUpdate(update) + chanPoint := lntest.ChanPointFromPendingUpdate(update) // Re-lookup our transaction in the block that it confirmed in. tx = ht.AssertTxAtHeight(alice, height, fundingTxID) @@ -699,7 +704,7 @@ func testChannelFundingPersistence(ht *lntemp.HarnessTest) { // testBatchChanFunding makes sure multiple channels can be opened in one batch // transaction in an atomic way. -func testBatchChanFunding(ht *lntemp.HarnessTest) { +func testBatchChanFunding(ht *lntest.HarnessTest) { // First, we'll create two new nodes that we'll use to open channels // to during this test. Carol has a high minimum funding amount that // we'll use to trigger an error during the batch channel open. @@ -793,7 +798,7 @@ func testBatchChanFunding(ht *lntemp.HarnessTest) { // deriveFundingShim creates a channel funding shim by deriving the necessary // keys on both sides. -func deriveFundingShim(ht *lntemp.HarnessTest, +func deriveFundingShim(ht *lntest.HarnessTest, carol, dave *node.HarnessNode, chanSize btcutil.Amount, thawHeight uint32, publish bool) (*lnrpc.FundingShim, *lnrpc.ChannelPoint, *chainhash.Hash) { diff --git a/itest/lnd_hold_invoice_force_test.go b/itest/lnd_hold_invoice_force_test.go index 613281305..a3d832614 100644 --- a/itest/lnd_hold_invoice_force_test.go +++ b/itest/lnd_hold_invoice_force_test.go @@ -7,7 +7,7 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lntypes" "github.com/stretchr/testify/require" @@ -15,11 +15,11 @@ import ( // testHoldInvoiceForceClose tests cancellation of accepted hold invoices which // would otherwise trigger force closes when they expire. -func testHoldInvoiceForceClose(ht *lntemp.HarnessTest) { +func testHoldInvoiceForceClose(ht *lntest.HarnessTest) { // Open a channel between alice and bob. alice, bob := ht.Alice, ht.Bob chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: 300000}, + alice, bob, lntest.OpenChannelParams{Amt: 300000}, ) // Create a non-dust hold invoice for bob. diff --git a/itest/lnd_hold_persistence_test.go b/itest/lnd_hold_persistence_test.go index da5424ca3..c7cd5eac2 100644 --- a/itest/lnd_hold_persistence_test.go +++ b/itest/lnd_hold_persistence_test.go @@ -7,8 +7,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/rpc" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/rpc" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lntypes" "github.com/stretchr/testify/require" @@ -17,7 +17,7 @@ import ( // testHoldInvoicePersistence tests that a sender to a hold-invoice, can be // restarted before the payment gets settled, and still be able to receive the // preimage. -func testHoldInvoicePersistence(ht *lntemp.HarnessTest) { +func testHoldInvoicePersistence(ht *lntest.HarnessTest) { const ( chanAmt = btcutil.Amount(1000000) numPayments = 10 @@ -34,7 +34,7 @@ func testHoldInvoicePersistence(ht *lntemp.HarnessTest) { // Open a channel between Alice and Carol which is private so that we // cover the addition of hop hints for hold invoices. chanPointAlice := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{ + alice, carol, lntest.OpenChannelParams{ Amt: chanAmt, Private: true, }, @@ -45,7 +45,7 @@ func testHoldInvoicePersistence(ht *lntemp.HarnessTest) { // has at least one public channel in the graph. We open a public // channel from Alice -> Bob and wait for Carol to see it. chanPointBob := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, }, ) diff --git a/itest/lnd_macaroons_test.go b/itest/lnd_macaroons_test.go index 01d576f8f..b5dad77bb 100644 --- a/itest/lnd_macaroons_test.go +++ b/itest/lnd_macaroons_test.go @@ -11,8 +11,8 @@ import ( "github.com/golang/protobuf/proto" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/macaroons" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -23,7 +23,7 @@ import ( // enabled on the gRPC interface, no requests with missing or invalid // macaroons are allowed. Further, the specific access rights (read/write, // entity based) and first-party caveats are tested as well. -func testMacaroonAuthentication(ht *lntemp.HarnessTest) { +func testMacaroonAuthentication(ht *lntest.HarnessTest) { var ( infoReq = &lnrpc.GetInfoRequest{} newAddrReq = &lnrpc.NewAddressRequest{ @@ -294,7 +294,7 @@ func testMacaroonAuthentication(ht *lntemp.HarnessTest) { // testBakeMacaroon checks that when creating macaroons, the permissions param // in the request must be set correctly, and the baked macaroon has the intended // permissions. -func testBakeMacaroon(ht *lntemp.HarnessTest) { +func testBakeMacaroon(ht *lntest.HarnessTest) { var testNode = ht.Alice testCases := []struct { @@ -518,7 +518,7 @@ func testBakeMacaroon(ht *lntemp.HarnessTest) { // specified ID and invalidates all macaroons derived from the key with that ID. // Also, it checks deleting the reserved marcaroon ID, DefaultRootKeyID or is // forbidden. -func testDeleteMacaroonID(ht *lntemp.HarnessTest) { +func testDeleteMacaroonID(ht *lntest.HarnessTest) { var ( ctxb = ht.Context() testNode = ht.Alice @@ -610,7 +610,7 @@ func testDeleteMacaroonID(ht *lntemp.HarnessTest) { // does not write any macaroon files to the daemon's file system and returns // the admin macaroon in the response. It then checks that the password // change of the wallet can also happen stateless. -func testStatelessInit(ht *lntemp.HarnessTest) { +func testStatelessInit(ht *lntest.HarnessTest) { var ( initPw = []byte("stateless") newPw = []byte("stateless-new") diff --git a/itest/lnd_max_channel_size_test.go b/itest/lnd_max_channel_size_test.go index 320ccabe4..9959c7589 100644 --- a/itest/lnd_max_channel_size_test.go +++ b/itest/lnd_max_channel_size_test.go @@ -5,14 +5,14 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/funding" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lnwallet" ) // testMaxChannelSize tests that lnd handles --maxchansize parameter correctly. // Wumbo nodes should enforce a default soft limit of 10 BTC by default. This // limit can be adjusted with --maxchansize config option. -func testMaxChannelSize(ht *lntemp.HarnessTest) { +func testMaxChannelSize(ht *lntest.HarnessTest) { // We'll make two new nodes, both wumbo but with the default limit on // maximum channel size (10 BTC) wumboNode := ht.NewNode( @@ -39,7 +39,7 @@ func testMaxChannelSize(ht *lntemp.HarnessTest) { ) ht.OpenChannelAssertErr( wumboNode, wumboNode2, - lntemp.OpenChannelParams{Amt: chanAmt}, expectedErr, + lntest.OpenChannelParams{Amt: chanAmt}, expectedErr, ) // We'll now make another wumbo node with appropriate maximum channel @@ -57,7 +57,7 @@ func testMaxChannelSize(ht *lntemp.HarnessTest) { // Creating a wumbo channel between these two nodes should succeed. ht.EnsureConnected(wumboNode, wumboNode3) chanPoint := ht.OpenChannel( - wumboNode, wumboNode3, lntemp.OpenChannelParams{Amt: chanAmt}, + wumboNode, wumboNode3, lntest.OpenChannelParams{Amt: chanAmt}, ) ht.CloseChannel(wumboNode, chanPoint) diff --git a/itest/lnd_max_htlcs_test.go b/itest/lnd_max_htlcs_test.go index d457e452f..72d6ac031 100644 --- a/itest/lnd_max_htlcs_test.go +++ b/itest/lnd_max_htlcs_test.go @@ -4,8 +4,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntypes" "github.com/stretchr/testify/require" ) @@ -14,14 +14,14 @@ import ( // channel where we have already reached the limit of the number of htlcs that // we may add to the remote party's commitment. This test asserts that we do // not attempt to use the full channel at all in our pathfinding. -func testMaxHtlcPathfind(ht *lntemp.HarnessTest) { +func testMaxHtlcPathfind(ht *lntest.HarnessTest) { // Setup a channel between Alice and Bob where Alice will only allow // Bob to add a maximum of 5 htlcs to her commitment. maxHtlcs := 5 alice, bob := ht.Alice, ht.Bob chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: 1000000, PushAmt: 800000, RemoteMaxHtlcs: uint16(maxHtlcs), @@ -84,7 +84,7 @@ type holdSubscription struct { // cancel updates a hold invoice to cancel from the recipient and consumes // updates from the payer until it has reached a final, failed state. -func (h *holdSubscription) cancel(ht *lntemp.HarnessTest) { +func (h *holdSubscription) cancel(ht *lntest.HarnessTest) { h.recipient.RPC.CancelInvoice(h.hash[:]) invUpdate := ht.ReceiveSingleInvoice(h.invSubscription) @@ -110,7 +110,7 @@ func (h *holdSubscription) cancel(ht *lntemp.HarnessTest) { // acceptHoldInvoice adds a hold invoice to the recipient node, pays it from // the sender and asserts that we have reached the accepted state where htlcs // are locked in for the payment. -func acceptHoldInvoice(ht *lntemp.HarnessTest, idx int, sender, +func acceptHoldInvoice(ht *lntest.HarnessTest, idx int, sender, receiver *node.HarnessNode) *holdSubscription { hash := [lntypes.HashSize]byte{byte(idx + 1)} diff --git a/itest/lnd_misc_test.go b/itest/lnd_misc_test.go index 04274fb35..a0f0e4616 100644 --- a/itest/lnd_misc_test.go +++ b/itest/lnd_misc_test.go @@ -15,8 +15,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" @@ -28,7 +28,7 @@ import ( // disconnect at any point. // // TODO(yy): move to lnd_network_test. -func testDisconnectingTargetPeer(ht *lntemp.HarnessTest) { +func testDisconnectingTargetPeer(ht *lntest.HarnessTest) { // We'll start both nodes with a high backoff so that they don't // reconnect automatically during our test. args := []string{ @@ -49,7 +49,7 @@ func testDisconnectingTargetPeer(ht *lntemp.HarnessTest) { // Create a new channel that requires 1 confs before it's considered // open, then broadcast the funding transaction const numConfs = 1 - p := lntemp.OpenChannelParams{ + p := lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, } @@ -119,7 +119,7 @@ func testDisconnectingTargetPeer(ht *lntemp.HarnessTest) { // configuration arguments to force Carol to replay the same sphinx packet // after reconnecting to Dave, and compare the returned failure message with // what we expect for replayed onion packets. -func testSphinxReplayPersistence(ht *lntemp.HarnessTest) { +func testSphinxReplayPersistence(ht *lntest.HarnessTest) { // Open a channel with 100k satoshis between Carol and Dave with Carol // being the sole funder of the channel. chanAmt := btcutil.Amount(100000) @@ -135,7 +135,7 @@ func testSphinxReplayPersistence(ht *lntemp.HarnessTest) { ht.ConnectNodes(carol, dave) chanPoint := ht.OpenChannel( - carol, dave, lntemp.OpenChannelParams{ + carol, dave, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -150,7 +150,7 @@ func testSphinxReplayPersistence(ht *lntemp.HarnessTest) { ht.ConnectNodes(fred, carol) chanPointFC := ht.OpenChannel( - fred, carol, lntemp.OpenChannelParams{ + fred, carol, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -232,7 +232,7 @@ func testSphinxReplayPersistence(ht *lntemp.HarnessTest) { // tests the values in all ChannelConstraints are returned as expected. Once // ListChannels becomes mature, a test against all fields in ListChannels // should be performed. -func testListChannels(ht *lntemp.HarnessTest) { +func testListChannels(ht *lntest.HarnessTest) { const aliceRemoteMaxHtlcs = 50 const bobRemoteMaxHtlcs = 100 @@ -255,7 +255,7 @@ func testListChannels(ht *lntemp.HarnessTest) { chanAmt := btcutil.Amount(100000) pushAmt := btcutil.Amount(1000) - p := lntemp.OpenChannelParams{ + p := lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, MinHtlc: customizedMinHtlc, @@ -337,7 +337,7 @@ func testListChannels(ht *lntemp.HarnessTest) { // testMaxPendingChannels checks that error is returned from remote peer if // max pending channel number was exceeded and that '--maxpendingchannels' flag // exists and works properly. -func testMaxPendingChannels(ht *lntemp.HarnessTest) { +func testMaxPendingChannels(ht *lntest.HarnessTest) { maxPendingChannels := lncfg.DefaultMaxPendingChannels + 1 amount := funding.MaxBtcFundingAmount @@ -362,7 +362,7 @@ func testMaxPendingChannels(ht *lntemp.HarnessTest) { ) for i := 0; i < maxPendingChannels; i++ { stream := ht.OpenChannelAssertStream( - alice, carol, lntemp.OpenChannelParams{ + alice, carol, lntest.OpenChannelParams{ Amt: amount, }, ) @@ -372,7 +372,7 @@ func testMaxPendingChannels(ht *lntemp.HarnessTest) { // Carol exhausted available amount of pending channels, next open // channel request should cause ErrorGeneric to be sent back to Alice. ht.OpenChannelAssertErr( - alice, carol, lntemp.OpenChannelParams{ + alice, carol, lntest.OpenChannelParams{ Amt: amount, }, lnwire.ErrMaxPendingChannels, ) @@ -415,7 +415,7 @@ func testMaxPendingChannels(ht *lntemp.HarnessTest) { // testGarbageCollectLinkNodes tests that we properly garbage collect link // nodes from the database and the set of persistent connections within the // server. -func testGarbageCollectLinkNodes(ht *lntemp.HarnessTest) { +func testGarbageCollectLinkNodes(ht *lntest.HarnessTest) { const chanAmt = 1000000 alice, bob := ht.Alice, ht.Bob @@ -423,7 +423,7 @@ func testGarbageCollectLinkNodes(ht *lntemp.HarnessTest) { // Open a channel between Alice and Bob which will later be // cooperatively closed. coopChanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -435,7 +435,7 @@ func testGarbageCollectLinkNodes(ht *lntemp.HarnessTest) { // Open a channel between Alice and Carol which will later be force // closed. forceCloseChanPoint := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{ + alice, carol, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -447,7 +447,7 @@ func testGarbageCollectLinkNodes(ht *lntemp.HarnessTest) { ht.ConnectNodes(alice, dave) persistentChanPoint := ht.OpenChannel( - alice, dave, lntemp.OpenChannelParams{ + alice, dave, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -527,7 +527,7 @@ func testGarbageCollectLinkNodes(ht *lntemp.HarnessTest) { // testRejectHTLC tests that a node can be created with the flag --rejecthtlc. // This means that the node will reject all forwarded HTLCs but can still // accept direct HTLCs as well as send HTLCs. -func testRejectHTLC(ht *lntemp.HarnessTest) { +func testRejectHTLC(ht *lntest.HarnessTest) { // RejectHTLC // Alice ------> Carol ------> Bob // @@ -548,14 +548,14 @@ func testRejectHTLC(ht *lntemp.HarnessTest) { // Open a channel between Alice and Carol. chanPointAlice := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{ + alice, carol, lntest.OpenChannelParams{ Amt: chanAmt, }, ) // Open a channel between Carol and Bob. chanPointCarol := ht.OpenChannel( - carol, bob, lntemp.OpenChannelParams{ + carol, bob, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -623,14 +623,14 @@ func testRejectHTLC(ht *lntemp.HarnessTest) { // testNodeSignVerify checks that only connected nodes are allowed to perform // signing and verifying messages. -func testNodeSignVerify(ht *lntemp.HarnessTest) { +func testNodeSignVerify(ht *lntest.HarnessTest) { chanAmt := funding.MaxBtcFundingAmount pushAmt := btcutil.Amount(100000) alice, bob := ht.Alice, ht.Bob // Create a channel between alice and bob. aliceBobCh := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, }, @@ -670,11 +670,11 @@ func testNodeSignVerify(ht *lntemp.HarnessTest) { // testAbandonChannel abandons a channel and asserts that it is no longer open // and not in one of the pending closure states. It also verifies that the // abandoned channel is reported as closed with close type 'abandoned'. -func testAbandonChannel(ht *lntemp.HarnessTest) { +func testAbandonChannel(ht *lntest.HarnessTest) { alice, bob := ht.Alice, ht.Bob // First establish a channel between Alice and Bob. - channelParam := lntemp.OpenChannelParams{ + channelParam := lntest.OpenChannelParams{ Amt: funding.MaxBtcFundingAmount, PushAmt: btcutil.Amount(100000), } @@ -741,7 +741,7 @@ func testAbandonChannel(ht *lntemp.HarnessTest) { // wallet into a single target address at the specified fee rate. // // TODO(yy): expand this test to also use P2TR. -func testSweepAllCoins(ht *lntemp.HarnessTest) { +func testSweepAllCoins(ht *lntest.HarnessTest) { // First, we'll make a new node, ainz who'll we'll use to test wallet // sweeping. // @@ -917,7 +917,7 @@ func testSweepAllCoins(ht *lntemp.HarnessTest) { // testListAddresses tests that we get all the addresses and their // corresponding balance correctly. -func testListAddresses(ht *lntemp.HarnessTest) { +func testListAddresses(ht *lntest.HarnessTest) { // First, we'll make a new node - Alice, which will be generating // new addresses. alice := ht.NewNode("Alice", nil) @@ -985,7 +985,7 @@ func testListAddresses(ht *lntemp.HarnessTest) { foundAddresses := 0 for _, addressList := range addressLists.AccountWithAddresses { addresses := addressList.Addresses - derivationPath, err := lntemp.ParseDerivationPath( + derivationPath, err := lntest.ParseDerivationPath( addressList.DerivationPath, ) require.NoError(ht, err) @@ -1023,7 +1023,7 @@ func testListAddresses(ht *lntemp.HarnessTest) { for _, addressList := range addressLists.AccountWithAddresses { addresses := addressList.Addresses - derivationPath, err := lntemp.ParseDerivationPath( + derivationPath, err := lntest.ParseDerivationPath( addressList.DerivationPath, ) require.NoError(ht, err) @@ -1053,7 +1053,7 @@ func testListAddresses(ht *lntemp.HarnessTest) { require.Equal(ht, len(generatedAddr), foundAddresses) } -func assertChannelConstraintsEqual(ht *lntemp.HarnessTest, +func assertChannelConstraintsEqual(ht *lntest.HarnessTest, want, got *lnrpc.ChannelConstraints) { require.Equal(ht, want.CsvDelay, got.CsvDelay, "CsvDelay mismatched") @@ -1076,7 +1076,7 @@ func assertChannelConstraintsEqual(ht *lntemp.HarnessTest, // testSignVerifyMessageWithAddr tests signing and also verifying a signature // on a message with a provided address. -func testSignVerifyMessageWithAddr(ht *lntemp.HarnessTest) { +func testSignVerifyMessageWithAddr(ht *lntest.HarnessTest) { // Using different nodes to sign the message and verify the signature. alice, bob := ht.Alice, ht.Bob diff --git a/itest/lnd_mpp_test.go b/itest/lnd_mpp_test.go index c9d8fd4c2..4f0ed1666 100644 --- a/itest/lnd_mpp_test.go +++ b/itest/lnd_mpp_test.go @@ -7,8 +7,8 @@ import ( "github.com/lightningnetwork/lnd/chainreg" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/routing/route" "github.com/stretchr/testify/require" @@ -16,7 +16,7 @@ import ( // testSendToRouteMultiPath tests that we are able to successfully route a // payment using multiple shards across different paths, by using SendToRoute. -func testSendToRouteMultiPath(ht *lntemp.HarnessTest) { +func testSendToRouteMultiPath(ht *lntest.HarnessTest) { mts := newMppTestScenario(ht) // To ensure the payment goes through separate paths, we'll set a @@ -162,7 +162,7 @@ func testSendToRouteMultiPath(ht *lntemp.HarnessTest) { // It has two standby nodes, alice and bob, and three new nodes, carol, dave, // and eve. type mppTestScenario struct { - ht *lntemp.HarnessTest + ht *lntest.HarnessTest alice, bob, carol, dave, eve *node.HarnessNode nodes []*node.HarnessNode @@ -179,7 +179,7 @@ type mppTestScenario struct { // Alice -- Carol ---- Bob // \ / // \__ Dave ____/ -func newMppTestScenario(ht *lntemp.HarnessTest) *mppTestScenario { +func newMppTestScenario(ht *lntest.HarnessTest) *mppTestScenario { alice, bob := ht.Alice, ht.Bob ht.RestartNodeWithExtraArgs(bob, []string{ "--maxpendingchannels=2", @@ -256,36 +256,36 @@ type mppOpenChannelRequest struct { // // NOTE: all the channels are open together to save blocks mined. func (m *mppTestScenario) openChannels(r *mppOpenChannelRequest) { - reqs := []*lntemp.OpenChannelRequest{ + reqs := []*lntest.OpenChannelRequest{ { Local: m.alice, Remote: m.carol, - Param: lntemp.OpenChannelParams{Amt: r.amtAliceCarol}, + Param: lntest.OpenChannelParams{Amt: r.amtAliceCarol}, }, { Local: m.alice, Remote: m.dave, - Param: lntemp.OpenChannelParams{Amt: r.amtAliceDave}, + Param: lntest.OpenChannelParams{Amt: r.amtAliceDave}, }, { Local: m.carol, Remote: m.bob, - Param: lntemp.OpenChannelParams{Amt: r.amtCarolBob}, + Param: lntest.OpenChannelParams{Amt: r.amtCarolBob}, }, { Local: m.carol, Remote: m.eve, - Param: lntemp.OpenChannelParams{Amt: r.amtCarolEve}, + Param: lntest.OpenChannelParams{Amt: r.amtCarolEve}, }, { Local: m.dave, Remote: m.bob, - Param: lntemp.OpenChannelParams{Amt: r.amtDaveBob}, + Param: lntest.OpenChannelParams{Amt: r.amtDaveBob}, }, { Local: m.eve, Remote: m.bob, - Param: lntemp.OpenChannelParams{Amt: r.amtEveBob}, + Param: lntest.OpenChannelParams{Amt: r.amtEveBob}, }, } diff --git a/itest/lnd_multi-hop-error-propagation_test.go b/itest/lnd_multi-hop-error-propagation_test.go index 009c9769c..63766c738 100644 --- a/itest/lnd_multi-hop-error-propagation_test.go +++ b/itest/lnd_multi-hop-error-propagation_test.go @@ -6,12 +6,12 @@ import ( "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/require" ) -func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { +func testHtlcErrorPropagation(ht *lntest.HarnessTest) { // In this test we wish to exercise the daemon's correct parsing, // handling, and propagation of errors that occur while processing a // multi-hop payment. @@ -39,7 +39,7 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { // and Bob. chanPointAlice := ht.OpenChannel( alice, bob, - lntemp.OpenChannelParams{Amt: chanAmt}, + lntest.OpenChannelParams{Amt: chanAmt}, ) // Next, we'll create a connection from Bob to Carol, and open a @@ -48,14 +48,14 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { // above. const bobChanAmt = funding.MaxBtcFundingAmount chanPointBob := ht.OpenChannel( - bob, carol, lntemp.OpenChannelParams{Amt: chanAmt}, + bob, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) // Ensure that Alice has Carol in her routing table before proceeding. ht.AssertTopologyChannelOpen(alice, chanPointBob) cType := ht.GetChannelCommitType(alice, chanPointAlice) - commitFee := lntemp.CalcStaticFee(cType, 0) + commitFee := lntest.CalcStaticFee(cType, 0) assertBaseBalance := func() { // Alice has opened a channel with Bob with zero push amount, @@ -153,24 +153,24 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { assertAliceAndBob := func() { ht.AssertHtlcEventTypes( aliceEvents, routerrpc.HtlcEvent_SEND, - lntemp.HtlcEventForward, + lntest.HtlcEventForward, ) ht.AssertHtlcEventTypes( aliceEvents, routerrpc.HtlcEvent_SEND, - lntemp.HtlcEventForwardFail, + lntest.HtlcEventForwardFail, ) ht.AssertHtlcEventTypes( bobEvents, routerrpc.HtlcEvent_FORWARD, - lntemp.HtlcEventForward, + lntest.HtlcEventForward, ) ht.AssertHtlcEventTypes( bobEvents, routerrpc.HtlcEvent_FORWARD, - lntemp.HtlcEventForwardFail, + lntest.HtlcEventForwardFail, ) ht.AssertHtlcEventTypes( bobEvents, routerrpc.HtlcEvent_UNKNOWN, - lntemp.HtlcEventFinal, + lntest.HtlcEventFinal, ) } @@ -188,7 +188,7 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { // There's also a final htlc event that gives the final outcome of the // htlc. ht.AssertHtlcEventTypes( - carolEvents, routerrpc.HtlcEvent_UNKNOWN, lntemp.HtlcEventFinal, + carolEvents, routerrpc.HtlcEvent_UNKNOWN, lntest.HtlcEventFinal, ) // The balances of all parties should be the same as initially since @@ -228,7 +228,7 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { // There's also a final htlc event that gives the final outcome of the // htlc. ht.AssertHtlcEventTypes( - carolEvents, routerrpc.HtlcEvent_UNKNOWN, lntemp.HtlcEventFinal, + carolEvents, routerrpc.HtlcEvent_UNKNOWN, lntest.HtlcEventFinal, ) // The balances of all parties should be the same as initially since @@ -273,19 +273,19 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { // settle event and a final htlc event for her receive. ht.AssertHtlcEventTypes( bobEvents, routerrpc.HtlcEvent_SEND, - lntemp.HtlcEventForward, + lntest.HtlcEventForward, ) ht.AssertHtlcEventTypes( bobEvents, routerrpc.HtlcEvent_SEND, - lntemp.HtlcEventSettle, + lntest.HtlcEventSettle, ) ht.AssertHtlcEventTypes( carolEvents, routerrpc.HtlcEvent_RECEIVE, - lntemp.HtlcEventSettle, + lntest.HtlcEventSettle, ) ht.AssertHtlcEventTypes( carolEvents, routerrpc.HtlcEvent_UNKNOWN, - lntemp.HtlcEventFinal, + lntest.HtlcEventFinal, ) amtSent += toSend @@ -316,11 +316,11 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { // Alice should have a forwarding event and a forwarding failure. ht.AssertHtlcEventTypes( aliceEvents, routerrpc.HtlcEvent_SEND, - lntemp.HtlcEventForward, + lntest.HtlcEventForward, ) ht.AssertHtlcEventTypes( aliceEvents, routerrpc.HtlcEvent_SEND, - lntemp.HtlcEventForwardFail, + lntest.HtlcEventForwardFail, ) // Bob should have a link failure because the htlc failed on his @@ -331,7 +331,7 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { // There's also a final htlc event that gives the final outcome of the // htlc. ht.AssertHtlcEventTypes( - bobEvents, routerrpc.HtlcEvent_UNKNOWN, lntemp.HtlcEventFinal, + bobEvents, routerrpc.HtlcEvent_UNKNOWN, lntest.HtlcEventFinal, ) // Generate new invoice to not pay same invoice twice. @@ -362,11 +362,11 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { // Alice should have a forwarding event and subsequent fail. ht.AssertHtlcEventTypes( aliceEvents, routerrpc.HtlcEvent_SEND, - lntemp.HtlcEventForward, + lntest.HtlcEventForward, ) ht.AssertHtlcEventTypes( aliceEvents, routerrpc.HtlcEvent_SEND, - lntemp.HtlcEventForwardFail, + lntest.HtlcEventForwardFail, ) // Bob should have a link failure because he could not find the next @@ -377,7 +377,7 @@ func testHtlcErrorPropagation(ht *lntemp.HarnessTest) { // There's also a final htlc event that gives the final outcome of the // htlc. ht.AssertHtlcEventTypes( - bobEvents, routerrpc.HtlcEvent_UNKNOWN, lntemp.HtlcEventFinal, + bobEvents, routerrpc.HtlcEvent_UNKNOWN, lntest.HtlcEventFinal, ) // Finally, immediately close the channel. This function will also diff --git a/itest/lnd_multi-hop-payments_test.go b/itest/lnd_multi-hop-payments_test.go index 3baec46af..30a446471 100644 --- a/itest/lnd_multi-hop-payments_test.go +++ b/itest/lnd_multi-hop-payments_test.go @@ -5,12 +5,12 @@ import ( "github.com/lightningnetwork/lnd/chainreg" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/stretchr/testify/require" ) -func testMultiHopPayments(ht *lntemp.HarnessTest) { +func testMultiHopPayments(ht *lntest.HarnessTest) { const chanAmt = btcutil.Amount(100000) // As preliminary setup, we'll create two new nodes: Carol and Dave, @@ -43,21 +43,21 @@ func testMultiHopPayments(ht *lntemp.HarnessTest) { // Open a channel with 100k satoshis between Alice and Bob with Alice // being the sole funder of the channel. chanPointAlice := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) // We'll create Dave and establish a channel to Alice. Dave will be // running an older node that requires the legacy onion payload. ht.FundCoins(btcutil.SatoshiPerBitcoin, dave) chanPointDave := ht.OpenChannel( - dave, alice, lntemp.OpenChannelParams{Amt: chanAmt}, + dave, alice, lntest.OpenChannelParams{Amt: chanAmt}, ) // Next, we'll create Carol and establish a channel to from her to // Dave. ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) chanPointCarol := ht.OpenChannel( - carol, dave, lntemp.OpenChannelParams{Amt: chanAmt}, + carol, dave, lntest.OpenChannelParams{Amt: chanAmt}, ) // Create 5 invoices for Bob, which expect a payment from Carol for 1k @@ -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 := lntemp.CalculateMaxHtlc(chanAmt) + maxHtlc := lntest.CalculateMaxHtlc(chanAmt) const aliceBaseFeeSat = 1 const aliceFeeRatePPM = 100000 updateChannelPolicy( @@ -222,7 +222,7 @@ func testMultiHopPayments(ht *lntemp.HarnessTest) { // policy update. // // NOTE: only used in current test. -func updateChannelPolicy(ht *lntemp.HarnessTest, hn *node.HarnessNode, +func updateChannelPolicy(ht *lntest.HarnessTest, hn *node.HarnessNode, chanPoint *lnrpc.ChannelPoint, baseFee int64, feeRate int64, timeLockDelta uint32, maxHtlc uint64, listenerNode *node.HarnessNode) { diff --git a/itest/lnd_multi-hop_test.go b/itest/lnd_multi-hop_test.go index c156cf482..f47031635 100644 --- a/itest/lnd_multi-hop_test.go +++ b/itest/lnd_multi-hop_test.go @@ -12,9 +12,9 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntemp/rpc" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" + "github.com/lightningnetwork/lnd/lntest/rpc" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/routing" "github.com/stretchr/testify/require" @@ -52,12 +52,12 @@ var commitWithZeroConf = []struct { } // caseRunner defines a single test case runner. -type caseRunner func(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode, +type caseRunner func(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) // runMultiHopHtlcClaimTest is a helper method to build test cases based on // different commitment types and zero-conf config and run them. -func runMultiHopHtlcClaimTest(ht *lntemp.HarnessTest, tester caseRunner) { +func runMultiHopHtlcClaimTest(ht *lntest.HarnessTest, tester caseRunner) { for _, typeAndConf := range commitWithZeroConf { typeAndConf := typeAndConf name := fmt.Sprintf("zeroconf=%v/committype=%v", @@ -65,7 +65,7 @@ func runMultiHopHtlcClaimTest(ht *lntemp.HarnessTest, tester caseRunner) { // Create the nodes here so that separate logs will be created // for Alice and Bob. - args := lntemp.NodeArgsForCommitType(typeAndConf.commitType) + args := lntest.NodeArgsForCommitType(typeAndConf.commitType) if typeAndConf.zeroConf { args = append( args, "--protocol.option-scid-alias", @@ -103,11 +103,11 @@ func runMultiHopHtlcClaimTest(ht *lntemp.HarnessTest, tester caseRunner) { // it using the HTLC timeout transaction. Any dust HTLC's should be immediately // canceled backwards. Once the timeout has been reached, then we should sweep // it on-chain, and cancel the HTLC backwards. -func testMultiHopHtlcLocalTimeout(ht *lntemp.HarnessTest) { +func testMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest) { runMultiHopHtlcClaimTest(ht, runMultiHopHtlcLocalTimeout) } -func runMultiHopHtlcLocalTimeout(ht *lntemp.HarnessTest, +func runMultiHopHtlcLocalTimeout(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) { // First, we'll create a three hop network: Alice -> Bob -> Carol, with @@ -171,7 +171,7 @@ func runMultiHopHtlcLocalTimeout(ht *lntemp.HarnessTest, // Bob's force close transaction should now be found in the mempool. If // there are anchors, we also expect Bob's anchor sweep. expectedTxes := 1 - hasAnchors := lntemp.CommitTypeHasAnchors(c) + hasAnchors := lntest.CommitTypeHasAnchors(c) if hasAnchors { expectedTxes = 2 } @@ -272,11 +272,11 @@ func runMultiHopHtlcLocalTimeout(ht *lntemp.HarnessTest, // transaction. In this scenario, the node that sent the outgoing HTLC should // extract the preimage from the sweep transaction, and finish settling the // HTLC backwards into the route. -func testMultiHopReceiverChainClaim(ht *lntemp.HarnessTest) { +func testMultiHopReceiverChainClaim(ht *lntest.HarnessTest) { runMultiHopHtlcClaimTest(ht, runMultiHopReceiverChainClaim) } -func runMultiHopReceiverChainClaim(ht *lntemp.HarnessTest, +func runMultiHopReceiverChainClaim(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) { // First, we'll create a three hop network: Alice -> Bob -> Carol, with @@ -348,7 +348,7 @@ func runMultiHopReceiverChainClaim(ht *lntemp.HarnessTest, // transaction in order to go to the chain and sweep her HTLC. If there // are anchors, Carol also sweeps hers. expectedTxes := 1 - hasAnchors := lntemp.CommitTypeHasAnchors(c) + hasAnchors := lntest.CommitTypeHasAnchors(c) if hasAnchors { expectedTxes = 2 } @@ -470,13 +470,13 @@ func runMultiHopReceiverChainClaim(ht *lntemp.HarnessTest, // commitment on-chain early, then it eventually recognizes this HTLC as one // that's timed out. At this point, the node should timeout the HTLC using the // HTLC timeout transaction, then cancel it backwards as normal. -func testMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest) { +func testMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest) { runMultiHopHtlcClaimTest( ht, runMultiHopLocalForceCloseOnChainHtlcTimeout, ) } -func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest, +func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) { // First, we'll create a three hop network: Alice -> Bob -> Carol, with @@ -517,7 +517,7 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest, // Now that all parties have the HTLC locked in, we'll immediately // force close the Bob -> Carol channel. This should trigger contract // resolution mode for both of them. - hasAnchors := lntemp.CommitTypeHasAnchors(c) + hasAnchors := lntest.CommitTypeHasAnchors(c) stream, _ := ht.CloseChannelAssertPending(bob, bobChanPoint, true) closeTx := ht.AssertStreamChannelForceClosed( bob, bobChanPoint, hasAnchors, stream, @@ -626,13 +626,13 @@ func runMultiHopLocalForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest, // channel, then we properly timeout the HTLC directly on *their* commitment // transaction once the timeout has expired. Once we sweep the transaction, we // should also cancel back the initial HTLC. -func testMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest) { +func testMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest) { runMultiHopHtlcClaimTest( ht, runMultiHopRemoteForceCloseOnChainHtlcTimeout, ) } -func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest, +func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) { // First, we'll create a three hop network: Alice -> Bob -> Carol, with @@ -682,7 +682,7 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest, // transaction. This will let us exercise that Bob is able to sweep the // expired HTLC on Carol's version of the commitment transaction. If // Carol has an anchor, it will be swept too. - hasAnchors := lntemp.CommitTypeHasAnchors(c) + hasAnchors := lntest.CommitTypeHasAnchors(c) closeStream, _ := ht.CloseChannelAssertPending( carol, bobChanPoint, true, ) @@ -782,11 +782,11 @@ func runMultiHopRemoteForceCloseOnChainHtlcTimeout(ht *lntemp.HarnessTest, // we force close a channel with an incoming HTLC, and later find out the // preimage via the witness beacon, we properly settle the HTLC on-chain using // the HTLC success transaction in order to ensure we don't lose any funds. -func testMultiHopHtlcLocalChainClaim(ht *lntemp.HarnessTest) { +func testMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest) { runMultiHopHtlcClaimTest(ht, runMultiHopHtlcLocalChainClaim) } -func runMultiHopHtlcLocalChainClaim(ht *lntemp.HarnessTest, +func runMultiHopHtlcLocalChainClaim(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) { // First, we'll create a three hop network: Alice -> Bob -> Carol, with @@ -840,7 +840,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntemp.HarnessTest, // At this point, Bob decides that he wants to exit the channel // immediately, so he force closes his commitment transaction. - hasAnchors := lntemp.CommitTypeHasAnchors(c) + hasAnchors := lntest.CommitTypeHasAnchors(c) closeStream, _ := ht.CloseChannelAssertPending( bob, aliceChanPoint, true, ) @@ -888,7 +888,7 @@ func runMultiHopHtlcLocalChainClaim(ht *lntemp.HarnessTest, // Carol's commitment transaction should now be in the mempool. If // there is an anchor, Carol will sweep that too. - if lntemp.CommitTypeHasAnchors(c) { + if lntest.CommitTypeHasAnchors(c) { expectedTxes = 2 } ht.Miner.AssertNumTxsInMempool(expectedTxes) @@ -1076,11 +1076,11 @@ func runMultiHopHtlcLocalChainClaim(ht *lntemp.HarnessTest, // we found out the preimage via the witness beacon, we properly settle the // HTLC directly on-chain using the preimage in order to ensure that we don't // lose any funds. -func testMultiHopHtlcRemoteChainClaim(ht *lntemp.HarnessTest) { +func testMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest) { runMultiHopHtlcClaimTest(ht, runMultiHopHtlcRemoteChainClaim) } -func runMultiHopHtlcRemoteChainClaim(ht *lntemp.HarnessTest, +func runMultiHopHtlcRemoteChainClaim(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) { // First, we'll create a three hop network: Alice -> Bob -> Carol, with @@ -1135,7 +1135,7 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntemp.HarnessTest, // Next, Alice decides that she wants to exit the channel, so she'll // immediately force close the channel by broadcast her commitment // transaction. - hasAnchors := lntemp.CommitTypeHasAnchors(c) + hasAnchors := lntest.CommitTypeHasAnchors(c) closeStream, _ := ht.CloseChannelAssertPending( alice, aliceChanPoint, true, ) @@ -1346,11 +1346,11 @@ func runMultiHopHtlcRemoteChainClaim(ht *lntemp.HarnessTest, // resolve them using the second level timeout and success transactions. In // case of anchor channels, the second-level spends can also be aggregated and // properly feebumped, so we'll check that as well. -func testMultiHopHtlcAggregation(ht *lntemp.HarnessTest) { +func testMultiHopHtlcAggregation(ht *lntest.HarnessTest) { runMultiHopHtlcClaimTest(ht, runMultiHopHtlcAggregation) } -func runMultiHopHtlcAggregation(ht *lntemp.HarnessTest, +func runMultiHopHtlcAggregation(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, c lnrpc.CommitmentType, zeroConf bool) { // First, we'll create a three hop network: Alice -> Bob -> Carol. @@ -1489,7 +1489,7 @@ func runMultiHopHtlcAggregation(ht *lntemp.HarnessTest, // Bob's force close transaction should now be found in the mempool. If // there are anchors, we also expect Bob's anchor sweep. - hasAnchors := lntemp.CommitTypeHasAnchors(c) + hasAnchors := lntest.CommitTypeHasAnchors(c) expectedTxes := 1 if hasAnchors { expectedTxes = 2 @@ -1728,7 +1728,7 @@ func runMultiHopHtlcAggregation(ht *lntemp.HarnessTest, } // createThreeHopNetwork creates a topology of `Alice -> Bob -> Carol`. -func createThreeHopNetwork(ht *lntemp.HarnessTest, +func createThreeHopNetwork(ht *lntest.HarnessTest, alice, bob *node.HarnessNode, carolHodl bool, c lnrpc.CommitmentType, zeroConf bool) (*lnrpc.ChannelPoint, *lnrpc.ChannelPoint, *node.HarnessNode) { @@ -1738,7 +1738,7 @@ func createThreeHopNetwork(ht *lntemp.HarnessTest, // We'll create a new node "carol" and have Bob connect to her. // If the carolHodl flag is set, we'll make carol always hold onto the // HTLC, this way it'll force Bob to go to chain to resolve the HTLC. - carolFlags := lntemp.NodeArgsForCommitType(c) + carolFlags := lntest.NodeArgsForCommitType(c) if carolHodl { carolFlags = append(carolFlags, "--hodl.exit-settle") } @@ -1790,7 +1790,7 @@ func createThreeHopNetwork(ht *lntemp.HarnessTest, go acceptChannel(ht.T, true, acceptStream) } - aliceParams := lntemp.OpenChannelParams{ + aliceParams := lntest.OpenChannelParams{ Amt: chanAmt, CommitmentType: c, FundingShim: aliceFundingShim, @@ -1819,7 +1819,7 @@ func createThreeHopNetwork(ht *lntemp.HarnessTest, go acceptChannel(ht.T, true, acceptStream) } - bobParams := lntemp.OpenChannelParams{ + bobParams := lntest.OpenChannelParams{ Amt: chanAmt, CommitmentType: c, FundingShim: bobFundingShim, diff --git a/itest/lnd_network_test.go b/itest/lnd_network_test.go index 9244484a6..725d1b055 100644 --- a/itest/lnd_network_test.go +++ b/itest/lnd_network_test.go @@ -6,8 +6,8 @@ import ( "github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) @@ -15,7 +15,7 @@ import ( // testNetworkConnectionTimeout checks that the connectiontimeout is taking // effect. It creates a node with a small connection timeout value, and // connects it to a non-routable IP address. -func testNetworkConnectionTimeout(ht *lntemp.HarnessTest) { +func testNetworkConnectionTimeout(ht *lntest.HarnessTest) { var ( // testPub is a random public key for testing only. testPub = "0332bda7da70fefe4b6ab92f53b3c4f4ee7999" + @@ -74,7 +74,7 @@ func testNetworkConnectionTimeout(ht *lntemp.HarnessTest) { // testReconnectAfterIPChange verifies that if a persistent inbound node changes // its listening address then it's peer will still be able to reconnect to it. -func testReconnectAfterIPChange(ht *lntemp.HarnessTest) { +func testReconnectAfterIPChange(ht *lntest.HarnessTest) { // In this test, the following network will be set up. A single // dash line represents a peer connection and a double dash line // represents a channel. @@ -126,7 +126,7 @@ func testReconnectAfterIPChange(ht *lntemp.HarnessTest) { // ensures that Charlie receives the node announcement from Alice as // part of the announcement broadcast. chanPoint := ht.OpenChannel( - alice, dave, lntemp.OpenChannelParams{Amt: 1000000}, + alice, dave, lntest.OpenChannelParams{Amt: 1000000}, ) // waitForNodeAnnouncement is a closure used to wait on the given graph @@ -209,7 +209,7 @@ func testReconnectAfterIPChange(ht *lntemp.HarnessTest) { // testAddPeerConfig tests that the "--addpeer" config flag successfully adds // a new peer. -func testAddPeerConfig(ht *lntemp.HarnessTest) { +func testAddPeerConfig(ht *lntest.HarnessTest) { alice := ht.Alice info := alice.RPC.GetInfo() diff --git a/itest/lnd_neutrino_test.go b/itest/lnd_neutrino_test.go index acf56f9d8..2c551362a 100644 --- a/itest/lnd_neutrino_test.go +++ b/itest/lnd_neutrino_test.go @@ -2,13 +2,13 @@ package itest import ( "github.com/lightningnetwork/lnd/lnrpc/neutrinorpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" ) // testNeutrino checks that the neutrino sub-server can fetch compact // block filters, server status and connect to a connected peer. -func testNeutrino(ht *lntemp.HarnessTest) { +func testNeutrino(ht *lntest.HarnessTest) { if !ht.IsNeutrinoBackend() { ht.Skipf("skipping test for non neutrino backends") } diff --git a/itest/lnd_no_etcd_dummy_failover_test.go b/itest/lnd_no_etcd_dummy_failover_test.go index 721b60cf6..2d731febc 100644 --- a/itest/lnd_no_etcd_dummy_failover_test.go +++ b/itest/lnd_no_etcd_dummy_failover_test.go @@ -3,8 +3,8 @@ package itest -import "github.com/lightningnetwork/lnd/lntemp" +import "github.com/lightningnetwork/lnd/lntest" // testEtcdFailover is an empty itest when LND is not compiled with etcd // support. -func testEtcdFailover(ht *lntemp.HarnessTest) {} +func testEtcdFailover(ht *lntest.HarnessTest) {} diff --git a/itest/lnd_nonstd_sweep_test.go b/itest/lnd_nonstd_sweep_test.go index cc2ac7027..a85fbc786 100644 --- a/itest/lnd_nonstd_sweep_test.go +++ b/itest/lnd_nonstd_sweep_test.go @@ -5,11 +5,11 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" ) -func testNonstdSweep(ht *lntemp.HarnessTest) { +func testNonstdSweep(ht *lntest.HarnessTest) { p2shAddr, err := btcutil.NewAddressScriptHash( make([]byte, 1), harnessNetParams, ) @@ -74,7 +74,7 @@ func testNonstdSweep(ht *lntemp.HarnessTest) { } } -func testNonStdSweepInner(ht *lntemp.HarnessTest, address string) { +func testNonStdSweepInner(ht *lntest.HarnessTest, address string) { carol := ht.NewNode("carol", nil) // Give Carol a UTXO so SendCoins will behave as expected. diff --git a/itest/lnd_onchain_test.go b/itest/lnd_onchain_test.go index 2d56d2429..a95b2f325 100644 --- a/itest/lnd_onchain_test.go +++ b/itest/lnd_onchain_test.go @@ -11,8 +11,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/chainrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/sweep" @@ -20,7 +20,7 @@ import ( ) // testChainKit tests ChainKit RPC endpoints. -func testChainKit(ht *lntemp.HarnessTest) { +func testChainKit(ht *lntest.HarnessTest) { // Test functions registered as test cases spin up separate nodes // during execution. By calling sub-test functions as seen below we // avoid the need to start separate nodes. @@ -30,7 +30,7 @@ func testChainKit(ht *lntemp.HarnessTest) { // testChainKitGetBlock ensures that given a block hash, the RPC endpoint // returns the correct target block. -func testChainKitGetBlock(ht *lntemp.HarnessTest) { +func testChainKitGetBlock(ht *lntest.HarnessTest) { // Get best block hash. bestBlockRes := ht.Alice.RPC.GetBestBlock(nil) @@ -58,7 +58,7 @@ func testChainKitGetBlock(ht *lntemp.HarnessTest) { // testChainKitGetBlockHash ensures that given a block height, the RPC endpoint // returns the correct target block hash. -func testChainKitGetBlockHash(ht *lntemp.HarnessTest) { +func testChainKitGetBlockHash(ht *lntest.HarnessTest) { // Get best block hash. bestBlockRes := ht.Alice.RPC.GetBestBlock(nil) @@ -78,13 +78,13 @@ func testChainKitGetBlockHash(ht *lntemp.HarnessTest) { // rate by broadcasting a Child-Pays-For-Parent (CPFP) transaction. // // TODO(wilmer): Add RBF case once btcd supports it. -func testCPFP(ht *lntemp.HarnessTest) { +func testCPFP(ht *lntest.HarnessTest) { runCPFP(ht, ht.Alice, ht.Bob) } // runCPFP ensures that the daemon can bump an unconfirmed transaction's fee // rate by broadcasting a Child-Pays-For-Parent (CPFP) transaction. -func runCPFP(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode) { +func runCPFP(ht *lntest.HarnessTest, alice, bob *node.HarnessNode) { // Skip this test for neutrino, as it's not aware of mempool // transactions. if ht.IsNeutrinoBackend() { @@ -180,9 +180,9 @@ func runCPFP(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode) { // testAnchorReservedValue tests that we won't allow sending transactions when // that would take the value we reserve for anchor fee bumping out of our // wallet. -func testAnchorReservedValue(ht *lntemp.HarnessTest) { +func testAnchorReservedValue(ht *lntest.HarnessTest) { // Start two nodes supporting anchor channels. - args := lntemp.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) + args := lntest.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) // NOTE: we cannot reuse the standby node here as the test requires the // node to start with no UTXOs. @@ -203,7 +203,7 @@ func testAnchorReservedValue(ht *lntemp.HarnessTest) { // wallet, without a change output. This should not be allowed. ht.OpenChannelAssertErr( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, }, lnwallet.ErrReservedValueInvalidated, ) @@ -211,13 +211,13 @@ func testAnchorReservedValue(ht *lntemp.HarnessTest) { // Alice opens a smaller channel. This works since it will have a // change output. chanPoint1 := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt / 4}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt / 4}, ) // If Alice tries to open another anchor channel to Bob, Bob should not // reject it as he is not contributing any funds. chanPoint2 := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt / 4}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt / 4}, ) // Similarly, if Alice tries to open a legacy channel to Bob, Bob @@ -229,7 +229,7 @@ func testAnchorReservedValue(ht *lntemp.HarnessTest) { ht.EnsureConnected(alice, bob) chanPoint3 := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt / 4}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt / 4}, ) chanPoints := []*lnrpc.ChannelPoint{chanPoint1, chanPoint2, chanPoint3} @@ -347,13 +347,13 @@ func testAnchorReservedValue(ht *lntemp.HarnessTest) { // testAnchorThirdPartySpend tests that if we force close a channel, but then // don't sweep the anchor in time and a 3rd party spends it, that we remove any // transactions that are a descendent of that sweep. -func testAnchorThirdPartySpend(ht *lntemp.HarnessTest) { +func testAnchorThirdPartySpend(ht *lntest.HarnessTest) { // First, we'll create two new nodes that both default to anchor // channels. // // NOTE: The itests differ here as anchors is default off vs the normal // lnd binary. - args := lntemp.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) + args := lntest.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) alice := ht.NewNode("Alice", args) defer ht.Shutdown(alice) @@ -374,7 +374,7 @@ func testAnchorThirdPartySpend(ht *lntemp.HarnessTest) { // Open the channel between the two nodes and wait for it to confirm // fully. aliceChanPoint1 := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: firstChanSize, }, ) @@ -493,7 +493,7 @@ func testAnchorThirdPartySpend(ht *lntemp.HarnessTest) { // assertAnchorOutputLost asserts that the anchor output for the given channel // has the state of being lost. -func assertAnchorOutputLost(ht *lntemp.HarnessTest, hn *node.HarnessNode, +func assertAnchorOutputLost(ht *lntest.HarnessTest, hn *node.HarnessNode, chanPoint *lnrpc.ChannelPoint) { cp := ht.OutPointFromChannelPoint(chanPoint) @@ -527,8 +527,8 @@ func assertAnchorOutputLost(ht *lntemp.HarnessTest, hn *node.HarnessNode, // genAnchorSweep generates a "3rd party" anchor sweeping from an existing one. // In practice, we just re-use the existing witness, and track on our own // output producing a 1-in-1-out transaction. -func genAnchorSweep(ht *lntemp.HarnessTest, - aliceAnchor *lntemp.SweptOutput, anchorCsv uint32) *btcutil.Tx { +func genAnchorSweep(ht *lntest.HarnessTest, + aliceAnchor *lntest.SweptOutput, anchorCsv uint32) *btcutil.Tx { // At this point, we have the transaction that Alice used to try to // sweep her anchor. As this is actually just something anyone can diff --git a/itest/lnd_open_channel_test.go b/itest/lnd_open_channel_test.go index 06f8817e1..bfe80cbd1 100644 --- a/itest/lnd_open_channel_test.go +++ b/itest/lnd_open_channel_test.go @@ -10,9 +10,9 @@ import ( "github.com/lightningnetwork/lnd/chainreg" "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntemp/rpc" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" + "github.com/lightningnetwork/lnd/lntest/rpc" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) @@ -20,7 +20,7 @@ import ( // testOpenChannelAfterReorg tests that in the case where we have an open // channel where the funding tx gets reorged out, the channel will no // longer be present in the node's routing table. -func testOpenChannelAfterReorg(ht *lntemp.HarnessTest) { +func testOpenChannelAfterReorg(ht *lntest.HarnessTest) { // Skip test for neutrino, as we cannot disconnect the miner at will. // TODO(halseth): remove when either can disconnect at will, or restart // node with connection to new miner. @@ -33,7 +33,7 @@ func testOpenChannelAfterReorg(ht *lntemp.HarnessTest) { // Set up a new miner that we can use to cause a reorg. tempLogDir := ".tempminerlogs" logFilename := "output-open_channel_reorg-temp_miner.log" - tempMiner := lntemp.NewTempMiner( + tempMiner := lntest.NewTempMiner( ht.Context(), ht.T, tempLogDir, logFilename, ) defer tempMiner.Stop() @@ -68,7 +68,7 @@ func testOpenChannelAfterReorg(ht *lntemp.HarnessTest) { // Create a new channel that requires 1 confs before it's considered // open, then broadcast the funding transaction - params := lntemp.OpenChannelParams{ + params := lntest.OpenChannelParams{ Amt: funding.MaxBtcFundingAmount, Private: true, } @@ -172,7 +172,7 @@ func testOpenChannelAfterReorg(ht *lntemp.HarnessTest) { // ChannelUpdate --> defaultBaseFee, provided FeeRate // 4.) baseFee and feeRate provided to OpenChannelRequest // ChannelUpdate --> provided baseFee, provided feeRate. -func testOpenChannelUpdateFeePolicy(ht *lntemp.HarnessTest) { +func testOpenChannelUpdateFeePolicy(ht *lntest.HarnessTest) { const ( defaultBaseFee = 1000 defaultFeeRate = 1 @@ -182,12 +182,12 @@ func testOpenChannelUpdateFeePolicy(ht *lntemp.HarnessTest) { optionalFeeRate = 1337 ) - defaultMaxHtlc := lntemp.CalculateMaxHtlc(funding.MaxBtcFundingAmount) + defaultMaxHtlc := lntest.CalculateMaxHtlc(funding.MaxBtcFundingAmount) chanAmt := funding.MaxBtcFundingAmount pushAmt := chanAmt / 2 - feeScenarios := []lntemp.OpenChannelParams{ + feeScenarios := []lntest.OpenChannelParams{ { Amt: chanAmt, PushAmt: pushAmt, @@ -259,8 +259,8 @@ func testOpenChannelUpdateFeePolicy(ht *lntemp.HarnessTest) { alice, bob := ht.Alice, ht.Bob - runTestCase := func(ht *lntemp.HarnessTest, - fs lntemp.OpenChannelParams, + runTestCase := func(ht *lntest.HarnessTest, + fs lntest.OpenChannelParams, alicePolicy, bobPolicy *lnrpc.RoutingPolicy) { // Create a channel Alice->Bob. @@ -305,14 +305,14 @@ func testOpenChannelUpdateFeePolicy(ht *lntemp.HarnessTest) { // testBasicChannelCreationAndUpdates tests multiple channel opening and // closing, and ensures that if a node is subscribed to channel updates they // will be received correctly for both cooperative and force closed channels. -func testBasicChannelCreationAndUpdates(ht *lntemp.HarnessTest) { +func testBasicChannelCreationAndUpdates(ht *lntest.HarnessTest) { runBasicChannelCreationAndUpdates(ht, ht.Alice, ht.Bob) } // runBasicChannelCreationAndUpdates tests multiple channel opening and closing, // and ensures that if a node is subscribed to channel updates they will be // received correctly for both cooperative and force closed channels. -func runBasicChannelCreationAndUpdates(ht *lntemp.HarnessTest, +func runBasicChannelCreationAndUpdates(ht *lntest.HarnessTest, alice, bob *node.HarnessNode) { const ( @@ -329,7 +329,7 @@ func runBasicChannelCreationAndUpdates(ht *lntemp.HarnessTest, chanPoints := make([]*lnrpc.ChannelPoint, numChannels) for i := 0; i < numChannels; i++ { chanPoints[i] = ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: amount, }, ) @@ -458,8 +458,8 @@ func runBasicChannelCreationAndUpdates(ht *lntemp.HarnessTest, // assertMinerBlockHeightDelta ensures that tempMiner is 'delta' blocks ahead // of miner. -func assertMinerBlockHeightDelta(ht *lntemp.HarnessTest, - miner, tempMiner *lntemp.HarnessMiner, delta int32) { +func assertMinerBlockHeightDelta(ht *lntest.HarnessTest, + miner, tempMiner *lntest.HarnessMiner, delta int32) { // Ensure the chain lengths are what we expect. err := wait.NoError(func() error { diff --git a/itest/lnd_payment_test.go b/itest/lnd_payment_test.go index 754c7e937..e8986f363 100644 --- a/itest/lnd_payment_test.go +++ b/itest/lnd_payment_test.go @@ -10,13 +10,13 @@ import ( "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) -func testListPayments(ht *lntemp.HarnessTest) { +func testListPayments(ht *lntest.HarnessTest) { alice, bob := ht.Alice, ht.Bob // Check that there are no payments before test. @@ -26,7 +26,7 @@ func testListPayments(ht *lntemp.HarnessTest) { // being the sole funder of the channel. chanAmt := btcutil.Amount(100000) chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) // Get the number of invoices Bob already has. @@ -169,13 +169,13 @@ func testListPayments(ht *lntemp.HarnessTest) { // subsystems trying to update the channel state in the db. We follow this // transition with a payment that updates the commitment state and verify that // the pending state is up to date. -func testPaymentFollowingChannelOpen(ht *lntemp.HarnessTest) { +func testPaymentFollowingChannelOpen(ht *lntest.HarnessTest) { const paymentAmt = btcutil.Amount(100) channelCapacity := paymentAmt * 1000 // We first establish a channel between Alice and Bob. alice, bob := ht.Alice, ht.Bob - p := lntemp.OpenChannelParams{ + p := lntest.OpenChannelParams{ Amt: channelCapacity, } pendingUpdate := ht.OpenChannelAssertPending(alice, bob, p) @@ -196,7 +196,7 @@ func testPaymentFollowingChannelOpen(ht *lntemp.HarnessTest) { ht.MineBlocksAndAssertNumTxes(6, 1) // We verify that the channel is open from both nodes point of view. - chanPoint := lntemp.ChanPointFromPendingUpdate(pendingUpdate) + chanPoint := lntest.ChanPointFromPendingUpdate(pendingUpdate) ht.AssertNodesNumPendingOpenChannels(alice, bob, 0) ht.AssertChannelExists(alice, chanPoint) ht.AssertChannelExists(bob, chanPoint) @@ -224,7 +224,7 @@ func testPaymentFollowingChannelOpen(ht *lntemp.HarnessTest) { } // testAsyncPayments tests the performance of the async payments. -func testAsyncPayments(ht *lntemp.HarnessTest) { +func testAsyncPayments(ht *lntest.HarnessTest) { // We use new nodes here as the benchmark test creates lots of data // which can be costly to be carried on. alice := ht.NewNode("Alice", []string{"--pending-commit-interval=3m"}) @@ -237,7 +237,7 @@ func testAsyncPayments(ht *lntemp.HarnessTest) { } // runAsyncPayments tests the performance of the async payments. -func runAsyncPayments(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode) { +func runAsyncPayments(ht *lntest.HarnessTest, alice, bob *node.HarnessNode) { const paymentAmt = 100 // First establish a channel with a capacity equals to the overall @@ -245,7 +245,7 @@ func runAsyncPayments(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode) { // Alice should send all money from her side to Bob. channelCapacity := btcutil.Amount(paymentAmt * 2000) chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: channelCapacity}, + alice, bob, lntest.OpenChannelParams{Amt: channelCapacity}, ) info := ht.QueryChannelByChanPoint(alice, chanPoint) @@ -322,7 +322,7 @@ func runAsyncPayments(ht *lntemp.HarnessTest, alice, bob *node.HarnessNode) { // testBidirectionalAsyncPayments tests that nodes are able to send the // payments to each other in async manner without blocking. -func testBidirectionalAsyncPayments(ht *lntemp.HarnessTest) { +func testBidirectionalAsyncPayments(ht *lntest.HarnessTest) { const paymentAmt = 1000 // We use new nodes here as the benchmark test creates lots of data @@ -337,7 +337,7 @@ func testBidirectionalAsyncPayments(ht *lntemp.HarnessTest) { // amount of payments, between Alice and Bob, at the end of the test // Alice should send all money from her side to Bob. chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: paymentAmt * 2000, PushAmt: paymentAmt * 1000, }, @@ -419,7 +419,7 @@ func testBidirectionalAsyncPayments(ht *lntemp.HarnessTest) { ht.CloseChannel(alice, chanPoint) } -func testInvoiceSubscriptions(ht *lntemp.HarnessTest) { +func testInvoiceSubscriptions(ht *lntest.HarnessTest) { const chanAmt = btcutil.Amount(500000) alice, bob := ht.Alice, ht.Bob @@ -432,7 +432,7 @@ func testInvoiceSubscriptions(ht *lntemp.HarnessTest) { // Open a channel with 500k satoshis between Alice and Bob with Alice // being the sole funder of the channel. chanPoint := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) // Next create a new invoice for Bob requesting 1k satoshis. @@ -549,7 +549,7 @@ func testInvoiceSubscriptions(ht *lntemp.HarnessTest) { // assertChannelState asserts the channel state by checking the values in // fields, LocalBalance, RemoteBalance and num of PendingHtlcs. -func assertChannelState(ht *lntemp.HarnessTest, hn *node.HarnessNode, +func assertChannelState(ht *lntest.HarnessTest, hn *node.HarnessNode, cp *lnrpc.ChannelPoint, localBalance, remoteBalance int64) { // Get the funding point. @@ -576,6 +576,6 @@ func assertChannelState(ht *lntemp.HarnessTest, hn *node.HarnessNode, } return nil - }, lntemp.DefaultTimeout) + }, lntest.DefaultTimeout) require.NoError(ht, err, "timeout while chekcing for balance") } diff --git a/itest/lnd_psbt_test.go b/itest/lnd_psbt_test.go index 0395a3ac7..d2673f86e 100644 --- a/itest/lnd_psbt_test.go +++ b/itest/lnd_psbt_test.go @@ -20,15 +20,15 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/signrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/stretchr/testify/require" ) // testPsbtChanFunding makes sure a channel can be opened between carol and dave // by using a Partially Signed Bitcoin Transaction that funds the channel // multisig funding output. -func testPsbtChanFunding(ht *lntemp.HarnessTest) { +func testPsbtChanFunding(ht *lntest.HarnessTest) { // First, we'll create two new nodes that we'll use to open channels // between for this test. Dave gets some coins that will be used to // fund the PSBT, just to make sure that Carol has an empty wallet. @@ -41,7 +41,7 @@ func testPsbtChanFunding(ht *lntemp.HarnessTest) { // runPsbtChanFunding makes sure a channel can be opened between carol and dave // by using a Partially Signed Bitcoin Transaction that funds the channel // multisig funding output. -func runPsbtChanFunding(ht *lntemp.HarnessTest, carol, dave *node.HarnessNode) { +func runPsbtChanFunding(ht *lntest.HarnessTest, carol, dave *node.HarnessNode) { const chanSize = funding.MaxBtcFundingAmount ht.FundCoins(btcutil.SatoshiPerBitcoin, dave) @@ -63,7 +63,7 @@ func runPsbtChanFunding(ht *lntemp.HarnessTest, carol, dave *node.HarnessNode) { // by specifying a PSBT shim. We use the NoPublish flag here to avoid // publishing the whole batch TX too early. chanUpdates, tempPsbt := ht.OpenChannelPsbt( - carol, dave, lntemp.OpenChannelParams{ + carol, dave, lntest.OpenChannelParams{ Amt: chanSize, FundingShim: &lnrpc.FundingShim{ Shim: &lnrpc.FundingShim_PsbtShim{ @@ -80,7 +80,7 @@ func runPsbtChanFunding(ht *lntemp.HarnessTest, carol, dave *node.HarnessNode) { // Alice. We will publish the batch TX once this channel funding is // complete. chanUpdates2, psbtBytes2 := ht.OpenChannelPsbt( - carol, alice, lntemp.OpenChannelParams{ + carol, alice, lntest.OpenChannelParams{ Amt: chanSize, FundingShim: &lnrpc.FundingShim{ Shim: &lnrpc.FundingShim_PsbtShim{ @@ -230,7 +230,7 @@ func runPsbtChanFunding(ht *lntemp.HarnessTest, carol, dave *node.HarnessNode) { // and dave by using a Partially Signed Bitcoin Transaction that funds the // channel multisig funding output and is fully funded by an external third // party. -func testPsbtChanFundingExternal(ht *lntemp.HarnessTest) { +func testPsbtChanFundingExternal(ht *lntest.HarnessTest) { const chanSize = funding.MaxBtcFundingAmount // First, we'll create two new nodes that we'll use to open channels @@ -257,7 +257,7 @@ func testPsbtChanFundingExternal(ht *lntemp.HarnessTest) { // by specifying a PSBT shim. We use the NoPublish flag here to avoid // publishing the whole batch TX too early. chanUpdates, tempPsbt := ht.OpenChannelPsbt( - carol, dave, lntemp.OpenChannelParams{ + carol, dave, lntest.OpenChannelParams{ Amt: chanSize, FundingShim: &lnrpc.FundingShim{ Shim: &lnrpc.FundingShim_PsbtShim{ @@ -274,7 +274,7 @@ func testPsbtChanFundingExternal(ht *lntemp.HarnessTest) { // Alice. We will publish the batch TX once this channel funding is // complete. chanUpdates2, psbtBytes2 := ht.OpenChannelPsbt( - carol, alice, lntemp.OpenChannelParams{ + carol, alice, lntest.OpenChannelParams{ Amt: chanSize, FundingShim: &lnrpc.FundingShim{ Shim: &lnrpc.FundingShim_PsbtShim{ @@ -412,10 +412,10 @@ func testPsbtChanFundingExternal(ht *lntemp.HarnessTest) { // the wallet of both nodes are empty and one of them uses PSBT and an external // wallet to fund the channel while creating reserve output in the same // transaction. -func testPsbtChanFundingSingleStep(ht *lntemp.HarnessTest) { +func testPsbtChanFundingSingleStep(ht *lntest.HarnessTest) { const chanSize = funding.MaxBtcFundingAmount - args := lntemp.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) + args := lntest.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) // First, we'll create two new nodes that we'll use to open channels // between for this test. But in this case both nodes have an empty @@ -453,7 +453,7 @@ func testPsbtChanFundingSingleStep(ht *lntemp.HarnessTest) { // Now that we have the pending channel ID, Carol will open the channel // by specifying a PSBT shim. chanUpdates, tempPsbt := ht.OpenChannelPsbt( - carol, dave, lntemp.OpenChannelParams{ + carol, dave, lntest.OpenChannelParams{ Amt: chanSize, FundingShim: &lnrpc.FundingShim{ Shim: &lnrpc.FundingShim_PsbtShim{ @@ -575,7 +575,7 @@ func testPsbtChanFundingSingleStep(ht *lntemp.HarnessTest) { } // testSignPsbt tests that the SignPsbt RPC works correctly. -func testSignPsbt(ht *lntemp.HarnessTest) { +func testSignPsbt(ht *lntest.HarnessTest) { runSignPsbtSegWitV0P2WKH(ht, ht.Alice) runSignPsbtSegWitV0NP2WKH(ht, ht.Alice) runSignPsbtSegWitV1KeySpendBip86(ht, ht.Alice) @@ -590,7 +590,7 @@ func testSignPsbt(ht *lntemp.HarnessTest) { // runSignPsbtSegWitV0P2WKH tests that the SignPsbt RPC works correctly for a // SegWit v0 p2wkh input. -func runSignPsbtSegWitV0P2WKH(ht *lntemp.HarnessTest, alice *node.HarnessNode) { +func runSignPsbtSegWitV0P2WKH(ht *lntest.HarnessTest, alice *node.HarnessNode) { // We test that we can sign a PSBT that spends funds from an input that // the wallet doesn't know about. To set up that test case, we first // derive an address manually that the wallet won't be watching on @@ -669,7 +669,7 @@ func runSignPsbtSegWitV0P2WKH(ht *lntemp.HarnessTest, alice *node.HarnessNode) { // runSignPsbtSegWitV0NP2WKH tests that the SignPsbt RPC works correctly for a // SegWit v0 np2wkh input. -func runSignPsbtSegWitV0NP2WKH(ht *lntemp.HarnessTest, +func runSignPsbtSegWitV0NP2WKH(ht *lntest.HarnessTest, alice *node.HarnessNode) { // We test that we can sign a PSBT that spends funds from an input that @@ -758,7 +758,7 @@ func runSignPsbtSegWitV0NP2WKH(ht *lntemp.HarnessTest, // runSignPsbtSegWitV1KeySpendBip86 tests that the SignPsbt RPC works correctly // for a SegWit v1 p2tr key spend BIP-0086 input. -func runSignPsbtSegWitV1KeySpendBip86(ht *lntemp.HarnessTest, +func runSignPsbtSegWitV1KeySpendBip86(ht *lntest.HarnessTest, alice *node.HarnessNode) { // Derive a key we can use for signing. @@ -802,7 +802,7 @@ func runSignPsbtSegWitV1KeySpendBip86(ht *lntemp.HarnessTest, // runSignPsbtSegWitV1KeySpendRootHash tests that the SignPsbt RPC works // correctly for a SegWit v1 p2tr key spend that also commits to a script tree // root hash. -func runSignPsbtSegWitV1KeySpendRootHash(ht *lntemp.HarnessTest, +func runSignPsbtSegWitV1KeySpendRootHash(ht *lntest.HarnessTest, alice *node.HarnessNode) { // Derive a key we can use for signing. @@ -849,7 +849,7 @@ func runSignPsbtSegWitV1KeySpendRootHash(ht *lntemp.HarnessTest, // runSignPsbtSegWitV1ScriptSpend tests that the SignPsbt RPC works correctly // for a SegWit v1 p2tr script spend. -func runSignPsbtSegWitV1ScriptSpend(ht *lntemp.HarnessTest, +func runSignPsbtSegWitV1ScriptSpend(ht *lntest.HarnessTest, alice *node.HarnessNode) { // Derive a key we can use for signing. @@ -910,7 +910,7 @@ func runSignPsbtSegWitV1ScriptSpend(ht *lntemp.HarnessTest, // runFundAndSignPsbt makes sure we can sign PSBTs that were funded by our // internal wallet. -func runFundAndSignPsbt(ht *lntemp.HarnessTest, alice *node.HarnessNode) { +func runFundAndSignPsbt(ht *lntest.HarnessTest, alice *node.HarnessNode) { alice.AddToLogf("================ runFundAndSignPsbt ===============") // We'll be using a "main" address where we send the funds to and from @@ -964,7 +964,7 @@ func runFundAndSignPsbt(ht *lntemp.HarnessTest, alice *node.HarnessNode) { // assertPsbtSpend creates an output with the given pkScript on chain and then // attempts to create a sweep transaction that is signed using the SignPsbt RPC // that spends that output again. -func assertPsbtSpend(ht *lntemp.HarnessTest, alice *node.HarnessNode, +func assertPsbtSpend(ht *lntest.HarnessTest, alice *node.HarnessNode, pkScript []byte, decorateUnsigned func(*psbt.Packet), verifySigned func(*psbt.Packet)) { @@ -1073,7 +1073,7 @@ func assertPsbtSpend(ht *lntemp.HarnessTest, alice *node.HarnessNode, // assertPsbtFundSignSpend funds a PSBT from the internal wallet and then // attempts to sign it by using the SignPsbt or FinalizePsbt method. -func assertPsbtFundSignSpend(ht *lntemp.HarnessTest, alice *node.HarnessNode, +func assertPsbtFundSignSpend(ht *lntest.HarnessTest, alice *node.HarnessNode, fundOutputs map[string]uint64, changeType walletrpc.ChangeAddressType, useFinalize bool) { @@ -1148,7 +1148,7 @@ func assertPsbtFundSignSpend(ht *lntemp.HarnessTest, alice *node.HarnessNode, // assertChangeScriptType checks if the given script has the right type given // the change address type we used in FundPsbt. By default, the script should // be a P2WPKH one. -func assertChangeScriptType(ht *lntemp.HarnessTest, script []byte, +func assertChangeScriptType(ht *lntest.HarnessTest, script []byte, fundChangeType walletrpc.ChangeAddressType) { switch fundChangeType { @@ -1162,7 +1162,7 @@ func assertChangeScriptType(ht *lntemp.HarnessTest, script []byte, // deriveInternalKey derives a signing key and returns its descriptor, full // derivation path and parsed public key. -func deriveInternalKey(ht *lntemp.HarnessTest, +func deriveInternalKey(ht *lntest.HarnessTest, alice *node.HarnessNode) (*signrpc.KeyDescriptor, *btcec.PublicKey, []uint32) { @@ -1221,7 +1221,7 @@ func receiveChanUpdate(ctx context.Context, // sendAllCoinsToAddrType sweeps all coins from the wallet and sends them to a // new address of the given type. -func sendAllCoinsToAddrType(ht *lntemp.HarnessTest, +func sendAllCoinsToAddrType(ht *lntest.HarnessTest, hn *node.HarnessNode, addrType lnrpc.AddressType) { resp := hn.RPC.NewAddress(&lnrpc.NewAddressRequest{ diff --git a/itest/lnd_recovery_test.go b/itest/lnd_recovery_test.go index 4ba521912..ef251f042 100644 --- a/itest/lnd_recovery_test.go +++ b/itest/lnd_recovery_test.go @@ -15,8 +15,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/signrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/stretchr/testify/require" @@ -24,7 +24,7 @@ import ( // testGetRecoveryInfo checks whether lnd gives the right information about // the wallet recovery process. -func testGetRecoveryInfo(ht *lntemp.HarnessTest) { +func testGetRecoveryInfo(ht *lntest.HarnessTest) { // First, create a new node with strong passphrase and grab the mnemonic // used for key derivation. This will bring up Carol with an empty // wallet, and such that she is synced up. @@ -94,7 +94,7 @@ func testGetRecoveryInfo(ht *lntemp.HarnessTest) { // when providing a valid aezeed that owns outputs on the chain. This test // performs multiple restorations using the same seed and various recovery // windows to ensure we detect funds properly. -func testOnchainFundRecovery(ht *lntemp.HarnessTest) { +func testOnchainFundRecovery(ht *lntest.HarnessTest) { // First, create a new node with strong passphrase and grab the mnemonic // used for key derivation. This will bring up Carol with an empty // wallet, and such that she is synced up. @@ -321,7 +321,7 @@ func testOnchainFundRecovery(ht *lntemp.HarnessTest) { // The fix in the wallet is simple: In step 6, don't detect addresses from // internal scopes while re-scanning to be in line with the logic in other areas // of the wallet code. -func testRescanAddressDetection(ht *lntemp.HarnessTest) { +func testRescanAddressDetection(ht *lntest.HarnessTest) { // We start off by creating a new node with the wallet re-scan flag // enabled. This won't have any effect on the first startup but will // come into effect after we re-start the node. diff --git a/itest/lnd_remote_signer_test.go b/itest/lnd_remote_signer_test.go index 8b7a2b6a6..45f806cfd 100644 --- a/itest/lnd_remote_signer_test.go +++ b/itest/lnd_remote_signer_test.go @@ -11,8 +11,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/signrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/stretchr/testify/require" ) @@ -55,24 +55,24 @@ var ( // testRemoteSigner tests that a watch-only wallet can use a remote signing // wallet to perform any signing or ECDH operations. -func testRemoteSigner(ht *lntemp.HarnessTest) { +func testRemoteSigner(ht *lntest.HarnessTest) { type testCase struct { name string randomSeed bool sendCoins bool - fn func(tt *lntemp.HarnessTest, + fn func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) } subTests := []testCase{{ name: "random seed", randomSeed: true, - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { // Nothing more to test here. }, }, { name: "account import", - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { runWalletImportAccountScenario( tt, walletrpc.AddressType_WITNESS_PUBKEY_HASH, carol, wo, @@ -81,36 +81,36 @@ func testRemoteSigner(ht *lntemp.HarnessTest) { }, { name: "basic channel open close", sendCoins: true, - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { runBasicChannelCreationAndUpdates(tt, wo, carol) }, }, { name: "channel funding input types", sendCoins: false, - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { runChannelFundingInputTypes(tt, carol, wo) }, }, { name: "async payments", sendCoins: true, - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { runAsyncPayments(tt, wo, carol) }, }, { name: "shared key", - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { runDeriveSharedKey(tt, wo) }, }, { name: "cpfp", sendCoins: true, - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { runCPFP(tt, wo, carol) }, }, { name: "psbt", randomSeed: true, - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { runPsbtChanFunding(tt, carol, wo) runSignPsbtSegWitV0P2WKH(tt, wo) runSignPsbtSegWitV1KeySpendBip86(tt, wo) @@ -125,20 +125,20 @@ func testRemoteSigner(ht *lntemp.HarnessTest) { }, { name: "sign output raw", sendCoins: true, - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { runSignOutputRaw(tt, wo) }, }, { name: "sign verify msg", sendCoins: true, - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { runSignVerifyMessage(tt, wo) }, }, { name: "taproot", sendCoins: true, randomSeed: true, - fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) { + fn: func(tt *lntest.HarnessTest, wo, carol *node.HarnessNode) { testTaprootSendCoinsKeySpendBip86(tt, wo) testTaprootComputeInputScriptKeySpendBip86(tt, wo) testTaprootSignOutputRawScriptSpend(tt, wo) @@ -162,7 +162,7 @@ func testRemoteSigner(ht *lntemp.HarnessTest) { }, }} - prepareTest := func(st *lntemp.HarnessTest, + prepareTest := func(st *lntest.HarnessTest, subTest testCase) (*node.HarnessNode, *node.HarnessNode, *node.HarnessNode) { diff --git a/itest/lnd_res_handoff_test.go b/itest/lnd_res_handoff_test.go index a18d2fce0..e6c10b48f 100644 --- a/itest/lnd_res_handoff_test.go +++ b/itest/lnd_res_handoff_test.go @@ -5,13 +5,13 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" ) // testResHandoff tests that the contractcourt is able to properly hand-off // resolution messages to the switch. -func testResHandoff(ht *lntemp.HarnessTest) { +func testResHandoff(ht *lntest.HarnessTest) { const ( chanAmt = btcutil.Amount(1000000) paymentAmt = 50000 @@ -22,7 +22,7 @@ func testResHandoff(ht *lntemp.HarnessTest) { // First we'll create a channel between Alice and Bob. ht.EnsureConnected(alice, bob) - params := lntemp.OpenChannelParams{Amt: chanAmt} + params := lntest.OpenChannelParams{Amt: chanAmt} chanPointAlice := ht.OpenChannel(alice, bob, params) // Create a new node Carol that will be in hodl mode. This is used to diff --git a/itest/lnd_rest_api_test.go b/itest/lnd_rest_api_test.go index 43aff6110..3a9674a35 100644 --- a/itest/lnd_rest_api_test.go +++ b/itest/lnd_rest_api_test.go @@ -23,8 +23,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lnrpc/verrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/stretchr/testify/require" ) @@ -56,7 +56,7 @@ var ( // testRestAPI tests that the most important features of the REST API work // correctly. -func testRestAPI(ht *lntemp.HarnessTest) { +func testRestAPI(ht *lntest.HarnessTest) { testCases := []struct { name string run func(*testing.T, *node.HarnessNode, *node.HarnessNode) @@ -201,7 +201,7 @@ func testRestAPI(ht *lntemp.HarnessTest) { }} wsTestCases := []struct { name string - run func(ht *lntemp.HarnessTest) + run func(ht *lntest.HarnessTest) }{{ name: "websocket subscription", run: wsTestCaseSubscription, @@ -243,7 +243,7 @@ func testRestAPI(ht *lntemp.HarnessTest) { } } -func wsTestCaseSubscription(ht *lntemp.HarnessTest) { +func wsTestCaseSubscription(ht *lntest.HarnessTest) { // Find out the current best block so we can subscribe to the next one. hash, height := ht.Miner.GetBestBlock() @@ -317,7 +317,7 @@ func wsTestCaseSubscription(ht *lntemp.HarnessTest) { } } -func wsTestCaseSubscriptionMacaroon(ht *lntemp.HarnessTest) { +func wsTestCaseSubscriptionMacaroon(ht *lntest.HarnessTest) { // Find out the current best block so we can subscribe to the next one. hash, height := ht.Miner.GetBestBlock() @@ -407,7 +407,7 @@ func wsTestCaseSubscriptionMacaroon(ht *lntemp.HarnessTest) { } } -func wsTestCaseBiDirectionalSubscription(ht *lntemp.HarnessTest) { +func wsTestCaseBiDirectionalSubscription(ht *lntest.HarnessTest) { initialRequest := &lnrpc.ChannelAcceptResponse{} url := "/v1/channels/acceptor" @@ -530,7 +530,7 @@ func wsTestCaseBiDirectionalSubscription(ht *lntemp.HarnessTest) { const numChannels = 3 for i := 0; i < numChannels; i++ { chanPoint := ht.OpenChannel( - bob, alice, lntemp.OpenChannelParams{Amt: 500000}, + bob, alice, lntest.OpenChannelParams{Amt: 500000}, ) defer ht.CloseChannel(bob, chanPoint) @@ -545,7 +545,7 @@ func wsTestCaseBiDirectionalSubscription(ht *lntemp.HarnessTest) { } } -func wsTestPingPongTimeout(ht *lntemp.HarnessTest) { +func wsTestPingPongTimeout(ht *lntest.HarnessTest) { initialRequest := &lnrpc.InvoiceSubscription{ AddIndex: 1, SettleIndex: 1, } diff --git a/itest/lnd_revocation_test.go b/itest/lnd_revocation_test.go index 0184d634b..4ec04a11c 100644 --- a/itest/lnd_revocation_test.go +++ b/itest/lnd_revocation_test.go @@ -12,7 +12,7 @@ import ( "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/wtclientrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) @@ -20,7 +20,7 @@ import ( // testRevokedCloseRetribution tests that Carol is able carry out // retribution in the event that she fails immediately after detecting Bob's // breach txn in the mempool. -func testRevokedCloseRetribution(ht *lntemp.HarnessTest) { +func testRevokedCloseRetribution(ht *lntest.HarnessTest) { const ( chanAmt = funding.MaxBtcFundingAmount paymentAmt = 10000 @@ -50,7 +50,7 @@ func testRevokedCloseRetribution(ht *lntemp.HarnessTest) { // closure by Bob, we'll first open up a channel between them with a // 0.5 BTC value. chanPoint := ht.OpenChannel( - carol, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + carol, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) // With the channel open, we'll create a few invoices for Bob that @@ -165,7 +165,7 @@ func testRevokedCloseRetribution(ht *lntemp.HarnessTest) { // testRevokedCloseRetributionZeroValueRemoteOutput tests that Dave is able // carry out retribution in the event that he fails in state where the remote // commitment output has zero-value. -func testRevokedCloseRetributionZeroValueRemoteOutput(ht *lntemp.HarnessTest) { +func testRevokedCloseRetributionZeroValueRemoteOutput(ht *lntest.HarnessTest) { const ( chanAmt = funding.MaxBtcFundingAmount paymentAmt = 10000 @@ -198,7 +198,7 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(ht *lntemp.HarnessTest) { // closure by Carol, we'll first open up a channel between them with a // 0.5 BTC value. chanPoint := ht.OpenChannel( - dave, carol, lntemp.OpenChannelParams{Amt: chanAmt}, + dave, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) // With the channel open, we'll create a few invoices for Carol that @@ -297,7 +297,7 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(ht *lntemp.HarnessTest) { // testRevokedCloseRetributionRemoteHodl tests that Dave properly responds to a // channel breach made by the remote party, specifically in the case that the // remote party breaches before settling extended HTLCs. -func testRevokedCloseRetributionRemoteHodl(ht *lntemp.HarnessTest) { +func testRevokedCloseRetributionRemoteHodl(ht *lntest.HarnessTest) { const ( chanAmt = funding.MaxBtcFundingAmount pushAmt = 200000 @@ -332,7 +332,7 @@ func testRevokedCloseRetributionRemoteHodl(ht *lntemp.HarnessTest) { // by Carol, we'll first open up a channel between them with a // funding.MaxBtcFundingAmount (2^24) satoshis value. chanPoint := ht.OpenChannel( - dave, carol, lntemp.OpenChannelParams{ + dave, carol, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, }, @@ -577,7 +577,7 @@ func testRevokedCloseRetributionRemoteHodl(ht *lntemp.HarnessTest) { // trigger a breach. Carol is kept offline throughout the process and the test // asserts that Willy responds by broadcasting the justice transaction on // Carol's behalf sweeping her funds without a reward. -func testRevokedCloseRetributionAltruistWatchtower(ht *lntemp.HarnessTest) { +func testRevokedCloseRetributionAltruistWatchtower(ht *lntest.HarnessTest) { testCases := []struct { name string anchors bool @@ -591,7 +591,7 @@ func testRevokedCloseRetributionAltruistWatchtower(ht *lntemp.HarnessTest) { for _, tc := range testCases { tc := tc - testFunc := func(ht *lntemp.HarnessTest) { + testFunc := func(ht *lntest.HarnessTest) { testRevokedCloseRetributionAltruistWatchtowerCase( ht, tc.anchors, ) @@ -600,7 +600,7 @@ func testRevokedCloseRetributionAltruistWatchtower(ht *lntemp.HarnessTest) { success := ht.Run(tc.name, func(tt *testing.T) { st := ht.Subtest(tt) - st.RunTestCase(&lntemp.TestCase{ + st.RunTestCase(&lntest.TestCase{ Name: tc.name, TestFunc: testFunc, }) @@ -618,7 +618,7 @@ func testRevokedCloseRetributionAltruistWatchtower(ht *lntemp.HarnessTest) { } } -func testRevokedCloseRetributionAltruistWatchtowerCase(ht *lntemp.HarnessTest, +func testRevokedCloseRetributionAltruistWatchtowerCase(ht *lntest.HarnessTest, anchors bool) { const ( @@ -695,7 +695,7 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(ht *lntemp.HarnessTest, // In order to test Dave's response to an uncooperative channel // closure by Carol, we'll first open up a channel between them with a // 0.5 BTC value. - params := lntemp.OpenChannelParams{ + params := lntest.OpenChannelParams{ Amt: 3 * (chanAmt / 4), PushAmt: chanAmt / 4, } diff --git a/itest/lnd_routing_test.go b/itest/lnd_routing_test.go index 7dd9ef299..4d6746279 100644 --- a/itest/lnd_routing_test.go +++ b/itest/lnd_routing_test.go @@ -10,8 +10,8 @@ import ( "github.com/lightningnetwork/lnd/chainreg" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/require" @@ -65,7 +65,7 @@ var singleHopSendToRouteCases = []singleHopSendToRouteCase{ // by feeding the route back into the various SendToRoute RPC methods. Here we // test all three SendToRoute endpoints, forcing each to perform both a regular // payment and an MPP payment. -func testSingleHopSendToRoute(ht *lntemp.HarnessTest) { +func testSingleHopSendToRoute(ht *lntest.HarnessTest) { for _, test := range singleHopSendToRouteCases { test := test @@ -76,7 +76,7 @@ func testSingleHopSendToRoute(ht *lntemp.HarnessTest) { } } -func testSingleHopSendToRouteCase(ht *lntemp.HarnessTest, +func testSingleHopSendToRouteCase(ht *lntest.HarnessTest, test singleHopSendToRouteCase) { const chanAmt = btcutil.Amount(100000) @@ -97,7 +97,7 @@ func testSingleHopSendToRouteCase(ht *lntemp.HarnessTest, // Open a channel with 100k satoshis between Carol and Dave with Carol // being the sole funder of the channel. chanPointCarol := ht.OpenChannel( - carol, dave, lntemp.OpenChannelParams{Amt: chanAmt}, + carol, dave, lntest.OpenChannelParams{Amt: chanAmt}, ) defer ht.CloseChannel(carol, chanPointCarol) @@ -289,7 +289,7 @@ func testSingleHopSendToRouteCase(ht *lntemp.HarnessTest, // // We'll query the daemon for routes from Alice to Carol and then // send payments through the routes. -func testMultiHopSendToRoute(ht *lntemp.HarnessTest) { +func testMultiHopSendToRoute(ht *lntest.HarnessTest) { ht.Run("with cache", func(tt *testing.T) { st := ht.Subtest(tt) runMultiHopSendToRoute(st, true) @@ -309,7 +309,7 @@ func testMultiHopSendToRoute(ht *lntemp.HarnessTest) { // // We'll query the daemon for routes from Alice to Carol and then // send payments through the routes. -func runMultiHopSendToRoute(ht *lntemp.HarnessTest, useGraphCache bool) { +func runMultiHopSendToRoute(ht *lntest.HarnessTest, useGraphCache bool) { var opts []string if !useGraphCache { opts = append(opts, "--db.no-graph-cache") @@ -325,7 +325,7 @@ func runMultiHopSendToRoute(ht *lntemp.HarnessTest, useGraphCache bool) { // Open a channel with 100k satoshis between Alice and Bob with Alice // being the sole funder of the channel. chanPointAlice := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) defer ht.CloseChannel(alice, chanPointAlice) @@ -337,7 +337,7 @@ func runMultiHopSendToRoute(ht *lntemp.HarnessTest, useGraphCache bool) { ht.ConnectNodes(carol, bob) chanPointBob := ht.OpenChannel( - bob, carol, lntemp.OpenChannelParams{Amt: chanAmt}, + bob, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) defer ht.CloseChannel(carol, chanPointBob) @@ -407,14 +407,14 @@ func runMultiHopSendToRoute(ht *lntemp.HarnessTest, useGraphCache bool) { // testSendToRouteErrorPropagation tests propagation of errors that occur // while processing a multi-hop payment through an unknown route. -func testSendToRouteErrorPropagation(ht *lntemp.HarnessTest) { +func testSendToRouteErrorPropagation(ht *lntest.HarnessTest) { const chanAmt = btcutil.Amount(100000) // Open a channel with 100k satoshis between Alice and Bob with Alice // being the sole funder of the channel. alice, bob := ht.Alice, ht.Bob chanPointAlice := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) // Create a new nodes (Carol and Charlie), load her with some funds, @@ -432,7 +432,7 @@ func testSendToRouteErrorPropagation(ht *lntemp.HarnessTest) { ht.FundCoins(btcutil.SatoshiPerBitcoin, charlie) ht.ConnectNodes(carol, charlie) - ht.OpenChannel(carol, charlie, lntemp.OpenChannelParams{Amt: chanAmt}) + ht.OpenChannel(carol, charlie, lntest.OpenChannelParams{Amt: chanAmt}) // Query routes from Carol to Charlie which will be an invalid route // for Alice -> Bob. @@ -476,7 +476,7 @@ func testSendToRouteErrorPropagation(ht *lntemp.HarnessTest) { // testPrivateChannels tests that a private channel can be used for // routing by the two endpoints of the channel, but is not known by // the rest of the nodes in the graph. -func testPrivateChannels(ht *lntemp.HarnessTest) { +func testPrivateChannels(ht *lntest.HarnessTest) { const chanAmt = btcutil.Amount(100000) // We create the following topology: @@ -493,7 +493,7 @@ func testPrivateChannels(ht *lntemp.HarnessTest) { // Open a channel with 200k satoshis between Alice and Bob. alice, bob := ht.Alice, ht.Bob chanPointAlice := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt * 2}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt * 2}, ) // Create Dave, and a channel to Alice of 100k. @@ -502,7 +502,7 @@ func testPrivateChannels(ht *lntemp.HarnessTest) { ht.FundCoins(btcutil.SatoshiPerBitcoin, dave) chanPointDave := ht.OpenChannel( - dave, alice, lntemp.OpenChannelParams{Amt: chanAmt}, + dave, alice, lntest.OpenChannelParams{Amt: chanAmt}, ) // Next, we'll create Carol and establish a channel from her to @@ -512,14 +512,14 @@ func testPrivateChannels(ht *lntemp.HarnessTest) { ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) chanPointCarol := ht.OpenChannel( - carol, dave, lntemp.OpenChannelParams{Amt: chanAmt}, + carol, dave, lntest.OpenChannelParams{Amt: chanAmt}, ) // Now create a _private_ channel directly between Carol and // Alice of 100k. ht.ConnectNodes(carol, alice) chanPointPrivate := ht.OpenChannel( - carol, alice, lntemp.OpenChannelParams{ + carol, alice, lntest.OpenChannelParams{ Amt: chanAmt, Private: true, }, @@ -602,7 +602,7 @@ func testPrivateChannels(ht *lntemp.HarnessTest) { // testInvoiceRoutingHints tests that the routing hints for an invoice are // created properly. -func testInvoiceRoutingHints(ht *lntemp.HarnessTest) { +func testInvoiceRoutingHints(ht *lntest.HarnessTest) { const chanAmt = btcutil.Amount(100000) // Throughout this test, we'll be opening a channel between Alice and @@ -615,7 +615,7 @@ func testInvoiceRoutingHints(ht *lntemp.HarnessTest) { // invoice's payment. alice, bob := ht.Alice, ht.Bob chanPointBob := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: chanAmt / 2, Private: true, @@ -629,7 +629,7 @@ func testInvoiceRoutingHints(ht *lntemp.HarnessTest) { ht.ConnectNodes(alice, carol) chanPointCarol := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{ + alice, carol, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: chanAmt / 2, }, @@ -642,7 +642,7 @@ func testInvoiceRoutingHints(ht *lntemp.HarnessTest) { // that wish to stay unadvertised. ht.ConnectNodes(bob, carol) chanPointBobCarol := ht.OpenChannel( - bob, carol, lntemp.OpenChannelParams{ + bob, carol, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: chanAmt / 2, }, @@ -656,7 +656,7 @@ func testInvoiceRoutingHints(ht *lntemp.HarnessTest) { ht.ConnectNodes(alice, dave) chanPointDave := ht.OpenChannel( - alice, dave, lntemp.OpenChannelParams{ + alice, dave, lntest.OpenChannelParams{ Amt: chanAmt, Private: true, }, @@ -669,7 +669,7 @@ func testInvoiceRoutingHints(ht *lntemp.HarnessTest) { eve := ht.NewNode("Eve", nil) ht.ConnectNodes(alice, eve) chanPointEve := ht.OpenChannel( - alice, eve, lntemp.OpenChannelParams{ + alice, eve, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: chanAmt / 2, Private: true, @@ -744,7 +744,7 @@ func testInvoiceRoutingHints(ht *lntemp.HarnessTest) { // testMultiHopOverPrivateChannels tests that private channels can be used as // intermediate hops in a route for payments. -func testMultiHopOverPrivateChannels(ht *lntemp.HarnessTest) { +func testMultiHopOverPrivateChannels(ht *lntest.HarnessTest) { // We'll test that multi-hop payments over private channels work as // intended. To do so, we'll create the following topology: // private public private @@ -755,7 +755,7 @@ func testMultiHopOverPrivateChannels(ht *lntemp.HarnessTest) { // being the funder. alice, bob := ht.Alice, ht.Bob chanPointAlice := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: chanAmt, Private: true, }, @@ -766,7 +766,7 @@ func testMultiHopOverPrivateChannels(ht *lntemp.HarnessTest) { carol := ht.NewNode("Carol", nil) ht.ConnectNodes(bob, carol) chanPointBob := ht.OpenChannel( - bob, carol, lntemp.OpenChannelParams{ + bob, carol, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -781,7 +781,7 @@ func testMultiHopOverPrivateChannels(ht *lntemp.HarnessTest) { ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) chanPointCarol := ht.OpenChannel( - carol, dave, lntemp.OpenChannelParams{ + carol, dave, lntest.OpenChannelParams{ Amt: chanAmt, Private: true, }, @@ -851,7 +851,7 @@ func testMultiHopOverPrivateChannels(ht *lntemp.HarnessTest) { // Alice --> Bob --> Carol --> Dave // // and query the daemon for routes from Alice to Dave. -func testQueryRoutes(ht *lntemp.HarnessTest) { +func testQueryRoutes(ht *lntest.HarnessTest) { const chanAmt = btcutil.Amount(100000) // Grab Alice and Bob from the standby nodes. @@ -869,8 +869,8 @@ func testQueryRoutes(ht *lntemp.HarnessTest) { // We now proceed to open channels: // Alice=>Bob, Bob=>Carol and Carol=>Dave. - p := lntemp.OpenChannelParams{Amt: chanAmt} - reqs := []*lntemp.OpenChannelRequest{ + p := lntest.OpenChannelParams{Amt: chanAmt} + reqs := []*lntest.OpenChannelRequest{ {Local: alice, Remote: bob, Param: p}, {Local: bob, Remote: carol, Param: p}, {Local: carol, Remote: dave, Param: p}, @@ -1086,7 +1086,7 @@ func testMissionControlCfg(t *testing.T, hn *node.HarnessNode) { // testMissionControlImport tests import of mission control results from an // external source. -func testMissionControlImport(ht *lntemp.HarnessTest, hn *node.HarnessNode, +func testMissionControlImport(ht *lntest.HarnessTest, hn *node.HarnessNode, fromNode, toNode []byte) { // Reset mission control so that our query will return the default @@ -1138,7 +1138,7 @@ func testMissionControlImport(ht *lntemp.HarnessTest, hn *node.HarnessNode, // testRouteFeeCutoff tests that we are able to prevent querying routes and // sending payments that incur a fee higher than the fee limit. -func testRouteFeeCutoff(ht *lntemp.HarnessTest) { +func testRouteFeeCutoff(ht *lntest.HarnessTest) { // For this test, we'll create the following topology: // // --- Bob --- @@ -1155,7 +1155,7 @@ func testRouteFeeCutoff(ht *lntemp.HarnessTest) { // Open a channel between Alice and Bob. alice, bob := ht.Alice, ht.Bob chanPointAliceBob := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) // Create Carol's node and open a channel between her and Alice with @@ -1165,7 +1165,7 @@ func testRouteFeeCutoff(ht *lntemp.HarnessTest) { ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) chanPointAliceCarol := ht.OpenChannel( - alice, carol, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) // Create Dave's node and open a channel between him and Bob with Bob @@ -1173,13 +1173,13 @@ func testRouteFeeCutoff(ht *lntemp.HarnessTest) { dave := ht.NewNode("Dave", nil) ht.ConnectNodes(dave, bob) chanPointBobDave := ht.OpenChannel( - bob, dave, lntemp.OpenChannelParams{Amt: chanAmt}, + bob, dave, lntest.OpenChannelParams{Amt: chanAmt}, ) // Open a channel between Carol and Dave. ht.ConnectNodes(carol, dave) chanPointCarolDave := ht.OpenChannel( - carol, dave, lntemp.OpenChannelParams{Amt: chanAmt}, + carol, dave, lntest.OpenChannelParams{Amt: chanAmt}, ) // Now that all the channels were set up, we'll wait for all the nodes @@ -1203,7 +1203,7 @@ func testRouteFeeCutoff(ht *lntemp.HarnessTest) { baseFee := int64(10000) feeRate := int64(5) timeLockDelta := uint32(chainreg.DefaultBitcoinTimeLockDelta) - maxHtlc := lntemp.CalculateMaxHtlc(chanAmt) + maxHtlc := lntest.CalculateMaxHtlc(chanAmt) expectedPolicy := &lnrpc.RoutingPolicy{ FeeBaseMsat: baseFee, diff --git a/itest/lnd_rpc_middleware_interceptor_test.go b/itest/lnd_rpc_middleware_interceptor_test.go index f9a793db4..7c99f6f20 100644 --- a/itest/lnd_rpc_middleware_interceptor_test.go +++ b/itest/lnd_rpc_middleware_interceptor_test.go @@ -8,8 +8,8 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/macaroons" "github.com/lightningnetwork/lnd/zpay32" "github.com/stretchr/testify/require" @@ -19,7 +19,7 @@ import ( // testRPCMiddlewareInterceptor tests that the RPC middleware interceptor can // be used correctly and in a safe way. -func testRPCMiddlewareInterceptor(ht *lntemp.HarnessTest) { +func testRPCMiddlewareInterceptor(ht *lntest.HarnessTest) { // Let's first enable the middleware interceptor. // // NOTE: we cannot use standby nodes here as the test messes with @@ -32,7 +32,7 @@ func testRPCMiddlewareInterceptor(ht *lntemp.HarnessTest) { // data to inspect when doing RPC calls to Alice later. ht.EnsureConnected(alice, bob) ht.FundCoins(btcutil.SatoshiPerBitcoin, alice) - ht.OpenChannel(alice, bob, lntemp.OpenChannelParams{Amt: 1_234_567}) + ht.OpenChannel(alice, bob, lntest.OpenChannelParams{Amt: 1_234_567}) // Load or bake the macaroons that the simulated users will use to // access the RPC. @@ -545,7 +545,7 @@ func middlewareRequestManipulationTest(t *testing.T, node *node.HarnessNode, // middlewareMandatoryTest tests that all RPC requests are blocked if there is // a mandatory middleware declared that's currently not registered. -func middlewareMandatoryTest(ht *lntemp.HarnessTest, node *node.HarnessNode) { +func middlewareMandatoryTest(ht *lntest.HarnessTest, node *node.HarnessNode) { // Let's declare our itest interceptor as mandatory but don't register // it just yet. That should cause all RPC requests to fail, except for // the registration itself. diff --git a/itest/lnd_send_multi_path_payment_test.go b/itest/lnd_send_multi_path_payment_test.go index 0e5cfc24a..143cf496d 100644 --- a/itest/lnd_send_multi_path_payment_test.go +++ b/itest/lnd_send_multi_path_payment_test.go @@ -6,13 +6,13 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" ) // testSendMultiPathPayment tests that we are able to successfully route a // payment using multiple shards across different paths. -func testSendMultiPathPayment(ht *lntemp.HarnessTest) { +func testSendMultiPathPayment(ht *lntest.HarnessTest) { mts := newMppTestScenario(ht) const paymentAmt = btcutil.Amount(300000) diff --git a/itest/lnd_signer_test.go b/itest/lnd_signer_test.go index ce16240a3..1372e4502 100644 --- a/itest/lnd_signer_test.go +++ b/itest/lnd_signer_test.go @@ -13,8 +13,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/signrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/stretchr/testify/require" ) @@ -22,7 +22,7 @@ import ( // DeriveSharedKey. It creates an ephemeral private key, performing an ECDH with // the node's pubkey and a customized public key to check the validity of the // result. -func testDeriveSharedKey(ht *lntemp.HarnessTest) { +func testDeriveSharedKey(ht *lntest.HarnessTest) { runDeriveSharedKey(ht, ht.Alice) } @@ -30,7 +30,7 @@ func testDeriveSharedKey(ht *lntemp.HarnessTest) { // DeriveSharedKey. It creates an ephemeral private key, performing an ECDH with // the node's pubkey and a customized public key to check the validity of the // result. -func runDeriveSharedKey(ht *lntemp.HarnessTest, alice *node.HarnessNode) { +func runDeriveSharedKey(ht *lntest.HarnessTest, alice *node.HarnessNode) { // Create an ephemeral key, extracts its public key, and make a // PrivKeyECDH using the ephemeral key. ephemeralPriv, err := btcec.NewPrivateKey() @@ -194,13 +194,13 @@ func runDeriveSharedKey(ht *lntemp.HarnessTest, alice *node.HarnessNode) { // testSignOutputRaw makes sure that the SignOutputRaw RPC can be used with all // custom ways of specifying the signing key in the key descriptor/locator. -func testSignOutputRaw(ht *lntemp.HarnessTest) { +func testSignOutputRaw(ht *lntest.HarnessTest) { runSignOutputRaw(ht, ht.Alice) } // runSignOutputRaw makes sure that the SignOutputRaw RPC can be used with all // custom ways of specifying the signing key in the key descriptor/locator. -func runSignOutputRaw(ht *lntemp.HarnessTest, alice *node.HarnessNode) { +func runSignOutputRaw(ht *lntest.HarnessTest, alice *node.HarnessNode) { // For the next step, we need a public key. Let's use a special family // for this. We want this to be an index of zero. const testCustomKeyFamily = 44 @@ -272,7 +272,7 @@ func runSignOutputRaw(ht *lntemp.HarnessTest, alice *node.HarnessNode) { // assertSignOutputRaw sends coins to a p2wkh address derived from the given // target public key and then tries to spend that output again by invoking the // SignOutputRaw RPC with the key descriptor provided. -func assertSignOutputRaw(ht *lntemp.HarnessTest, +func assertSignOutputRaw(ht *lntest.HarnessTest, alice *node.HarnessNode, targetPubKey *btcec.PublicKey, keyDesc *signrpc.KeyDescriptor, sigHash txscript.SigHashType) { @@ -373,14 +373,14 @@ func assertSignOutputRaw(ht *lntemp.HarnessTest, // testSignVerifyMessage makes sure that the SignMessage RPC can be used with // all custom flags by verifying with VerifyMessage. Tests both ECDSA and // Schnorr signatures. -func testSignVerifyMessage(ht *lntemp.HarnessTest) { +func testSignVerifyMessage(ht *lntest.HarnessTest) { runSignVerifyMessage(ht, ht.Alice) } // runSignVerifyMessage makes sure that the SignMessage RPC can be used with // all custom flags by verifying with VerifyMessage. Tests both ECDSA and // Schnorr signatures. -func runSignVerifyMessage(ht *lntemp.HarnessTest, alice *node.HarnessNode) { +func runSignVerifyMessage(ht *lntest.HarnessTest, alice *node.HarnessNode) { aliceMsg := []byte("alice msg") keyLoc := &signrpc.KeyLocator{ KeyFamily: int32(keychain.KeyFamilyNodeKey), diff --git a/itest/lnd_single_hop_invoice_test.go b/itest/lnd_single_hop_invoice_test.go index ce75c42d0..8051f7bb8 100644 --- a/itest/lnd_single_hop_invoice_test.go +++ b/itest/lnd_single_hop_invoice_test.go @@ -7,20 +7,20 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/record" "github.com/stretchr/testify/require" ) -func testSingleHopInvoice(ht *lntemp.HarnessTest) { +func testSingleHopInvoice(ht *lntest.HarnessTest) { // Open a channel with 100k satoshis between Alice and Bob with Alice // being the sole funder of the channel. chanAmt := btcutil.Amount(100000) alice, bob := ht.Alice, ht.Bob cp := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) // assertAmountPaid is a helper closure that asserts the amount paid by diff --git a/itest/lnd_switch_test.go b/itest/lnd_switch_test.go index fd90be4a7..0bf71294a 100644 --- a/itest/lnd_switch_test.go +++ b/itest/lnd_switch_test.go @@ -3,8 +3,8 @@ package itest import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/stretchr/testify/require" ) @@ -21,11 +21,11 @@ const ( // // The general flow of this test: // 1. Carol --> Dave --> Alice --> Bob forward payment -// 2. -------X X X Bob restart sender and intermediaries +// 2. X X X Bob restart sender and intermediaries // 3. Carol <-- Dave <-- Alice <-- Bob expect settle to propagate // //nolint:dupword -func testSwitchCircuitPersistence(ht *lntemp.HarnessTest) { +func testSwitchCircuitPersistence(ht *lntest.HarnessTest) { // Setup our test scenario. We should now have four nodes running with // three channels. s := setupScenarioFourNodes(ht) @@ -95,7 +95,7 @@ func testSwitchCircuitPersistence(ht *lntemp.HarnessTest) { // 2. Carol --- Dave X Alice --- Bob disconnect intermediaries // 3. Carol --- Dave X Alice <-- Bob settle last hop // 4. Carol <-- Dave <-- Alice --- Bob reconnect, expect settle to propagate -func testSwitchOfflineDelivery(ht *lntemp.HarnessTest) { +func testSwitchOfflineDelivery(ht *lntest.HarnessTest) { // Setup our test scenario. We should now have four nodes running with // three channels. s := setupScenarioFourNodes(ht) @@ -174,7 +174,7 @@ func testSwitchOfflineDelivery(ht *lntemp.HarnessTest) { // 3. Carol --- Dave X Alice <-- Bob settle last hop // 4. Carol --- Dave X X Bob restart Alice // 5. Carol <-- Dave <-- Alice --- Bob expect settle to propagate -func testSwitchOfflineDeliveryPersistence(ht *lntemp.HarnessTest) { +func testSwitchOfflineDeliveryPersistence(ht *lntest.HarnessTest) { // Setup our test scenario. We should now have four nodes running with // three channels. s := setupScenarioFourNodes(ht) @@ -260,7 +260,7 @@ func testSwitchOfflineDeliveryPersistence(ht *lntemp.HarnessTest) { // 3. Carol --- Dave X Alice <-- Bob settle last hop // 4. Carol --- Dave X X shutdown Bob, restart Alice // 5. Carol <-- Dave <-- Alice X expect settle to propagate -func testSwitchOfflineDeliveryOutgoingOffline(ht *lntemp.HarnessTest) { +func testSwitchOfflineDeliveryOutgoingOffline(ht *lntest.HarnessTest) { // Setup our test scenario. We should now have four nodes running with // three channels. Note that we won't call the cleanUp function here as // we will manually stop the node Carol and her channel. @@ -371,13 +371,13 @@ type scenarioFourNodes struct { // // NOTE: caller needs to call cleanUp to clean the nodes and channels created // from this setup. -func setupScenarioFourNodes(ht *lntemp.HarnessTest) *scenarioFourNodes { +func setupScenarioFourNodes(ht *lntest.HarnessTest) *scenarioFourNodes { const ( chanAmt = btcutil.Amount(1000000) pushAmt = btcutil.Amount(900000) ) - params := lntemp.OpenChannelParams{ + params := lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, } @@ -404,7 +404,7 @@ func setupScenarioFourNodes(ht *lntemp.HarnessTest) *scenarioFourNodes { ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) // Open channels in batch to save blocks mined. - reqs := []*lntemp.OpenChannelRequest{ + reqs := []*lntest.OpenChannelRequest{ {Local: alice, Remote: bob, Param: params}, {Local: dave, Remote: alice, Param: params}, {Local: carol, Remote: dave, Param: params}, @@ -456,7 +456,7 @@ func setupScenarioFourNodes(ht *lntemp.HarnessTest) *scenarioFourNodes { // assertHTLCs is a helper function which asserts the desired num of // HTLCs has been seen in the nodes. -func (s *scenarioFourNodes) assertHTLCs(ht *lntemp.HarnessTest, num int) { +func (s *scenarioFourNodes) assertHTLCs(ht *lntest.HarnessTest, num int) { // Alice should have both the same number of outgoing and // incoming HTLCs. ht.AssertNumActiveHtlcs(s.alice, num*2) @@ -472,7 +472,7 @@ func (s *scenarioFourNodes) assertHTLCs(ht *lntemp.HarnessTest, num int) { // assertAmoutPaid is a helper method which takes a given paid amount // and number of payments and asserts the desired payments are made in // the four nodes. -func (s *scenarioFourNodes) assertAmoutPaid(ht *lntemp.HarnessTest, +func (s *scenarioFourNodes) assertAmoutPaid(ht *lntest.HarnessTest, amt int64, num int64) { ht.AssertAmountPaid( diff --git a/itest/lnd_taproot_test.go b/itest/lnd_taproot_test.go index a04048195..82f8c86fb 100644 --- a/itest/lnd_taproot_test.go +++ b/itest/lnd_taproot_test.go @@ -20,8 +20,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc/chainrpc" "github.com/lightningnetwork/lnd/lnrpc/signrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/stretchr/testify/require" ) @@ -47,7 +47,7 @@ var ( // testTaproot ensures that the daemon can send to and spend from taproot (p2tr) // outputs. -func testTaproot(ht *lntemp.HarnessTest) { +func testTaproot(ht *lntest.HarnessTest) { testTaprootSendCoinsKeySpendBip86(ht, ht.Alice) testTaprootComputeInputScriptKeySpendBip86(ht, ht.Alice) testTaprootSignOutputRawScriptSpend(ht, ht.Alice) @@ -81,7 +81,7 @@ func testTaproot(ht *lntemp.HarnessTest) { // testTaprootSendCoinsKeySpendBip86 tests sending to and spending from // p2tr key spend only (BIP-0086) addresses through the SendCoins RPC which // internally uses the ComputeInputScript method for signing. -func testTaprootSendCoinsKeySpendBip86(ht *lntemp.HarnessTest, +func testTaprootSendCoinsKeySpendBip86(ht *lntest.HarnessTest, alice *node.HarnessNode) { // We'll start the test by sending Alice some coins, which she'll use to @@ -137,7 +137,7 @@ func testTaprootSendCoinsKeySpendBip86(ht *lntemp.HarnessTest, // testTaprootComputeInputScriptKeySpendBip86 tests sending to and spending from // p2tr key spend only (BIP-0086) addresses through the SendCoins RPC which // internally uses the ComputeInputScript method for signing. -func testTaprootComputeInputScriptKeySpendBip86(ht *lntemp.HarnessTest, +func testTaprootComputeInputScriptKeySpendBip86(ht *lntest.HarnessTest, alice *node.HarnessNode) { // We'll start the test by sending Alice some coins, which she'll use @@ -234,7 +234,7 @@ func testTaprootComputeInputScriptKeySpendBip86(ht *lntemp.HarnessTest, // testTaprootSignOutputRawScriptSpend tests sending to and spending from p2tr // script addresses using the script path with the SignOutputRaw RPC. -func testTaprootSignOutputRawScriptSpend(ht *lntemp.HarnessTest, +func testTaprootSignOutputRawScriptSpend(ht *lntest.HarnessTest, alice *node.HarnessNode, sigHashType ...txscript.SigHashType) { // For the next step, we need a public key. Let's use a special family @@ -392,7 +392,7 @@ func testTaprootSignOutputRawScriptSpend(ht *lntemp.HarnessTest, // testTaprootSignOutputRawKeySpendBip86 tests that a tapscript address can // also be spent using the key spend path through the SignOutputRaw RPC using a // BIP0086 key spend only commitment. -func testTaprootSignOutputRawKeySpendBip86(ht *lntemp.HarnessTest, +func testTaprootSignOutputRawKeySpendBip86(ht *lntest.HarnessTest, alice *node.HarnessNode, sigHashType ...txscript.SigHashType) { // For the next step, we need a public key. Let's use a special family @@ -490,7 +490,7 @@ func testTaprootSignOutputRawKeySpendBip86(ht *lntemp.HarnessTest, // testTaprootSignOutputRawKeySpendRootHash tests that a tapscript address can // also be spent using the key spend path through the SignOutputRaw RPC using a // tapscript root hash. -func testTaprootSignOutputRawKeySpendRootHash(ht *lntemp.HarnessTest, +func testTaprootSignOutputRawKeySpendRootHash(ht *lntest.HarnessTest, alice *node.HarnessNode) { // For the next step, we need a public key. Let's use a special family @@ -583,7 +583,7 @@ func testTaprootSignOutputRawKeySpendRootHash(ht *lntemp.HarnessTest, // testTaprootMuSig2KeySpendBip86 tests that a combined MuSig2 key can also be // used as a BIP-0086 key spend only key. -func testTaprootMuSig2KeySpendBip86(ht *lntemp.HarnessTest, +func testTaprootMuSig2KeySpendBip86(ht *lntest.HarnessTest, alice *node.HarnessNode, version signrpc.MuSig2Version) { // We're not going to commit to a script. So our taproot tweak will be @@ -711,7 +711,7 @@ func testTaprootMuSig2KeySpendBip86(ht *lntemp.HarnessTest, // testTaprootMuSig2KeySpendRootHash tests that a tapscript address can also be // spent using a MuSig2 combined key. -func testTaprootMuSig2KeySpendRootHash(ht *lntemp.HarnessTest, +func testTaprootMuSig2KeySpendRootHash(ht *lntest.HarnessTest, alice *node.HarnessNode, version signrpc.MuSig2Version) { // We're going to commit to a script as well. This is a hash lock with a @@ -843,7 +843,7 @@ func testTaprootMuSig2KeySpendRootHash(ht *lntemp.HarnessTest, // testTaprootMuSig2ScriptSpend tests that a tapscript address with an internal // key that is a MuSig2 combined key can also be spent using the script path. -func testTaprootMuSig2ScriptSpend(ht *lntemp.HarnessTest, +func testTaprootMuSig2ScriptSpend(ht *lntest.HarnessTest, alice *node.HarnessNode, version signrpc.MuSig2Version) { // We're going to commit to a script and spend the output using the @@ -926,7 +926,7 @@ func testTaprootMuSig2ScriptSpend(ht *lntemp.HarnessTest, // testTaprootMuSig2CombinedLeafKeySpend tests that a MuSig2 combined key can be // used for an OP_CHECKSIG inside a tap script leaf spend. -func testTaprootMuSig2CombinedLeafKeySpend(ht *lntemp.HarnessTest, +func testTaprootMuSig2CombinedLeafKeySpend(ht *lntest.HarnessTest, alice *node.HarnessNode, version signrpc.MuSig2Version) { // We're using the combined MuSig2 key in a script leaf. So we need to @@ -1102,7 +1102,7 @@ func testTaprootMuSig2CombinedLeafKeySpend(ht *lntemp.HarnessTest, // testTaprootImportTapscriptScriptSpend tests importing p2tr script addresses // using the script path with the full tree known. -func testTaprootImportTapscriptFullTree(ht *lntemp.HarnessTest, +func testTaprootImportTapscriptFullTree(ht *lntest.HarnessTest, alice *node.HarnessNode) { // For the next step, we need a public key. Let's use a special family @@ -1176,7 +1176,7 @@ func testTaprootImportTapscriptFullTree(ht *lntemp.HarnessTest, // testTaprootImportTapscriptPartialReveal tests importing p2tr script addresses // for which we only know part of the tree. -func testTaprootImportTapscriptPartialReveal(ht *lntemp.HarnessTest, +func testTaprootImportTapscriptPartialReveal(ht *lntest.HarnessTest, alice *node.HarnessNode) { // For the next step, we need a public key. Let's use a special family @@ -1247,7 +1247,7 @@ func testTaprootImportTapscriptPartialReveal(ht *lntemp.HarnessTest, // testTaprootImportTapscriptRootHashOnly tests importing p2tr script addresses // for which we only know the root hash. -func testTaprootImportTapscriptRootHashOnly(ht *lntemp.HarnessTest, +func testTaprootImportTapscriptRootHashOnly(ht *lntest.HarnessTest, alice *node.HarnessNode) { // For the next step, we need a public key. Let's use a special family @@ -1306,7 +1306,7 @@ func testTaprootImportTapscriptRootHashOnly(ht *lntemp.HarnessTest, // testTaprootImportTapscriptFullKey tests importing p2tr script addresses for // which we only know the full Taproot key. -func testTaprootImportTapscriptFullKey(ht *lntemp.HarnessTest, +func testTaprootImportTapscriptFullKey(ht *lntest.HarnessTest, alice *node.HarnessNode) { // For the next step, we need a public key. Let's use a special family @@ -1365,7 +1365,7 @@ func testTaprootImportTapscriptFullKey(ht *lntemp.HarnessTest, // clearWalletImportedTapscriptBalance manually assembles and then attempts to // sign a TX to sweep funds from an imported tapscript address. -func clearWalletImportedTapscriptBalance(ht *lntemp.HarnessTest, +func clearWalletImportedTapscriptBalance(ht *lntest.HarnessTest, hn *node.HarnessNode, utxo *wire.TxOut, outPoint wire.OutPoint, internalKey *btcec.PublicKey, derivationPath []uint32, rootHash []byte) { @@ -1460,7 +1460,7 @@ func testScriptSchnorrSig(t *testing.T, } // newAddrWithScript returns a new address and its pkScript. -func newAddrWithScript(ht *lntemp.HarnessTest, node *node.HarnessNode, +func newAddrWithScript(ht *lntest.HarnessTest, node *node.HarnessNode, addrType lnrpc.AddressType) (btcutil.Address, []byte) { p2wkhResp := node.RPC.NewAddress(&lnrpc.NewAddressRequest{ @@ -1479,7 +1479,7 @@ func newAddrWithScript(ht *lntemp.HarnessTest, node *node.HarnessNode, // sendToTaprootOutput sends coins to a p2tr output of the given taproot key and // mines a block to confirm the coins. -func sendToTaprootOutput(ht *lntemp.HarnessTest, hn *node.HarnessNode, +func sendToTaprootOutput(ht *lntest.HarnessTest, hn *node.HarnessNode, taprootKey *btcec.PublicKey, amt int64) (wire.OutPoint, []byte) { tapScriptAddr, err := btcutil.NewAddressTaproot( @@ -1542,7 +1542,7 @@ func sendToTaprootOutput(ht *lntemp.HarnessTest, hn *node.HarnessNode, // after checking its weight against an estimate. After asserting the given // spend request, the given sweep address' balance is verified to be seen as // funds belonging to the wallet. -func publishTxAndConfirmSweep(ht *lntemp.HarnessTest, node *node.HarnessNode, +func publishTxAndConfirmSweep(ht *lntest.HarnessTest, node *node.HarnessNode, tx *wire.MsgTx, estimatedWeight int64, spendRequest *chainrpc.SpendRequest, sweepAddr string) { @@ -1604,7 +1604,7 @@ func publishTxAndConfirmSweep(ht *lntemp.HarnessTest, node *node.HarnessNode, // confirmAddress makes sure that a transaction in the mempool spends funds to // the given address. It also checks that a confirmation notification for the // address is triggered when the transaction is mined. -func confirmAddress(ht *lntemp.HarnessTest, hn *node.HarnessNode, +func confirmAddress(ht *lntest.HarnessTest, hn *node.HarnessNode, addrString string) { // Wait until the tx that sends to the address is found. @@ -1654,7 +1654,7 @@ func confirmAddress(ht *lntemp.HarnessTest, hn *node.HarnessNode, // deriveSigningKeys derives three signing keys and returns their descriptors, // as well as the public keys in the Schnorr serialized format. -func deriveSigningKeys(ht *lntemp.HarnessTest, node *node.HarnessNode, +func deriveSigningKeys(ht *lntest.HarnessTest, node *node.HarnessNode, version signrpc.MuSig2Version) (*signrpc.KeyDescriptor, *signrpc.KeyDescriptor, *signrpc.KeyDescriptor, [][]byte) { @@ -1700,7 +1700,7 @@ func deriveSigningKeys(ht *lntemp.HarnessTest, node *node.HarnessNode, // combined into a single key. The same node is used for the three signing // participants but a separate key is generated for each session. So the result // should be the same as if it were three different nodes. -func createMuSigSessions(ht *lntemp.HarnessTest, node *node.HarnessNode, +func createMuSigSessions(ht *lntest.HarnessTest, node *node.HarnessNode, taprootTweak *signrpc.TaprootTweakDesc, keyDesc1, keyDesc2, keyDesc3 *signrpc.KeyDescriptor, allPubKeys [][]byte, version signrpc.MuSig2Version) (*btcec.PublicKey, @@ -1838,7 +1838,7 @@ func createMuSigSessions(ht *lntemp.HarnessTest, node *node.HarnessNode, // testTaprootCoopClose asserts that if both peers signal ShutdownAnySegwit, // then a taproot closing addr is used. Otherwise, we shouldn't expect one to // be used. -func testTaprootCoopClose(ht *lntemp.HarnessTest) { +func testTaprootCoopClose(ht *lntest.HarnessTest) { // We'll start by making two new nodes, and funding a channel between // them. carol := ht.NewNode("Carol", nil) @@ -1853,7 +1853,7 @@ func testTaprootCoopClose(ht *lntemp.HarnessTest) { // We'll now open a channel between Carol and Dave. chanPoint := ht.OpenChannel( - carol, dave, lntemp.OpenChannelParams{ + carol, dave, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, SatPerVByte: satPerVbyte, @@ -1888,7 +1888,7 @@ func testTaprootCoopClose(ht *lntemp.HarnessTest) { // We'll now open up a chanel again between Carol and Eve. chanPoint = ht.OpenChannel( - carol, eve, lntemp.OpenChannelParams{ + carol, eve, lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: pushAmt, SatPerVByte: satPerVbyte, @@ -1904,7 +1904,7 @@ func testTaprootCoopClose(ht *lntemp.HarnessTest) { // testMuSig2CombineKey makes sure that combining a key with MuSig2 returns the // correct result according to the MuSig2 version specified. -func testMuSig2CombineKey(ht *lntemp.HarnessTest, alice *node.HarnessNode, +func testMuSig2CombineKey(ht *lntest.HarnessTest, alice *node.HarnessNode, version signrpc.MuSig2Version) { testVector040Key1 := hexDecode( diff --git a/itest/lnd_test.go b/itest/lnd_test.go index 0ff7294e2..cb9f60dbf 100644 --- a/itest/lnd_test.go +++ b/itest/lnd_test.go @@ -15,8 +15,8 @@ import ( "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" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" "google.golang.org/grpc/grpclog" @@ -90,11 +90,11 @@ func TestLightningNetworkDaemon(t *testing.T) { node.ApplyPortOffset(uint32(trancheIndex) * 1000) // Create a simple fee service. - feeService := lntemp.NewFeeService(t) + feeService := lntest.NewFeeService(t) // Get the binary path and setup the harness test. binary := getLndBinary(t) - harnessTest := lntemp.SetupHarness( + harnessTest := lntest.SetupHarness( t, binary, *dbBackendFlag, feeService, ) defer harnessTest.Stop() @@ -156,7 +156,7 @@ func TestLightningNetworkDaemon(t *testing.T) { // getTestCaseSplitTranche returns the sub slice of the test cases that should // be run as the current split tranche as well as the index and slice offset of // the tranche. -func getTestCaseSplitTranche() ([]*lntemp.TestCase, uint, uint) { +func getTestCaseSplitTranche() ([]*lntest.TestCase, uint, uint) { numTranches := defaultSplitTranches if testCasesSplitTranches != nil { numTranches = *testCasesSplitTranches diff --git a/itest/lnd_trackpayments_test.go b/itest/lnd_trackpayments_test.go index 2554471ef..55224b87b 100644 --- a/itest/lnd_trackpayments_test.go +++ b/itest/lnd_trackpayments_test.go @@ -7,17 +7,17 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" ) // testTrackPayments tests whether a client that calls the TrackPayments api // receives payment updates. -func testTrackPayments(ht *lntemp.HarnessTest) { +func testTrackPayments(ht *lntest.HarnessTest) { // Open a channel between alice and bob. alice, bob := ht.Alice, ht.Bob channel := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{ + alice, bob, lntest.OpenChannelParams{ Amt: btcutil.Amount(300000), }, ) diff --git a/itest/lnd_wallet_import_test.go b/itest/lnd_wallet_import_test.go index 818ff311d..afd96a352 100644 --- a/itest/lnd_wallet_import_test.go +++ b/itest/lnd_wallet_import_test.go @@ -16,8 +16,8 @@ import ( "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lnwallet" "github.com/stretchr/testify/require" ) @@ -51,7 +51,7 @@ func walletToLNAddrType(t *testing.T, // newExternalAddr generates a new external address of an imported account for a // pair of nodes, where one acts as the funder and the other as the signer. -func newExternalAddr(ht *lntemp.HarnessTest, funder, signer *node.HarnessNode, +func newExternalAddr(ht *lntest.HarnessTest, funder, signer *node.HarnessNode, importedAccount string, addrType walletrpc.AddressType) string { // We'll generate a new address for Carol from Dave's node to receive @@ -125,7 +125,7 @@ func assertOutputScriptType(t *testing.T, expType txscript.ScriptClass, // psbtSendFromImportedAccount attempts to fund a PSBT from the given imported // account, originating from the source node to the destination. -func psbtSendFromImportedAccount(ht *lntemp.HarnessTest, srcNode, destNode, +func psbtSendFromImportedAccount(ht *lntest.HarnessTest, srcNode, destNode, signer *node.HarnessNode, account string, accountAddrType walletrpc.AddressType) { @@ -236,7 +236,7 @@ func psbtSendFromImportedAccount(ht *lntemp.HarnessTest, srcNode, destNode, // node. To ensure the channel is operational before closing it, a test payment // is made. Several balance assertions are made along the way for the sake of // correctness. -func fundChanAndCloseFromImportedAccount(ht *lntemp.HarnessTest, srcNode, +func fundChanAndCloseFromImportedAccount(ht *lntest.HarnessTest, srcNode, destNode, signer *node.HarnessNode, account string, accountAddrType walletrpc.AddressType, utxoAmt, chanSize int64) { @@ -256,7 +256,7 @@ func fundChanAndCloseFromImportedAccount(ht *lntemp.HarnessTest, srcNode, // The source node will then fund the channel through a PSBT shim. pendingChanID := ht.Random32Bytes() chanUpdates, rawPsbt := ht.OpenChannelPsbt( - srcNode, destNode, lntemp.OpenChannelParams{ + srcNode, destNode, lntest.OpenChannelParams{ Amt: btcutil.Amount(chanSize), FundingShim: &lnrpc.FundingShim{ Shim: &lnrpc.FundingShim_PsbtShim{ @@ -463,7 +463,7 @@ func fundChanAndCloseFromImportedAccount(ht *lntemp.HarnessTest, srcNode, // testWalletImportAccount tests that an imported account can fund transactions // and channels through PSBTs, by having one node (the one with the imported // account) craft the transactions and another node act as the signer. -func testWalletImportAccount(ht *lntemp.HarnessTest) { +func testWalletImportAccount(ht *lntest.HarnessTest) { testCases := []struct { name string addrType walletrpc.AddressType @@ -491,7 +491,7 @@ func testWalletImportAccount(ht *lntemp.HarnessTest) { for _, tc := range testCases { tc := tc success := ht.Run(tc.name, func(tt *testing.T) { - testFunc := func(ht *lntemp.HarnessTest) { + testFunc := func(ht *lntest.HarnessTest) { testWalletImportAccountScenario( ht, tc.addrType, ) @@ -499,7 +499,7 @@ func testWalletImportAccount(ht *lntemp.HarnessTest) { st := ht.Subtest(tt) - st.RunTestCase(&lntemp.TestCase{ + st.RunTestCase(&lntest.TestCase{ Name: tc.name, TestFunc: testFunc, }) @@ -515,7 +515,7 @@ func testWalletImportAccount(ht *lntemp.HarnessTest) { } } -func testWalletImportAccountScenario(ht *lntemp.HarnessTest, +func testWalletImportAccountScenario(ht *lntest.HarnessTest, addrType walletrpc.AddressType) { // We'll start our test by having two nodes, Carol and Dave. Carol's @@ -529,7 +529,7 @@ func testWalletImportAccountScenario(ht *lntemp.HarnessTest, runWalletImportAccountScenario(ht, addrType, carol, dave) } -func runWalletImportAccountScenario(ht *lntemp.HarnessTest, +func runWalletImportAccountScenario(ht *lntest.HarnessTest, addrType walletrpc.AddressType, carol, dave *node.HarnessNode) { const utxoAmt int64 = btcutil.SatoshiPerBitcoin @@ -619,7 +619,7 @@ func runWalletImportAccountScenario(ht *lntemp.HarnessTest, // testWalletImportPubKey tests that an imported public keys can fund // transactions and channels through PSBTs, by having one node (the one with the // imported account) craft the transactions and another node act as the signer. -func testWalletImportPubKey(ht *lntemp.HarnessTest) { +func testWalletImportPubKey(ht *lntest.HarnessTest) { testCases := []struct { name string addrType walletrpc.AddressType @@ -642,7 +642,7 @@ func testWalletImportPubKey(ht *lntemp.HarnessTest) { for _, tc := range testCases { tc := tc success := ht.Run(tc.name, func(tt *testing.T) { - testFunc := func(ht *lntemp.HarnessTest) { + testFunc := func(ht *lntest.HarnessTest) { testWalletImportPubKeyScenario( ht, tc.addrType, ) @@ -650,7 +650,7 @@ func testWalletImportPubKey(ht *lntemp.HarnessTest) { st := ht.Subtest(tt) - st.RunTestCase(&lntemp.TestCase{ + st.RunTestCase(&lntest.TestCase{ Name: tc.name, TestFunc: testFunc, }) @@ -666,7 +666,7 @@ func testWalletImportPubKey(ht *lntemp.HarnessTest) { } } -func testWalletImportPubKeyScenario(ht *lntemp.HarnessTest, +func testWalletImportPubKeyScenario(ht *lntest.HarnessTest, addrType walletrpc.AddressType) { const utxoAmt int64 = btcutil.SatoshiPerBitcoin diff --git a/itest/lnd_wipe_fwdpkgs_test.go b/itest/lnd_wipe_fwdpkgs_test.go index 0f74d4fab..35953f5cb 100644 --- a/itest/lnd_wipe_fwdpkgs_test.go +++ b/itest/lnd_wipe_fwdpkgs_test.go @@ -5,7 +5,7 @@ import ( "github.com/lightningnetwork/lnd/chainreg" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/stretchr/testify/require" ) @@ -21,7 +21,7 @@ type pendingChan *lnrpc.PendingChannelsResponse_PendingChannel // packages are wiped. // - Bob coop closes the channel Bob->Carol, and checks from both Bob PoVs // that the forwarding packages are wiped. -func testWipeForwardingPackages(ht *lntemp.HarnessTest) { +func testWipeForwardingPackages(ht *lntest.HarnessTest) { const ( chanAmt = 10e6 paymentAmt = 10e4 @@ -41,12 +41,12 @@ func testWipeForwardingPackages(ht *lntemp.HarnessTest) { // Open a channel between Alice and Bob. chanPointAB := ht.OpenChannel( - alice, bob, lntemp.OpenChannelParams{Amt: chanAmt}, + alice, bob, lntest.OpenChannelParams{Amt: chanAmt}, ) // Open a channel between Bob and Carol. chanPointBC := ht.OpenChannel( - bob, carol, lntemp.OpenChannelParams{Amt: chanAmt}, + bob, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) // Before we continue, make sure Alice has seen the channel between Bob diff --git a/itest/lnd_wumbo_channels_test.go b/itest/lnd_wumbo_channels_test.go index 5a5ba6627..18d170acc 100644 --- a/itest/lnd_wumbo_channels_test.go +++ b/itest/lnd_wumbo_channels_test.go @@ -3,7 +3,7 @@ package itest import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/funding" - "github.com/lightningnetwork/lnd/lntemp" + "github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -11,7 +11,7 @@ import ( // acceptances will allow a wumbo channel to be created. Additionally, if a // node is running with mini channels only enabled, then they should reject any // inbound wumbo channel requests. -func testWumboChannels(ht *lntemp.HarnessTest) { +func testWumboChannels(ht *lntest.HarnessTest) { // With all the channel types exercised, we'll now make sure the wumbo // signalling support works properly. // @@ -33,7 +33,7 @@ func testWumboChannels(ht *lntemp.HarnessTest) { // The test should indicate a failure due to the channel being too // large. ht.OpenChannelAssertErr( - wumboNode, miniNode, lntemp.OpenChannelParams{Amt: chanAmt}, + wumboNode, miniNode, lntest.OpenChannelParams{Amt: chanAmt}, lnwallet.ErrChanTooLarge(chanAmt, funding.MaxBtcFundingAmount), ) @@ -46,7 +46,7 @@ func testWumboChannels(ht *lntemp.HarnessTest) { // Creating a wumbo channel between these two nodes should succeed. ht.EnsureConnected(wumboNode, wumboNode2) chanPoint := ht.OpenChannel( - wumboNode, wumboNode2, lntemp.OpenChannelParams{Amt: chanAmt}, + wumboNode, wumboNode2, lntest.OpenChannelParams{Amt: chanAmt}, ) ht.CloseChannel(wumboNode, chanPoint) } diff --git a/itest/lnd_zero_conf_test.go b/itest/lnd_zero_conf_test.go index 4482874e3..3eae1ebe9 100644 --- a/itest/lnd_zero_conf_test.go +++ b/itest/lnd_zero_conf_test.go @@ -13,9 +13,9 @@ import ( "github.com/lightningnetwork/lnd/chainreg" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntemp" - "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntemp/rpc" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" + "github.com/lightningnetwork/lnd/lntest/rpc" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/require" @@ -23,7 +23,7 @@ import ( // testZeroConfChannelOpen tests that opening a zero-conf channel works and // sending payments also works. -func testZeroConfChannelOpen(ht *lntemp.HarnessTest) { +func testZeroConfChannelOpen(ht *lntest.HarnessTest) { // Since option-scid-alias is opt-in, the provided harness nodes will // not have the feature bit set. Also need to set anchors as those are // default-off in itests. @@ -39,7 +39,7 @@ func testZeroConfChannelOpen(ht *lntemp.HarnessTest) { // We'll open a regular public channel between Bob and Carol here. chanAmt := btcutil.Amount(1_000_000) - p := lntemp.OpenChannelParams{ + p := lntest.OpenChannelParams{ Amt: chanAmt, } chanPoint := ht.OpenChannel(bob, carol, p) @@ -58,7 +58,7 @@ func testZeroConfChannelOpen(ht *lntemp.HarnessTest) { go acceptChannel(ht.T, true, acceptStream) // Open a private zero-conf anchors channel of 1M satoshis. - params := lntemp.OpenChannelParams{ + params := lntest.OpenChannelParams{ Amt: chanAmt, Private: true, CommitmentType: lnrpc.CommitmentType_ANCHORS, @@ -191,7 +191,7 @@ func testZeroConfChannelOpen(ht *lntemp.HarnessTest) { // testOptionScidAlias checks that opening an option_scid_alias channel-type // channel or w/o the channel-type works properly. -func testOptionScidAlias(ht *lntemp.HarnessTest) { +func testOptionScidAlias(ht *lntest.HarnessTest) { type scidTestCase struct { name string @@ -234,7 +234,7 @@ func testOptionScidAlias(ht *lntemp.HarnessTest) { } } -func optionScidAliasScenario(ht *lntemp.HarnessTest, chantype, private bool) { +func optionScidAliasScenario(ht *lntest.HarnessTest, chantype, private bool) { // Option-scid-alias is opt-in, as is anchors. scidAliasArgs := []string{ "--protocol.option-scid-alias", @@ -256,7 +256,7 @@ func optionScidAliasScenario(ht *lntemp.HarnessTest, chantype, private bool) { chanAmt := btcutil.Amount(1_000_000) - params := lntemp.OpenChannelParams{ + params := lntest.OpenChannelParams{ Amt: chanAmt, Private: private, CommitmentType: lnrpc.CommitmentType_ANCHORS, @@ -282,7 +282,7 @@ func optionScidAliasScenario(ht *lntemp.HarnessTest, chantype, private bool) { // We'll now open a regular public channel between Bob and Carol and // assert that Bob can pay Dave. We'll also assert that the invoice // Dave issues has the startingAlias as a hop hint. - p := lntemp.OpenChannelParams{ + p := lntest.OpenChannelParams{ Amt: chanAmt, } fundingPoint2 := ht.OpenChannel(bob, carol, p) @@ -409,7 +409,7 @@ func waitForZeroConfGraphChange(hn *node.HarnessNode, // testUpdateChannelPolicyScidAlias checks that option-scid-alias, zero-conf // channel-types, and option-scid-alias feature-bit-only channels have the // expected graph and that payments work when updating the channel policy. -func testUpdateChannelPolicyScidAlias(ht *lntemp.HarnessTest) { +func testUpdateChannelPolicyScidAlias(ht *lntest.HarnessTest) { tests := []struct { name string @@ -461,7 +461,7 @@ func testUpdateChannelPolicyScidAlias(ht *lntemp.HarnessTest) { } } -func testPrivateUpdateAlias(ht *lntemp.HarnessTest, +func testPrivateUpdateAlias(ht *lntest.HarnessTest, zeroConf, scidAliasType, private bool) { // We'll create a new node Eve that will not have option-scid-alias @@ -494,7 +494,7 @@ func testPrivateUpdateAlias(ht *lntemp.HarnessTest, chanAmt := btcutil.Amount(1_000_000) - p := lntemp.OpenChannelParams{ + p := lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: chanAmt / 2, } @@ -508,7 +508,7 @@ func testPrivateUpdateAlias(ht *lntemp.HarnessTest, go acceptChannel(ht.T, zeroConf, acceptStream) // Open a private channel, optionally specifying a channel-type. - params := lntemp.OpenChannelParams{ + params := lntest.OpenChannelParams{ Amt: chanAmt, Private: private, CommitmentType: lnrpc.CommitmentType_ANCHORS, @@ -541,7 +541,7 @@ func testPrivateUpdateAlias(ht *lntemp.HarnessTest, FeeRateMilliMsat: testFeeBase * feeRate, TimeLockDelta: timeLockDelta, MinHtlc: 1000, // default value - MaxHtlcMsat: lntemp.CalculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntest.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: lntemp.CalculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntest.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: lntemp.CalculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntest.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: lntemp.CalculateMaxHtlc(chanAmt), + MaxHtlcMsat: lntest.CalculateMaxHtlc(chanAmt), } // Assert Dave and optionally Eve receives Carol's update. @@ -763,7 +763,7 @@ func testPrivateUpdateAlias(ht *lntemp.HarnessTest, // testOptionScidUpgrade tests that toggling the option-scid-alias feature bit // correctly upgrades existing channels. -func testOptionScidUpgrade(ht *lntemp.HarnessTest) { +func testOptionScidUpgrade(ht *lntest.HarnessTest) { bob := ht.Bob // Start carol with anchors only. @@ -787,7 +787,7 @@ func testOptionScidUpgrade(ht *lntemp.HarnessTest) { chanAmt := btcutil.Amount(1_000_000) - p := lntemp.OpenChannelParams{ + p := lntest.OpenChannelParams{ Amt: chanAmt, PushAmt: chanAmt / 2, Private: true, @@ -797,7 +797,7 @@ func testOptionScidUpgrade(ht *lntemp.HarnessTest) { // Bob will open a channel to Carol now. ht.EnsureConnected(bob, carol) - p = lntemp.OpenChannelParams{ + p = lntest.OpenChannelParams{ Amt: chanAmt, } fundingPoint2 := ht.OpenChannel(bob, carol, p) @@ -891,7 +891,7 @@ func acceptChannel(t *testing.T, zeroConf bool, stream rpc.AcceptorClient) { // testZeroConfReorg tests that a reorg does not cause a zero-conf channel to // be deleted from the channel graph. This was previously the case due to logic // in the function DisconnectBlockAtHeight. -func testZeroConfReorg(ht *lntemp.HarnessTest) { +func testZeroConfReorg(ht *lntest.HarnessTest) { if ht.IsNeutrinoBackend() { ht.Skipf("skipping zero-conf reorg test for neutrino backend") } @@ -925,7 +925,7 @@ func testZeroConfReorg(ht *lntemp.HarnessTest) { go acceptChannel(ht.T, true, acceptStream) // Open a private zero-conf anchors channel of 1M satoshis. - params := lntemp.OpenChannelParams{ + params := lntest.OpenChannelParams{ Amt: btcutil.Amount(1_000_000), CommitmentType: lnrpc.CommitmentType_ANCHORS, ZeroConf: true, @@ -959,7 +959,7 @@ func testZeroConfReorg(ht *lntemp.HarnessTest) { // First, we'll setup a new miner that we can use to cause a reorg. tempLogDir := ".tempminerlogs" logFilename := "output-open_channel_reorg-temp_miner.log" - tempMiner := lntemp.NewTempMiner( + tempMiner := lntest.NewTempMiner( ht.Context(), ht.T, tempLogDir, logFilename, ) defer tempMiner.Stop() diff --git a/lntemp/README.md b/lntest/README.md similarity index 100% rename from lntemp/README.md rename to lntest/README.md diff --git a/lntest/bitcoind_common.go b/lntest/bitcoind_common.go index 320d89345..8cac2e5af 100644 --- a/lntest/bitcoind_common.go +++ b/lntest/bitcoind_common.go @@ -14,7 +14,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/rpcclient" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest/node" ) // logDirPattern is the pattern of the name of the temporary log directory. diff --git a/lntest/btcd.go b/lntest/btcd.go index 817936709..be5f52f58 100644 --- a/lntest/btcd.go +++ b/lntest/btcd.go @@ -15,7 +15,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/integration/rpctest" "github.com/btcsuite/btcd/rpcclient" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest/node" ) // logDirPattern is the pattern of the name of the temporary log directory. diff --git a/lntemp/fee_service.go b/lntest/fee_service.go similarity index 98% rename from lntemp/fee_service.go rename to lntest/fee_service.go index e89809c71..a707ff2a3 100644 --- a/lntemp/fee_service.go +++ b/lntest/fee_service.go @@ -1,4 +1,4 @@ -package lntemp +package lntest import ( "context" @@ -9,7 +9,7 @@ import ( "sync" "testing" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/stretchr/testify/require" ) diff --git a/lntemp/harness.go b/lntest/harness.go similarity index 99% rename from lntemp/harness.go rename to lntest/harness.go index 9a656723c..23c7ab9a0 100644 --- a/lntemp/harness.go +++ b/lntest/harness.go @@ -1,4 +1,4 @@ -package lntemp +package lntest import ( "context" @@ -17,8 +17,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntemp/rpc" + "github.com/lightningnetwork/lnd/lntest/node" + "github.com/lightningnetwork/lnd/lntest/rpc" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwire" diff --git a/lntemp/harness_assertion.go b/lntest/harness_assertion.go similarity index 99% rename from lntemp/harness_assertion.go rename to lntest/harness_assertion.go index 9b61c9186..7e94d371f 100644 --- a/lntemp/harness_assertion.go +++ b/lntest/harness_assertion.go @@ -1,4 +1,4 @@ -package lntemp +package lntest import ( "bytes" @@ -23,8 +23,8 @@ import ( "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntemp/rpc" + "github.com/lightningnetwork/lnd/lntest/node" + "github.com/lightningnetwork/lnd/lntest/rpc" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lntypes" "github.com/stretchr/testify/require" diff --git a/lntemp/harness_miner.go b/lntest/harness_miner.go similarity index 99% rename from lntemp/harness_miner.go rename to lntest/harness_miner.go index 851423438..53ef4154d 100644 --- a/lntemp/harness_miner.go +++ b/lntest/harness_miner.go @@ -1,4 +1,4 @@ -package lntemp +package lntest import ( "bytes" @@ -18,7 +18,7 @@ import ( "github.com/btcsuite/btcd/integration/rpctest" "github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcd/wire" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/stretchr/testify/require" ) diff --git a/lntemp/harness_node_manager.go b/lntest/harness_node_manager.go similarity index 99% rename from lntemp/harness_node_manager.go rename to lntest/harness_node_manager.go index 4ed365a33..bb8e8bdd7 100644 --- a/lntemp/harness_node_manager.go +++ b/lntest/harness_node_manager.go @@ -1,4 +1,4 @@ -package lntemp +package lntest import ( "context" @@ -8,7 +8,7 @@ import ( "testing" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/lightningnetwork/lnd/lntest/wait" ) diff --git a/lntemp/harness_setup.go b/lntest/harness_setup.go similarity index 95% rename from lntemp/harness_setup.go rename to lntest/harness_setup.go index 4c14a4479..666f59b2b 100644 --- a/lntemp/harness_setup.go +++ b/lntest/harness_setup.go @@ -1,4 +1,4 @@ -package lntemp +package lntest import ( "context" @@ -6,8 +6,7 @@ import ( "testing" "github.com/btcsuite/btcd/integration/rpctest" - "github.com/lightningnetwork/lnd/lntemp/node" - "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/stretchr/testify/require" ) @@ -85,7 +84,7 @@ func prepareMiner(ctxt context.Context, t *testing.T) *HarnessMiner { func prepareChainBackend(t *testing.T, minerAddr string) (node.BackendConfig, func()) { - chainBackend, cleanUp, err := lntest.NewBackend( + chainBackend, cleanUp, err := NewBackend( minerAddr, harnessNetParams, ) require.NoError(t, err, "new backend") diff --git a/lntest/neutrino.go b/lntest/neutrino.go index 9ea18a4db..11f13612f 100644 --- a/lntest/neutrino.go +++ b/lntest/neutrino.go @@ -7,7 +7,7 @@ import ( "fmt" "github.com/btcsuite/btcd/chaincfg" - "github.com/lightningnetwork/lnd/lntemp/node" + "github.com/lightningnetwork/lnd/lntest/node" ) // NeutrinoBackendConfig is an implementation of the BackendConfig interface diff --git a/lntemp/node/config.go b/lntest/node/config.go similarity index 100% rename from lntemp/node/config.go rename to lntest/node/config.go diff --git a/lntemp/node/harness_node.go b/lntest/node/harness_node.go similarity index 99% rename from lntemp/node/harness_node.go rename to lntest/node/harness_node.go index ebba81e84..db7d78857 100644 --- a/lntemp/node/harness_node.go +++ b/lntest/node/harness_node.go @@ -18,7 +18,7 @@ import ( "github.com/jackc/pgx/v4/pgxpool" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp/rpc" + "github.com/lightningnetwork/lnd/lntest/rpc" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/macaroons" "google.golang.org/grpc" diff --git a/lntemp/node/state.go b/lntest/node/state.go similarity index 99% rename from lntemp/node/state.go rename to lntest/node/state.go index 2c3c45f02..bab178bd0 100644 --- a/lntemp/node/state.go +++ b/lntest/node/state.go @@ -9,7 +9,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" - "github.com/lightningnetwork/lnd/lntemp/rpc" + "github.com/lightningnetwork/lnd/lntest/rpc" "github.com/lightningnetwork/lnd/lnutils" ) diff --git a/lntemp/node/watcher.go b/lntest/node/watcher.go similarity index 99% rename from lntemp/node/watcher.go rename to lntest/node/watcher.go index dd36e3202..e89bcf6d1 100644 --- a/lntemp/node/watcher.go +++ b/lntest/node/watcher.go @@ -11,7 +11,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lntemp/rpc" + "github.com/lightningnetwork/lnd/lntest/rpc" "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnutils" ) diff --git a/lntemp/rpc/chain_kit.go b/lntest/rpc/chain_kit.go similarity index 100% rename from lntemp/rpc/chain_kit.go rename to lntest/rpc/chain_kit.go diff --git a/lntemp/rpc/chain_notifier.go b/lntest/rpc/chain_notifier.go similarity index 100% rename from lntemp/rpc/chain_notifier.go rename to lntest/rpc/chain_notifier.go diff --git a/lntemp/rpc/harness_rpc.go b/lntest/rpc/harness_rpc.go similarity index 100% rename from lntemp/rpc/harness_rpc.go rename to lntest/rpc/harness_rpc.go diff --git a/lntemp/rpc/invoices.go b/lntest/rpc/invoices.go similarity index 100% rename from lntemp/rpc/invoices.go rename to lntest/rpc/invoices.go diff --git a/lntemp/rpc/lnd.go b/lntest/rpc/lnd.go similarity index 100% rename from lntemp/rpc/lnd.go rename to lntest/rpc/lnd.go diff --git a/lntemp/rpc/neutrino_kit.go b/lntest/rpc/neutrino_kit.go similarity index 100% rename from lntemp/rpc/neutrino_kit.go rename to lntest/rpc/neutrino_kit.go diff --git a/lntemp/rpc/peers.go b/lntest/rpc/peers.go similarity index 100% rename from lntemp/rpc/peers.go rename to lntest/rpc/peers.go diff --git a/lntemp/rpc/router.go b/lntest/rpc/router.go similarity index 100% rename from lntemp/rpc/router.go rename to lntest/rpc/router.go diff --git a/lntemp/rpc/signer.go b/lntest/rpc/signer.go similarity index 100% rename from lntemp/rpc/signer.go rename to lntest/rpc/signer.go diff --git a/lntemp/rpc/state.go b/lntest/rpc/state.go similarity index 100% rename from lntemp/rpc/state.go rename to lntest/rpc/state.go diff --git a/lntemp/rpc/wallet_kit.go b/lntest/rpc/wallet_kit.go similarity index 100% rename from lntemp/rpc/wallet_kit.go rename to lntest/rpc/wallet_kit.go diff --git a/lntemp/rpc/wallet_unlocker.go b/lntest/rpc/wallet_unlocker.go similarity index 100% rename from lntemp/rpc/wallet_unlocker.go rename to lntest/rpc/wallet_unlocker.go diff --git a/lntemp/rpc/watchtower.go b/lntest/rpc/watchtower.go similarity index 100% rename from lntemp/rpc/watchtower.go rename to lntest/rpc/watchtower.go diff --git a/lntemp/utils.go b/lntest/utils.go similarity index 99% rename from lntemp/utils.go rename to lntest/utils.go index acb5b77e5..23cd41a14 100644 --- a/lntemp/utils.go +++ b/lntest/utils.go @@ -1,4 +1,4 @@ -package lntemp +package lntest import ( "fmt" From 8b9ccfe3105f51cbdfc55de7f2b897699a25e4fd Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Thu, 20 Oct 2022 19:55:19 +0800 Subject: [PATCH 12/45] itest: fix test `async_bidirectional_payments` --- itest/lnd_payment_test.go | 21 +++++++++++++++++---- lntest/wait/timeouts_darwin.go | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/itest/lnd_payment_test.go b/itest/lnd_payment_test.go index e8986f363..631399326 100644 --- a/itest/lnd_payment_test.go +++ b/itest/lnd_payment_test.go @@ -271,7 +271,7 @@ func runAsyncPayments(ht *lntest.HarnessTest, alice, bob *node.HarnessNode) { settled := make(chan struct{}) defer close(settled) - timeout := wait.AsyncBenchmarkTimeout * 2 + timeout := wait.AsyncBenchmarkTimeout for i := 0; i < numInvoices; i++ { payReq := bobPayReqs[i] go func() { @@ -327,8 +327,21 @@ func testBidirectionalAsyncPayments(ht *lntest.HarnessTest) { // We use new nodes here as the benchmark test creates lots of data // which can be costly to be carried on. - alice := ht.NewNode("Alice", []string{"--pending-commit-interval=3m"}) - bob := ht.NewNode("Bob", []string{"--pending-commit-interval=3m"}) + args := []string{ + // Increase the dust threshold to avoid the payments fail due + // to threshold limit reached. + "--dust-threshold=5000000", + + // Increase the pending commit interval since there are lots of + // commitment dances. + "--pending-commit-interval=5m", + + // Increase the mailbox delivery timeout as there are lots of + // ADDs going on. + "--htlcswitch.mailboxdeliverytimeout=2m", + } + alice := ht.NewNode("Alice", args) + bob := ht.NewNode("Bob", args) ht.EnsureConnected(alice, bob) ht.FundCoins(btcutil.SatoshiPerBitcoin, alice) @@ -375,7 +388,7 @@ func testBidirectionalAsyncPayments(ht *lntest.HarnessTest) { settled := make(chan struct{}) defer close(settled) - timeout := wait.AsyncBenchmarkTimeout * 4 + timeout := wait.AsyncBenchmarkTimeout * 2 send := func(node *node.HarnessNode, payReq string) { req := &routerrpc.SendPaymentRequest{ PaymentRequest: payReq, diff --git a/lntest/wait/timeouts_darwin.go b/lntest/wait/timeouts_darwin.go index f08cd215a..5cfc16bd7 100644 --- a/lntest/wait/timeouts_darwin.go +++ b/lntest/wait/timeouts_darwin.go @@ -25,7 +25,7 @@ const ( // AsyncBenchmarkTimeout is the timeout used when running the async // payments benchmark. This timeout takes considerably longer on darwin // after go1.12 corrected its use of fsync. - AsyncBenchmarkTimeout = time.Minute * 3 + AsyncBenchmarkTimeout = time.Minute * 5 // NodeStartTimeout is the timeout value when waiting for a node to // become fully started. From a080375b7df715038b789d866f711645ef5b531c Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 21 Oct 2022 18:19:25 +0800 Subject: [PATCH 13/45] itest: remove unnecessary shutdown --- itest/lnd_onchain_test.go | 3 --- itest/lnd_psbt_test.go | 3 --- itest/lnd_res_handoff_test.go | 1 - 3 files changed, 7 deletions(-) diff --git a/itest/lnd_onchain_test.go b/itest/lnd_onchain_test.go index a95b2f325..dbc01690e 100644 --- a/itest/lnd_onchain_test.go +++ b/itest/lnd_onchain_test.go @@ -355,10 +355,7 @@ func testAnchorThirdPartySpend(ht *lntest.HarnessTest) { // lnd binary. args := lntest.NodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) alice := ht.NewNode("Alice", args) - defer ht.Shutdown(alice) - bob := ht.NewNode("Bob", args) - defer ht.Shutdown(bob) ht.EnsureConnected(alice, bob) diff --git a/itest/lnd_psbt_test.go b/itest/lnd_psbt_test.go index d2673f86e..80fe55189 100644 --- a/itest/lnd_psbt_test.go +++ b/itest/lnd_psbt_test.go @@ -421,10 +421,7 @@ func testPsbtChanFundingSingleStep(ht *lntest.HarnessTest) { // between for this test. But in this case both nodes have an empty // wallet. carol := ht.NewNode("carol", args) - defer ht.Shutdown(carol) - dave := ht.NewNode("dave", args) - defer ht.Shutdown(dave) alice := ht.Alice ht.FundCoins(btcutil.SatoshiPerBitcoin, alice) diff --git a/itest/lnd_res_handoff_test.go b/itest/lnd_res_handoff_test.go index e6c10b48f..0a85cd77d 100644 --- a/itest/lnd_res_handoff_test.go +++ b/itest/lnd_res_handoff_test.go @@ -29,7 +29,6 @@ func testResHandoff(ht *lntest.HarnessTest) { // trigger the behavior of checkRemoteDanglingActions in the // contractcourt. This will cause Bob to fail the HTLC back to Alice. carol := ht.NewNode("Carol", []string{"--hodl.commit"}) - defer ht.Shutdown(carol) // Connect Bob to Carol. ht.ConnectNodes(bob, carol) From 2bc6aabf966bc64ca7880a14fafa608b3979c1bc Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Fri, 12 Aug 2022 15:49:54 +0800 Subject: [PATCH 14/45] itest: fix `make lint` This commit fixes the issues reported by the linter. --- itest/lnd_channel_backup_test.go | 18 ++++--- itest/lnd_channel_force_close_test.go | 45 ++++++++--------- itest/lnd_channel_policy_test.go | 8 ++-- itest/lnd_forward_interceptor_test.go | 1 + itest/lnd_funding_test.go | 8 ++-- itest/lnd_misc_test.go | 3 +- itest/lnd_multi-hop-error-propagation_test.go | 1 - itest/lnd_multi-hop_test.go | 4 +- itest/lnd_onchain_test.go | 2 + itest/lnd_psbt_test.go | 35 -------------- itest/lnd_routing_test.go | 5 +- itest/lnd_switch_test.go | 9 ++-- itest/lnd_taproot_test.go | 48 +++++-------------- itest/lnd_wipe_fwdpkgs_test.go | 2 - itest/lnd_zero_conf_test.go | 1 + lntest/btcd.go | 13 +++-- lntest/fee_service.go | 4 ++ lntest/harness.go | 21 ++++++-- lntest/harness_assertion.go | 3 ++ lntest/harness_miner.go | 8 ++++ lntest/harness_node_manager.go | 2 +- lntest/node/config.go | 5 +- lntest/node/harness_node.go | 11 +++-- lntest/utils.go | 12 +++-- 24 files changed, 127 insertions(+), 142 deletions(-) diff --git a/itest/lnd_channel_backup_test.go b/itest/lnd_channel_backup_test.go index acd4b9c5b..6b5b76788 100644 --- a/itest/lnd_channel_backup_test.go +++ b/itest/lnd_channel_backup_test.go @@ -376,6 +376,8 @@ func testChannelBackupRestoreBasic(ht *lntest.HarnessTest) { // Now that we have Dave's backup file, we'll // create a new nodeRestorer that will restore // using the on-disk channel.backup. + // + //nolint:lll backup := &lnrpc.RestoreChanBackupRequest_MultiChanBackup{ MultiChanBackup: multi, } @@ -606,7 +608,7 @@ func runChanRestoreScenarioCommitTypes(ht *lntest.HarnessTest, _, minerHeight := ht.Miner.GetBestBlock() thawHeight := uint32(minerHeight + thawHeightDelta) - fundingShim, _, _ = deriveFundingShim( + fundingShim, _ = deriveFundingShim( ht, dave, carol, crs.params.Amt, thawHeight, true, ) crs.params.FundingShim = fundingShim @@ -1022,17 +1024,20 @@ func testExportChannelBackup(ht *lntest.HarnessTest) { require.NoError(ht, err, "timeout checking num single backup") } - assertMultiBackupFound := func() func(bool, map[wire.OutPoint]struct{}) { + assertMultiBackupFound := func() func(bool, + map[wire.OutPoint]struct{}) { + chanSnapshot := carol.RPC.ExportAllChanBackups() return func(found bool, chanPoints map[wire.OutPoint]struct{}) { + num := len(chanSnapshot.MultiChanBackup.MultiChanBackup) + switch { case found && chanSnapshot.MultiChanBackup == nil: require.Fail(ht, "multi-backup not present") case !found && chanSnapshot.MultiChanBackup != nil && - (len(chanSnapshot.MultiChanBackup.MultiChanBackup) != - chanbackup.NilMultiSizePacked): + num != chanbackup.NilMultiSizePacked: require.Fail(ht, "found multi-backup when "+ "non should be found") @@ -1295,8 +1300,9 @@ func createLegacyRevocationChannel(ht *lntest.HarnessTest, } fundResp := from.RPC.FundPsbt(fundReq) - // We have a PSBT that has no witness data yet, which is exactly what we - // need for the next step of verifying the PSBT with the funding intents. + // We have a PSBT that has no witness data yet, which is exactly what + // we need for the next step of verifying the PSBT with the funding + // intents. msg := &lnrpc.FundingTransitionMsg{ Trigger: &lnrpc.FundingTransitionMsg_PsbtVerify{ PsbtVerify: &lnrpc.FundingPsbtVerify{ diff --git a/itest/lnd_channel_force_close_test.go b/itest/lnd_channel_force_close_test.go index f7b77ec88..a1c36e8d6 100644 --- a/itest/lnd_channel_force_close_test.go +++ b/itest/lnd_channel_force_close_test.go @@ -602,6 +602,18 @@ func channelForceClosureTest(ht *lntest.HarnessTest, // checkForceClosedChannelNumHtlcs verifies that a force closed channel // has the proper number of htlcs. + checkPendingChannelNumHtlcs := func( + forceClose lntest.PendingForceClose) error { + + if len(forceClose.PendingHtlcs) != numInvoices { + return fmt.Errorf("expected force closed channel to "+ + "have %d pending htlcs, found %d instead", + numInvoices, len(forceClose.PendingHtlcs)) + } + + return nil + } + err = wait.NoError(func() error { // Now that the commit output has been fully swept, check to // see that the channel remains open for the pending htlc @@ -613,7 +625,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest, // The commitment funds will have been recovered after the // commit txn was included in the last block. The htlc funds // will be shown in limbo. - err := checkPendingChannelNumHtlcs(forceClose, numInvoices) + err := checkPendingChannelNumHtlcs(forceClose) if err != nil { return err } @@ -661,7 +673,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest, // We should now be at the block just before the utxo nursery // will attempt to broadcast the htlc timeout transactions. - err = checkPendingChannelNumHtlcs(forceClose, numInvoices) + err = checkPendingChannelNumHtlcs(forceClose) if err != nil { return err } @@ -704,9 +716,9 @@ func channelForceClosureTest(ht *lntest.HarnessTest, // Retrieve each htlc timeout txn from the mempool, and ensure it is // well-formed. This entails verifying that each only spends from - // output, and that that output is from the commitment txn. In case - // this is an anchor channel, the transactions are aggregated by the - // sweeper into one. + // output, and that output is from the commitment txn. In case this is + // an anchor channel, the transactions are aggregated by the sweeper + // into one. numInputs := 1 if channelType == lnrpc.CommitmentType_ANCHORS { numInputs = numInvoices + 1 @@ -798,7 +810,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest, // We record the htlc amount less fees here, so that we know // what value to expect for the second stage of our htlc - // htlc resolution. + // resolution. htlcLessFees = uint64(outputs[0].Value) } @@ -840,7 +852,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest, return fmt.Errorf("htlc funds should still be in limbo") } - return checkPendingChannelNumHtlcs(forceClose, numInvoices) + return checkPendingChannelNumHtlcs(forceClose) }, defaultTimeout) require.NoError(ht, err, "timeout while checking force closed channel") @@ -915,7 +927,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest, forceClose := ht.AssertChannelPendingForceClose( alice, chanPoint, ) - err := checkPendingChannelNumHtlcs(forceClose, numInvoices) + err := checkPendingChannelNumHtlcs(forceClose) if err != nil { return err } @@ -1111,23 +1123,6 @@ func checkCommitmentMaturity(forceClose lntest.PendingForceClose, return nil } -// checkForceClosedChannelNumHtlcs verifies that a force closed channel has the -// proper number of htlcs. -// -// NOTE: only used in current test file. -func checkPendingChannelNumHtlcs( - forceClose *lnrpc.PendingChannelsResponse_ForceClosedChannel, - expectedNumHtlcs int) error { - - if len(forceClose.PendingHtlcs) != expectedNumHtlcs { - return fmt.Errorf("expected force closed channel to have %d "+ - "pending htlcs, found %d instead", expectedNumHtlcs, - len(forceClose.PendingHtlcs)) - } - - return nil -} - // checkPendingHtlcStageAndMaturity uniformly tests all pending htlc's belonging // to a force closed channel, testing for the expected stage number, blocks till // maturity, and the maturity height. diff --git a/itest/lnd_channel_policy_test.go b/itest/lnd_channel_policy_test.go index 876e8fd68..ebabde856 100644 --- a/itest/lnd_channel_policy_test.go +++ b/itest/lnd_channel_policy_test.go @@ -167,9 +167,9 @@ func testUpdateChannelPolicy(ht *lntest.HarnessTest) { payAmt = btcutil.Amount(4) amtSat := int64(payAmt) amtMSat := int64(lnwire.NewMSatFromSatoshis(payAmt)) - routes.Routes[0].Hops[0].AmtToForward = amtSat // nolint:staticcheck + routes.Routes[0].Hops[0].AmtToForward = amtSat routes.Routes[0].Hops[0].AmtToForwardMsat = amtMSat - routes.Routes[0].Hops[1].AmtToForward = amtSat // nolint:staticcheck + routes.Routes[0].Hops[1].AmtToForward = amtSat routes.Routes[0].Hops[1].AmtToForwardMsat = amtMSat // Send the payment with the modified value. @@ -200,9 +200,9 @@ func testUpdateChannelPolicy(ht *lntest.HarnessTest) { payAmt = btcutil.Amount(5) amtSat = int64(payAmt) amtMSat = int64(lnwire.NewMSatFromSatoshis(payAmt)) - routes.Routes[0].Hops[0].AmtToForward = amtSat // nolint:staticcheck + routes.Routes[0].Hops[0].AmtToForward = amtSat routes.Routes[0].Hops[0].AmtToForwardMsat = amtMSat - routes.Routes[0].Hops[1].AmtToForward = amtSat // nolint:staticcheck + routes.Routes[0].Hops[1].AmtToForward = amtSat routes.Routes[0].Hops[1].AmtToForwardMsat = amtMSat // Manually set the MPP payload a new for each payment since diff --git a/itest/lnd_forward_interceptor_test.go b/itest/lnd_forward_interceptor_test.go index f0ea5b6c5..a7ecf99fa 100644 --- a/itest/lnd_forward_interceptor_test.go +++ b/itest/lnd_forward_interceptor_test.go @@ -416,6 +416,7 @@ func (c *interceptorTestScenario) prepareTestCases() []*interceptorTestCase { t.invoice = invoice t.payAddr = payReq.PaymentAddr } + return cases } diff --git a/itest/lnd_funding_test.go b/itest/lnd_funding_test.go index 432261ffb..8be4da242 100644 --- a/itest/lnd_funding_test.go +++ b/itest/lnd_funding_test.go @@ -501,7 +501,7 @@ func testExternalFundingChanPoint(ht *lntest.HarnessTest) { // a transaction that will never be published. const thawHeight uint32 = 10 const chanSize = funding.MaxBtcFundingAmount - fundingShim1, chanPoint1, _ := deriveFundingShim( + fundingShim1, chanPoint1 := deriveFundingShim( ht, carol, dave, chanSize, thawHeight, false, ) ht.OpenChannelAssertPending( @@ -517,7 +517,7 @@ func testExternalFundingChanPoint(ht *lntest.HarnessTest) { // externally funded, we should still be able to open another one. Let's // do exactly that now. For this one we publish the transaction so we // can mine it later. - fundingShim2, chanPoint2, _ := deriveFundingShim( + fundingShim2, chanPoint2 := deriveFundingShim( ht, carol, dave, chanSize, thawHeight, true, ) @@ -801,7 +801,7 @@ func testBatchChanFunding(ht *lntest.HarnessTest) { func deriveFundingShim(ht *lntest.HarnessTest, carol, dave *node.HarnessNode, chanSize btcutil.Amount, thawHeight uint32, publish bool) (*lnrpc.FundingShim, - *lnrpc.ChannelPoint, *chainhash.Hash) { + *lnrpc.ChannelPoint) { keyLoc := &signrpc.KeyLocator{KeyFamily: 9999} carolFundingKey := carol.RPC.DeriveKey(keyLoc) @@ -887,5 +887,5 @@ func deriveFundingShim(ht *lntest.HarnessTest, } fundingShim.GetChanPointShim().RemoteKey = daveFundingKey.RawKeyBytes - return fundingShim, chanPoint, txid + return fundingShim, chanPoint } diff --git a/itest/lnd_misc_test.go b/itest/lnd_misc_test.go index a0f0e4616..577462afe 100644 --- a/itest/lnd_misc_test.go +++ b/itest/lnd_misc_test.go @@ -964,7 +964,8 @@ func testListAddresses(ht *lntest.HarnessTest) { }) generatedAddr[resp.Address] = addressDetails{ Balance: 400_000, - Type: walletrpc.AddressType_HYBRID_NESTED_WITNESS_PUBKEY_HASH, + Type: walletrpc. + AddressType_HYBRID_NESTED_WITNESS_PUBKEY_HASH, } for addr, addressDetail := range generatedAddr { diff --git a/itest/lnd_multi-hop-error-propagation_test.go b/itest/lnd_multi-hop-error-propagation_test.go index 63766c738..3941accb0 100644 --- a/itest/lnd_multi-hop-error-propagation_test.go +++ b/itest/lnd_multi-hop-error-propagation_test.go @@ -46,7 +46,6 @@ func testHtlcErrorPropagation(ht *lntest.HarnessTest) { // channel between them so we have the topology: Alice -> Bob -> Carol. // The channel created will be of lower capacity that the one created // above. - const bobChanAmt = funding.MaxBtcFundingAmount chanPointBob := ht.OpenChannel( bob, carol, lntest.OpenChannelParams{Amt: chanAmt}, ) diff --git a/itest/lnd_multi-hop_test.go b/itest/lnd_multi-hop_test.go index f47031635..0f562ed9b 100644 --- a/itest/lnd_multi-hop_test.go +++ b/itest/lnd_multi-hop_test.go @@ -1774,7 +1774,7 @@ func createThreeHopNetwork(ht *lntest.HarnessTest, if c == lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE { _, minerHeight := ht.Miner.GetBestBlock() thawHeight = uint32(minerHeight + thawHeightDelta) - aliceFundingShim, _, _ = deriveFundingShim( + aliceFundingShim, _ = deriveFundingShim( ht, alice, bob, chanAmt, thawHeight, true, ) } @@ -1807,7 +1807,7 @@ func createThreeHopNetwork(ht *lntest.HarnessTest, // open, our topology looks like: A -> B -> C. var bobFundingShim *lnrpc.FundingShim if c == lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE { - bobFundingShim, _, _ = deriveFundingShim( + bobFundingShim, _ = deriveFundingShim( ht, bob, carol, chanAmt, thawHeight, true, ) } diff --git a/itest/lnd_onchain_test.go b/itest/lnd_onchain_test.go index dbc01690e..b9d50d5c6 100644 --- a/itest/lnd_onchain_test.go +++ b/itest/lnd_onchain_test.go @@ -172,6 +172,7 @@ func runCPFP(ht *lntest.HarnessTest, alice, bob *node.HarnessNode) { return fmt.Errorf("expected 0 pending sweeps, found %d", len(resp.PendingSweeps)) } + return nil }, defaultTimeout) require.NoError(ht, err, "timeout checking bob's pending sweeps") @@ -276,6 +277,7 @@ func testAnchorReservedValue(ht *lntest.HarnessTest) { } balance = resp.TotalBalance + return nil }, defaultTimeout) require.NoError(ht, err, "timeout checking alice's balance") diff --git a/itest/lnd_psbt_test.go b/itest/lnd_psbt_test.go index 80fe55189..3d3b38c5f 100644 --- a/itest/lnd_psbt_test.go +++ b/itest/lnd_psbt_test.go @@ -2,8 +2,6 @@ package itest import ( "bytes" - "context" - "fmt" "time" "github.com/btcsuite/btcd/btcec/v2" @@ -1183,39 +1181,6 @@ func deriveInternalKey(ht *lntest.HarnessTest, return keyDesc, parsedPubKey, fullDerivationPath } -// receiveChanUpdate waits until a message is received on the stream or the -// context is canceled. The context must have a timeout or must be canceled -// in case no message is received, otherwise this function will block forever. -func receiveChanUpdate(ctx context.Context, - stream lnrpc.Lightning_OpenChannelClient) (*lnrpc.OpenStatusUpdate, - error) { - - chanMsg := make(chan *lnrpc.OpenStatusUpdate) - errChan := make(chan error) - go func() { - // Consume one message. This will block until the message is - // received. - resp, err := stream.Recv() - if err != nil { - errChan <- err - return - } - chanMsg <- resp - }() - - select { - case <-ctx.Done(): - return nil, fmt.Errorf("timeout reached before chan pending " + - "update sent") - - case err := <-errChan: - return nil, err - - case updateMsg := <-chanMsg: - return updateMsg, nil - } -} - // sendAllCoinsToAddrType sweeps all coins from the wallet and sends them to a // new address of the given type. func sendAllCoinsToAddrType(ht *lntest.HarnessTest, diff --git a/itest/lnd_routing_test.go b/itest/lnd_routing_test.go index 4d6746279..5f28acba2 100644 --- a/itest/lnd_routing_test.go +++ b/itest/lnd_routing_test.go @@ -476,6 +476,8 @@ func testSendToRouteErrorPropagation(ht *lntest.HarnessTest) { // testPrivateChannels tests that a private channel can be used for // routing by the two endpoints of the channel, but is not known by // the rest of the nodes in the graph. +// +//nolint:dupword func testPrivateChannels(ht *lntest.HarnessTest) { const chanAmt = btcutil.Amount(100000) @@ -1285,7 +1287,8 @@ func testRouteFeeCutoff(ht *lntest.HarnessTest) { case *lnrpc.FeeLimit_Fixed: sendReq.FeeLimitMsat = 1000 * limit.Fixed case *lnrpc.FeeLimit_Percent: - sendReq.FeeLimitMsat = 1000 * paymentAmt * limit.Percent / 100 + sendReq.FeeLimitMsat = 1000 * paymentAmt * + limit.Percent / 100 } result := ht.SendPaymentAssertSettled(alice, sendReq) diff --git a/itest/lnd_switch_test.go b/itest/lnd_switch_test.go index 0bf71294a..fc3a6cd5b 100644 --- a/itest/lnd_switch_test.go +++ b/itest/lnd_switch_test.go @@ -131,11 +131,6 @@ func testSwitchOfflineDelivery(ht *lntest.HarnessTest) { // Wait until all outstanding htlcs in the network have been settled. s.assertHTLCs(ht, 0) - // When asserting the amount of satoshis moved, we'll factor in the - // default base fee, as we didn't modify the fee structure when - // creating the seed nodes in the network. - const baseFee = 1 - // At this point all the channels within our proto network should be // shifted by 5k satoshis in the direction of Carol, the sink within the // payment flow generated above. The order of asserts corresponds to @@ -174,6 +169,8 @@ func testSwitchOfflineDelivery(ht *lntest.HarnessTest) { // 3. Carol --- Dave X Alice <-- Bob settle last hop // 4. Carol --- Dave X X Bob restart Alice // 5. Carol <-- Dave <-- Alice --- Bob expect settle to propagate +// +//nolint:dupword func testSwitchOfflineDeliveryPersistence(ht *lntest.HarnessTest) { // Setup our test scenario. We should now have four nodes running with // three channels. @@ -260,6 +257,8 @@ func testSwitchOfflineDeliveryPersistence(ht *lntest.HarnessTest) { // 3. Carol --- Dave X Alice <-- Bob settle last hop // 4. Carol --- Dave X X shutdown Bob, restart Alice // 5. Carol <-- Dave <-- Alice X expect settle to propagate +// +//nolint:dupword func testSwitchOfflineDeliveryOutgoingOffline(ht *lntest.HarnessTest) { // Setup our test scenario. We should now have four nodes running with // three channels. Note that we won't call the cleanUp function here as diff --git a/itest/lnd_taproot_test.go b/itest/lnd_taproot_test.go index 82f8c86fb..c03c1b5e0 100644 --- a/itest/lnd_taproot_test.go +++ b/itest/lnd_taproot_test.go @@ -260,9 +260,7 @@ func testTaprootSignOutputRawScriptSpend(ht *lntest.HarnessTest, require.NoError(ht, err) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) // Spend the output again, this time back to a p2wkh address. p2wkhAddr, p2wkhPkScript := newAddrWithScript( @@ -413,9 +411,7 @@ func testTaprootSignOutputRawKeySpendBip86(ht *lntest.HarnessTest, taprootKey := txscript.ComputeTaprootKeyNoScript(internalKey) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) // Spend the output again, this time back to a p2wkh address. p2wkhAddr, p2wkhPkScript := newAddrWithScript( @@ -514,9 +510,7 @@ func testTaprootSignOutputRawKeySpendRootHash(ht *lntest.HarnessTest, taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:]) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) // Spend the output again, this time back to a p2wkh address. p2wkhAddr, p2wkhPkScript := newAddrWithScript( @@ -601,9 +595,7 @@ func testTaprootMuSig2KeySpendBip86(ht *lntest.HarnessTest, ) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) // Spend the output again, this time back to a p2wkh address. p2wkhAddr, p2wkhPkScript := newAddrWithScript( @@ -733,9 +725,7 @@ func testTaprootMuSig2KeySpendRootHash(ht *lntest.HarnessTest, ) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) // Spend the output again, this time back to a p2wkh address. p2wkhAddr, p2wkhPkScript := newAddrWithScript( @@ -870,9 +860,7 @@ func testTaprootMuSig2ScriptSpend(ht *lntest.HarnessTest, tapscript := input.TapscriptFullTree(internalKey, leaf1) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) // Spend the output again, this time back to a p2wkh address. p2wkhAddr, p2wkhPkScript := newAddrWithScript( @@ -951,9 +939,7 @@ func testTaprootMuSig2CombinedLeafKeySpend(ht *lntest.HarnessTest, require.NoError(ht, err) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) // Spend the output again, this time back to a p2wkh address. p2wkhAddr, p2wkhPkScript := newAddrWithScript( @@ -1151,9 +1137,7 @@ func testTaprootImportTapscriptFullTree(ht *lntest.HarnessTest, require.Equal(ht, calculatedAddr.String(), importResp.P2TrAddress) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) p2trOutputRPC := &lnrpc.OutPoint{ TxidBytes: p2trOutpoint.Hash[:], OutputIndex: p2trOutpoint.Index, @@ -1221,9 +1205,7 @@ func testTaprootImportTapscriptPartialReveal(ht *lntest.HarnessTest, require.Equal(ht, calculatedAddr.String(), importResp.P2TrAddress) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) p2trOutputRPC := &lnrpc.OutPoint{ TxidBytes: p2trOutpoint.Hash[:], @@ -1280,9 +1262,7 @@ func testTaprootImportTapscriptRootHashOnly(ht *lntest.HarnessTest, require.Equal(ht, calculatedAddr.String(), importResp.P2TrAddress) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) p2trOutputRPC := &lnrpc.OutPoint{ TxidBytes: p2trOutpoint.Hash[:], @@ -1339,9 +1319,7 @@ func testTaprootImportTapscriptFullKey(ht *lntest.HarnessTest, require.Equal(ht, calculatedAddr.String(), importResp.P2TrAddress) // Send some coins to the generated tapscript address. - p2trOutpoint, p2trPkScript := sendToTaprootOutput( - ht, alice, taprootKey, testAmount, - ) + p2trOutpoint, p2trPkScript := sendToTaprootOutput(ht, alice, taprootKey) p2trOutputRPC := &lnrpc.OutPoint{ TxidBytes: p2trOutpoint.Hash[:], @@ -1480,7 +1458,7 @@ func newAddrWithScript(ht *lntest.HarnessTest, node *node.HarnessNode, // sendToTaprootOutput sends coins to a p2tr output of the given taproot key and // mines a block to confirm the coins. func sendToTaprootOutput(ht *lntest.HarnessTest, hn *node.HarnessNode, - taprootKey *btcec.PublicKey, amt int64) (wire.OutPoint, []byte) { + taprootKey *btcec.PublicKey) (wire.OutPoint, []byte) { tapScriptAddr, err := btcutil.NewAddressTaproot( schnorr.SerializePubKey(taprootKey), harnessNetParams, @@ -1492,7 +1470,7 @@ func sendToTaprootOutput(ht *lntest.HarnessTest, hn *node.HarnessNode, // Send some coins to the generated tapscript address. req := &lnrpc.SendCoinsRequest{ Addr: tapScriptAddr.String(), - Amount: amt, + Amount: testAmount, } hn.RPC.SendCoins(req) diff --git a/itest/lnd_wipe_fwdpkgs_test.go b/itest/lnd_wipe_fwdpkgs_test.go index 35953f5cb..0e3a74d7b 100644 --- a/itest/lnd_wipe_fwdpkgs_test.go +++ b/itest/lnd_wipe_fwdpkgs_test.go @@ -9,8 +9,6 @@ import ( "github.com/stretchr/testify/require" ) -type pendingChan *lnrpc.PendingChannelsResponse_PendingChannel - // testWipeForwardingPackagesLocal tests that when a channel is closed, either // through local force close, remote close, or coop close, all the forwarding // packages of that particular channel are deleted. The test creates a diff --git a/itest/lnd_zero_conf_test.go b/itest/lnd_zero_conf_test.go index 3eae1ebe9..a4838165f 100644 --- a/itest/lnd_zero_conf_test.go +++ b/itest/lnd_zero_conf_test.go @@ -312,6 +312,7 @@ func optionScidAliasScenario(ht *lntest.HarnessTest, chantype, private bool) { require.Len(ht, decodedReq.RouteHints, 0) payReq := daveInvoiceResp2.PaymentRequest ht.CompletePaymentRequests(bob, []string{payReq}) + return } diff --git a/lntest/btcd.go b/lntest/btcd.go index be5f52f58..3ba613539 100644 --- a/lntest/btcd.go +++ b/lntest/btcd.go @@ -103,7 +103,7 @@ func NewBackend(miner string, netParams *chaincfg.Params) ( netParams, nil, args, node.GetBtcdBinary(), ) if err != nil { - return nil, nil, fmt.Errorf("unable to create btcd node: %v", + return nil, nil, fmt.Errorf("unable to create btcd node: %w", err) } @@ -112,11 +112,16 @@ func NewBackend(miner string, netParams *chaincfg.Params) ( // are already blocks present, which will take a bit longer than the // 1 second the default settings amount to. Doubling both values will // give us retries up to 4 seconds. - chainBackend.MaxConnRetries = rpctest.DefaultMaxConnectionRetries * 2 - chainBackend.ConnectionRetryTimeout = rpctest.DefaultConnectionRetryTimeout * 2 + const ( + maxConnRetries = rpctest.DefaultMaxConnectionRetries * 2 + connRetryTimeout = rpctest.DefaultConnectionRetryTimeout * 2 + ) + + chainBackend.MaxConnRetries = maxConnRetries + chainBackend.ConnectionRetryTimeout = connRetryTimeout if err := chainBackend.SetUp(false, 0); err != nil { - return nil, nil, fmt.Errorf("unable to set up btcd backend: %v", + return nil, nil, fmt.Errorf("unable to set up btcd backend: %w", err) } diff --git a/lntest/fee_service.go b/lntest/fee_service.go index a707ff2a3..40128b68d 100644 --- a/lntest/fee_service.go +++ b/lntest/fee_service.go @@ -61,6 +61,8 @@ var _ WebFeeService = (*FeeService)(nil) // Start spins up a go-routine to serve fee estimates. func NewFeeService(t *testing.T) *FeeService { + t.Helper() + port := node.NextAvailablePort() f := FeeService{ T: t, @@ -82,6 +84,7 @@ func NewFeeService(t *testing.T) *FeeService { Addr: listenAddr, Handler: mux, } + return &f } @@ -123,6 +126,7 @@ func (f *FeeService) Stop() error { require.NoError(f, err, "cannot stop fee api") f.wg.Wait() + return nil } diff --git a/lntest/harness.go b/lntest/harness.go index 23c7ab9a0..e72f7abfe 100644 --- a/lntest/harness.go +++ b/lntest/harness.go @@ -37,6 +37,10 @@ const ( // numBlocksOpenChannel specifies the number of blocks mined when // opening a channel. numBlocksOpenChannel = 6 + + // lndErrorChanSize specifies the buffer size used to receive errors + // from lnd process. + lndErrorChanSize = 10 ) // TestCase defines a test case that's been used in the integration test. @@ -84,7 +88,7 @@ type HarnessTest struct { // runCtx is a context with cancel method. It's used to signal when the // node needs to quit, and used as the parent context when spawning // children contexts for RPC requests. - runCtx context.Context + runCtx context.Context //nolint:containedctx cancel context.CancelFunc // stopChainBackend points to the cleanup function returned by the @@ -101,10 +105,13 @@ type HarnessTest struct { func NewHarnessTest(t *testing.T, lndBinary string, feeService WebFeeService, dbBackend node.DatabaseBackend) *HarnessTest { + t.Helper() + // Create the run context. ctxt, cancel := context.WithCancel(context.Background()) manager := newNodeManager(lndBinary, dbBackend) + return &HarnessTest{ T: t, manager: manager, @@ -113,7 +120,7 @@ func NewHarnessTest(t *testing.T, lndBinary string, feeService WebFeeService, cancel: cancel, // We need to use buffered channel here as we don't want to // block sending errors. - lndErrorChan: make(chan error, 10), + lndErrorChan: make(chan error, lndErrorChanSize), } } @@ -188,6 +195,8 @@ func (h *HarnessTest) SetupStandbyNodes() { Type: lnrpc.AddressType_WITNESS_PUBKEY_HASH, } + const initialFund = 10 * btcutil.SatoshiPerBitcoin + // Load up the wallets of the seeder nodes with 10 outputs of 10 BTC // each. nodes := []*node.HarnessNode{h.Alice, h.Bob} @@ -206,7 +215,7 @@ func (h *HarnessTest) SetupStandbyNodes() { output := &wire.TxOut{ PkScript: addrScript, - Value: 10 * btcutil.SatoshiPerBitcoin, + Value: initialFund, } h.Miner.SendOutput(output, defaultMinerFeeRate) } @@ -222,7 +231,7 @@ func (h *HarnessTest) SetupStandbyNodes() { h.WaitForBlockchainSync(h.Bob) // Now block until both wallets have fully synced up. - expectedBalance := int64(btcutil.SatoshiPerBitcoin * 100) + const expectedBalance = 10 * initialFund err := wait.NoError(func() error { aliceResp := h.Alice.RPC.WalletBalance() bobResp := h.Bob.RPC.WalletBalance() @@ -285,6 +294,8 @@ func (h *HarnessTest) RunTestCase(testCase *TestCase) { // resetStandbyNodes resets all standby nodes by attaching the new testing.T // and restarting them with the original config. func (h *HarnessTest) resetStandbyNodes(t *testing.T) { + t.Helper() + for _, hn := range h.manager.standbyNodes { // Inherit the testing.T. h.T = t @@ -312,7 +323,7 @@ func (h *HarnessTest) Subtest(t *testing.T) *HarnessTest { Miner: h.Miner, standbyNodes: h.standbyNodes, feeService: h.feeService, - lndErrorChan: make(chan error, 10), + lndErrorChan: make(chan error, lndErrorChanSize), } // Inherit context from the main test. diff --git a/lntest/harness_assertion.go b/lntest/harness_assertion.go index 7e94d371f..c40d6e8fe 100644 --- a/lntest/harness_assertion.go +++ b/lntest/harness_assertion.go @@ -38,6 +38,7 @@ func (h *HarnessTest) WaitForBlockchainSync(hn *node.HarnessNode) { if resp.SyncedToChain { return nil } + return fmt.Errorf("%s is not synced to chain", hn.Name()) }, DefaultTimeout) @@ -231,8 +232,10 @@ func (h *HarnessTest) AssertNumEdges(hn *node.HarnessNode, // slice. edges = chanGraph.Edges[old:] } + return nil } + return errNumNotMatched(hn.Name(), "num of channel edges", expected, total-old, total, old) }, DefaultTimeout) diff --git a/lntest/harness_miner.go b/lntest/harness_miner.go index 53ef4154d..7e829c516 100644 --- a/lntest/harness_miner.go +++ b/lntest/harness_miner.go @@ -55,6 +55,7 @@ type HarnessMiner struct { // NewMiner creates a new miner using btcd backend with the default log file // dir and name. func NewMiner(ctxt context.Context, t *testing.T) *HarnessMiner { + t.Helper() return newMiner(ctxt, t, minerLogDir, minerLogFilename) } @@ -72,6 +73,8 @@ func NewTempMiner(ctxt context.Context, t *testing.T, func newMiner(ctxb context.Context, t *testing.T, minerDirName, logFilename string) *HarnessMiner { + t.Helper() + handler := &rpcclient.NotificationHandlers{} btcdBinary := node.GetBtcdBinary() baseLogPath := fmt.Sprintf("%s/%s", node.GetLogDir(), minerDirName) @@ -92,6 +95,7 @@ func newMiner(ctxb context.Context, t *testing.T, minerDirName, require.NoError(t, err, "unable to create mining node") ctxt, cancel := context.WithCancel(ctxb) + return &HarnessMiner{ T: t, Harness: miner, @@ -137,6 +141,7 @@ func (h *HarnessMiner) Stop() { func (h *HarnessMiner) GetBestBlock() (*chainhash.Hash, int32) { blockHash, height, err := h.Client.GetBestBlock() require.NoError(h, err, "failed to GetBestBlock") + return blockHash, height } @@ -145,6 +150,7 @@ func (h *HarnessMiner) GetBestBlock() (*chainhash.Hash, int32) { func (h *HarnessMiner) GetRawMempool() []*chainhash.Hash { mempool, err := h.Client.GetRawMempool() require.NoError(h, err, "unable to get mempool") + return mempool } @@ -161,6 +167,7 @@ func (h *HarnessMiner) GenerateBlocks(num uint32) []*chainhash.Hash { func (h *HarnessMiner) GetBlock(blockHash *chainhash.Hash) *wire.MsgBlock { block, err := h.Client.GetBlock(blockHash) require.NoError(h, err, "unable to get block") + return block } @@ -289,6 +296,7 @@ func (h *HarnessMiner) AssertTxInMempool(txid *chainhash.Hash) *wire.MsgTx { }, wait.MinerMempoolTimeout) require.NoError(h, err, "timeout checking mempool") + return msgTx } diff --git a/lntest/harness_node_manager.go b/lntest/harness_node_manager.go index bb8e8bdd7..9cb69a54f 100644 --- a/lntest/harness_node_manager.go +++ b/lntest/harness_node_manager.go @@ -79,7 +79,7 @@ func (nm *nodeManager) newNode(t *testing.T, name string, extraArgs []string, BackendCfg: nm.chainBackend, ExtraArgs: extraArgs, FeeURL: nm.feeServiceURL, - DbBackend: nm.dbBackend, + DBBackend: nm.dbBackend, NodeID: nm.nextNodeID(), LndBinary: nm.lndBinary, NetParams: harnessNetParams, diff --git a/lntest/node/config.go b/lntest/node/config.go index 4e632ec7e..8bee34b6f 100644 --- a/lntest/node/config.go +++ b/lntest/node/config.go @@ -116,7 +116,7 @@ type BaseNodeConfig struct { FeeURL string - DbBackend DatabaseBackend + DBBackend DatabaseBackend PostgresDsn string // NodeID is a unique ID used to identify the node. @@ -240,7 +240,7 @@ func (cfg *BaseNodeConfig) GenArgs() []string { args = append(args, "--noseedbackup") } - switch cfg.DbBackend { + switch cfg.DBBackend { case BackendEtcd: args = append(args, "--db.backend=etcd") args = append(args, "--db.etcd.embedded") @@ -349,6 +349,7 @@ func GetLogDir() string { if logSubDir != nil && *logSubDir != "" { return *logSubDir } + return "." } diff --git a/lntest/node/harness_node.go b/lntest/node/harness_node.go index db7d78857..359a328e4 100644 --- a/lntest/node/harness_node.go +++ b/lntest/node/harness_node.go @@ -116,7 +116,7 @@ func NewHarnessNode(t *testing.T, cfg *BaseNodeConfig) (*HarnessNode, error) { // Create temporary database. var dbName string - if cfg.DbBackend == BackendPostgres { + if cfg.DBBackend == BackendPostgres { var err error dbName, err = createTempPgDb() if err != nil { @@ -374,7 +374,7 @@ func (hn *HarnessNode) StartLndCmd(ctxb context.Context) error { hn.runCtx, hn.cancel = context.WithCancel(ctxb) args := hn.Cfg.GenArgs() - hn.cmd = exec.Command(hn.Cfg.LndBinary, args...) //nolint:gosec + hn.cmd = exec.Command(hn.Cfg.LndBinary, args...) // Redirect stderr output to buffer var errb bytes.Buffer @@ -649,9 +649,10 @@ func (hn *HarnessNode) waitForProcessExit() { // Otherwise, we print the error, break the select and save // logs. hn.printErrf("wait process exit got err: %v", err) + break - case <-time.After(wait.DefaultTimeout * 2): + case <-time.After(wait.DefaultTimeout): hn.printErrf("timeout waiting for process to exit") } @@ -783,7 +784,7 @@ func (hn *HarnessNode) Kill() error { // printErrf prints an error to the console. func (hn *HarnessNode) printErrf(format string, a ...interface{}) { - fmt.Printf("itest error from [%s:%s]: %s\n", // nolint:forbidigo + fmt.Printf("itest error from [%s:%s]: %s\n", //nolint:forbidigo hn.Cfg.LogFilenamePrefix, hn.Cfg.Name, fmt.Sprintf(format, a...)) } @@ -945,7 +946,7 @@ func finalizeLogfile(hn *HarnessNode) { // finalizeEtcdLog saves the etcd log files when test ends. func finalizeEtcdLog(hn *HarnessNode) { // Exit early if this is not etcd backend. - if hn.Cfg.DbBackend != BackendEtcd { + if hn.Cfg.DBBackend != BackendEtcd { return } diff --git a/lntest/utils.go b/lntest/utils.go index 23cd41a14..dd5fc8c17 100644 --- a/lntest/utils.go +++ b/lntest/utils.go @@ -162,10 +162,12 @@ func NodeArgsForCommitType(commitType lnrpc.CommitmentType) []string { // 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 { + //nolint:lll const ( htlcWeight = input.HTLCWeight - anchorSize = 330 + anchorSize = 330 * 2 defaultSatPerVByte = lnwallet.DefaultAnchorsCommitMaxFeeRateSatPerVByte + scale = 1000 ) var ( @@ -180,10 +182,10 @@ func CalcStaticFee(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { // channels. if CommitTypeHasAnchors(c) { feePerKw = chainfee.SatPerKVByte( - defaultSatPerVByte * 1000, + defaultSatPerVByte * scale, ).FeePerKWeight() commitWeight = input.AnchorCommitWeight - anchors = 2 * anchorSize + anchors = anchorSize } return feePerKw.FeeForWeight(int64(commitWeight+htlcWeight*numHTLCs)) + @@ -194,7 +196,9 @@ func CalcStaticFee(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { // 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) + const ratio = 100 + reserve := lnwire.NewMSatFromSatoshis(chanCap / ratio) max := lnwire.NewMSatFromSatoshis(chanCap) - reserve + return uint64(max) } From 0e8a525f946755084d013b89f1fde127a8d168f3 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Sat, 29 Oct 2022 00:51:54 +0800 Subject: [PATCH 15/45] lntest: change wait timeout values --- lntest/wait/timeouts.go | 4 ++-- lntest/wait/timeouts_darwin.go | 4 ++-- lntest/wait/timeouts_remote_db.go | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lntest/wait/timeouts.go b/lntest/wait/timeouts.go index 507edd87a..e17c8a433 100644 --- a/lntest/wait/timeouts.go +++ b/lntest/wait/timeouts.go @@ -24,11 +24,11 @@ const ( // AsyncBenchmarkTimeout is the timeout used when running the async // payments benchmark. - AsyncBenchmarkTimeout = 2 * time.Minute + AsyncBenchmarkTimeout = time.Minute * 2 // NodeStartTimeout is the timeout value when waiting for a node to // become fully started. - NodeStartTimeout = time.Second * 120 + NodeStartTimeout = time.Minute * 2 // SqliteBusyTimeout is the maximum time that a call to the sqlite db // will wait for the connection to become available. diff --git a/lntest/wait/timeouts_darwin.go b/lntest/wait/timeouts_darwin.go index 5cfc16bd7..18c4ec653 100644 --- a/lntest/wait/timeouts_darwin.go +++ b/lntest/wait/timeouts_darwin.go @@ -16,7 +16,7 @@ const ( // ChannelCloseTimeout is the max time we will wait before a channel is // considered closed. - ChannelCloseTimeout = time.Second * 30 + ChannelCloseTimeout = time.Second * 60 // DefaultTimeout is a timeout that will be used for various wait // scenarios where no custom timeout value is defined. @@ -29,7 +29,7 @@ const ( // NodeStartTimeout is the timeout value when waiting for a node to // become fully started. - NodeStartTimeout = time.Second * 120 + NodeStartTimeout = time.Minute * 2 // SqliteBusyTimeout is the maximum time that a call to the sqlite db // will wait for the connection to become available. diff --git a/lntest/wait/timeouts_remote_db.go b/lntest/wait/timeouts_remote_db.go index c6805118b..2e798b709 100644 --- a/lntest/wait/timeouts_remote_db.go +++ b/lntest/wait/timeouts_remote_db.go @@ -16,7 +16,7 @@ const ( // ChannelCloseTimeout is the max time we will wait before a channel is // considered closed. - ChannelCloseTimeout = time.Second * 120 + ChannelCloseTimeout = time.Second * 30 // DefaultTimeout is a timeout that will be used for various wait // scenarios where no custom timeout value is defined. @@ -24,11 +24,11 @@ const ( // AsyncBenchmarkTimeout is the timeout used when running the async // payments benchmark. - AsyncBenchmarkTimeout = 3 * time.Minute + AsyncBenchmarkTimeout = time.Minute * 2 // NodeStartTimeout is the timeout value when waiting for a node to // become fully started. - NodeStartTimeout = time.Second * 120 + NodeStartTimeout = time.Minute * 2 // SqliteBusyTimeout is the maximum time that a call to the sqlite db // will wait for the connection to become available. From d97f52d12a9644632ad988f3400ab52544ebc755 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Sat, 29 Oct 2022 01:01:58 +0800 Subject: [PATCH 16/45] lntest: shutdown running nodes when test fails Fixes the zip log files failure we see. --- lntest/harness.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lntest/harness.go b/lntest/harness.go index e72f7abfe..91f2e188f 100644 --- a/lntest/harness.go +++ b/lntest/harness.go @@ -351,6 +351,7 @@ func (h *HarnessTest) Subtest(t *testing.T) *HarnessTest { // Don't bother run the cleanups if the test is failed. if st.Failed() { st.Log("test failed, skipped cleanup") + st.shutdownAllNodes() return } @@ -391,10 +392,21 @@ func (h *HarnessTest) Subtest(t *testing.T) *HarnessTest { // shutdownNonStandbyNodes will shutdown any non-standby nodes. func (h *HarnessTest) shutdownNonStandbyNodes() { + h.shutdownNodes(true) +} + +// shutdownAllNodes will shutdown all running nodes. +func (h *HarnessTest) shutdownAllNodes() { + h.shutdownNodes(false) +} + +// shutdownNodes will shutdown any non-standby nodes. If skipStandby is false, +// all the standby nodes will be shutdown too. +func (h *HarnessTest) shutdownNodes(skipStandby bool) { for nid, node := range h.manager.activeNodes { // If it's a standby node, skip. _, ok := h.manager.standbyNodes[nid] - if ok { + if ok && skipStandby { continue } From 8288d3da8e5e6f8d395375300b58aff4a8ee502f Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Mon, 14 Nov 2022 21:35:08 +0800 Subject: [PATCH 17/45] itest: add missing topology check in tests This commit adds the missing topology checks. --- itest/lnd_forward_interceptor_test.go | 4 +++- itest/lnd_revocation_test.go | 9 +++++++++ itest/lnd_routing_test.go | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/itest/lnd_forward_interceptor_test.go b/itest/lnd_forward_interceptor_test.go index a7ecf99fa..b5d08f5bf 100644 --- a/itest/lnd_forward_interceptor_test.go +++ b/itest/lnd_forward_interceptor_test.go @@ -106,6 +106,7 @@ func testForwardInterceptorDedupHtlc(ht *lntest.HarnessTest) { ht.EnsureConnected(bob, alice) // Here we wait for the channel to be active again. + ht.AssertChannelExists(alice, cpAB) ht.AssertChannelExists(bob, cpAB) // Now that the channel is active we make sure the test passes as @@ -296,7 +297,8 @@ func testForwardInterceptorBasic(ht *lntest.HarnessTest) { restartAlice := ht.SuspendNode(alice) require.NoError(ht, restartAlice(), "failed to restart alice") - // Make sure the channel is active from Bob's PoV. + // Make sure the channel is active from both Alice and Bob's PoV. + ht.AssertChannelExists(alice, cpAB) ht.AssertChannelExists(bob, cpAB) // Create a new interceptor as the old one has quit. diff --git a/itest/lnd_revocation_test.go b/itest/lnd_revocation_test.go index 4ec04a11c..dba130025 100644 --- a/itest/lnd_revocation_test.go +++ b/itest/lnd_revocation_test.go @@ -223,6 +223,9 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(ht *lntest.HarnessTest) { // backup. ht.EnsureConnected(dave, carol) + // Once connected, give Dave some time to enable the channel again. + ht.AssertTopologyChannelOpen(dave, chanPoint) + // Finally, send payments from Dave to Carol, consuming Carol's // remaining payment hashes. ht.CompletePaymentRequestsNoWait(dave, carolPayReqs, chanPoint) @@ -400,6 +403,9 @@ func testRevokedCloseRetributionRemoteHodl(ht *lntest.HarnessTest) { // backup. ht.EnsureConnected(dave, carol) + // Once connected, give Dave some time to enable the channel again. + ht.AssertTopologyChannelOpen(dave, chanPoint) + // Finally, send payments from Dave to Carol, consuming Carol's // remaining payment hashes. ht.CompletePaymentRequestsNoWait( @@ -726,6 +732,9 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(ht *lntest.HarnessTest, // backup. ht.EnsureConnected(dave, carol) + // Once connected, give Dave some time to enable the channel again. + ht.AssertTopologyChannelOpen(dave, chanPoint) + // Finally, send payments from Dave to Carol, consuming Carol's // remaining payment hashes. ht.CompletePaymentRequestsNoWait(dave, carolPayReqs, chanPoint) diff --git a/itest/lnd_routing_test.go b/itest/lnd_routing_test.go index 5f28acba2..a2bb4f4e8 100644 --- a/itest/lnd_routing_test.go +++ b/itest/lnd_routing_test.go @@ -341,6 +341,9 @@ func runMultiHopSendToRoute(ht *lntest.HarnessTest, useGraphCache bool) { ) defer ht.CloseChannel(carol, chanPointBob) + // Make sure Alice knows the channel between Bob and Carol. + ht.AssertTopologyChannelOpen(alice, chanPointBob) + // Create 5 invoices for Carol, which expect a payment from Alice for // 1k satoshis with a different preimage each time. const ( From 28203fc77c72bc7134acee50d026c5834dfa2fb4 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Tue, 1 Nov 2022 08:56:40 +0800 Subject: [PATCH 18/45] lntest+itest: fix `testDataLossProtection` --- itest/lnd_channel_backup_test.go | 65 ++++++++++++++++++-------------- lntest/harness_assertion.go | 4 +- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/itest/lnd_channel_backup_test.go b/itest/lnd_channel_backup_test.go index 6b5b76788..c05a0adee 100644 --- a/itest/lnd_channel_backup_test.go +++ b/itest/lnd_channel_backup_test.go @@ -1112,22 +1112,20 @@ func testDataLossProtection(ht *lntest.HarnessTest) { // directly from the miner. ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) - // timeTravel is a method that will make Carol open a channel to the - // passed node, settle a series of payments, then reset the node back - // to the state before the payments happened. When this method returns - // the node will be unaware of the new state updates. The returned - // function can be used to restart the node in this state. - timeTravel := func(node *node.HarnessNode) (func() error, - *lnrpc.ChannelPoint, int64) { - + // timeTravelDave is a method that will make Carol open a channel to + // Dave, settle a series of payments, then Dave back to the state + // before the payments happened. When this method returns Dave will + // be unaware of the new state updates. The returned function can be + // used to restart Dave in this state. + timeTravelDave := func() (func() error, *lnrpc.ChannelPoint, int64) { // We must let the node communicate with Carol before they are // able to open channel, so we connect them. - ht.EnsureConnected(carol, node) + ht.EnsureConnected(carol, dave) // We'll first open up a channel between them with a 0.5 BTC // value. chanPoint := ht.OpenChannel( - carol, node, lntest.OpenChannelParams{ + carol, dave, lntest.OpenChannelParams{ Amt: chanAmt, }, ) @@ -1137,17 +1135,17 @@ func testDataLossProtection(ht *lntest.HarnessTest) { // the channel. // TODO(halseth): have dangling HTLCs on the commitment, able to // retrieve funds? - payReqs, _, _ := ht.CreatePayReqs(node, paymentAmt, numInvoices) + payReqs, _, _ := ht.CreatePayReqs(dave, paymentAmt, numInvoices) // Send payments from Carol using 3 of the payment hashes // generated above. ht.CompletePaymentRequests(carol, payReqs[:numInvoices/2]) - // Next query for the node's channel state, as we sent 3 - // payments of 10k satoshis each, it should now see his balance - // as being 30k satoshis. + // Next query for Dave's channel state, as we sent 3 payments + // of 10k satoshis each, it should now see his balance as being + // 30k satoshis. nodeChan := ht.AssertChannelLocalBalance( - node, chanPoint, 30_000, + dave, chanPoint, 30_000, ) // Grab the current commitment height (update number), we'll @@ -1158,39 +1156,46 @@ func testDataLossProtection(ht *lntest.HarnessTest) { // With the temporary file created, copy the current state into // the temporary file we created above. Later after more // updates, we'll restore this state. - ht.BackupDB(node) + ht.BackupDB(dave) // Reconnect the peers after the restart that was needed for // the db backup. - ht.EnsureConnected(carol, node) + ht.EnsureConnected(carol, dave) - // Finally, send more payments from , using the remaining + // Finally, send more payments from Carol, using the remaining // payment hashes. ht.CompletePaymentRequests(carol, payReqs[numInvoices/2:]) - // Now we shutdown the node, copying over the its temporary + // TODO(yy): remove the sleep once the following bug is fixed. + // + // While the payment is reported as settled, the commitment + // dance may not be finished, which leaves several HTLCs in the + // commitment. Later on, when Carol force closes this channel, + // she would have HTLCs there and the test won't pass. + time.Sleep(2 * time.Second) + + // Now we shutdown Dave, copying over the its temporary // database state which has the *prior* channel state over his // current most up to date state. With this, we essentially - // force the node to travel back in time within the channel's + // force Dave to travel back in time within the channel's // history. - ht.RestartNodeAndRestoreDB(node) + ht.RestartNodeAndRestoreDB(dave) - // Make sure the channel is still there from the PoV of the - // node. - ht.AssertNodeNumChannels(node, 1) + // Make sure the channel is still there from the PoV of Dave. + ht.AssertNodeNumChannels(dave, 1) // Now query for the channel state, it should show that it's at // a state number in the past, not the *latest* state. - ht.AssertChannelNumUpdates(node, stateNumPreCopy, chanPoint) + ht.AssertChannelNumUpdates(dave, stateNumPreCopy, chanPoint) - balResp := node.RPC.WalletBalance() - restart := ht.SuspendNode(node) + balResp := dave.RPC.WalletBalance() + restart := ht.SuspendNode(dave) return restart, chanPoint, balResp.ConfirmedBalance } // Reset Dave to a state where he has an outdated channel state. - restartDave, _, daveStartingBalance := timeTravel(dave) + restartDave, _, daveStartingBalance := timeTravelDave() // We make a note of the nodes' current on-chain balances, to make sure // they are able to retrieve the channel funds eventually, @@ -1214,7 +1219,7 @@ func testDataLossProtection(ht *lntest.HarnessTest) { // closed channel, such that Dave can retrieve his funds. // // We start by letting Dave time travel back to an outdated state. - restartDave, chanPoint2, daveStartingBalance := timeTravel(dave) + restartDave, chanPoint2, daveStartingBalance := timeTravelDave() carolBalResp = carol.RPC.WalletBalance() carolStartingBalance = carolBalResp.ConfirmedBalance @@ -1461,6 +1466,8 @@ func assertDLPExecuted(ht *lntest.HarnessTest, dave *node.HarnessNode, daveStartingBalance int64, commitType lnrpc.CommitmentType) { + ht.Helper() + // Increase the fee estimate so that the following force close tx will // be cpfp'ed. ht.SetFeeEstimate(30000) diff --git a/lntest/harness_assertion.go b/lntest/harness_assertion.go index c40d6e8fe..a58f292e6 100644 --- a/lntest/harness_assertion.go +++ b/lntest/harness_assertion.go @@ -1169,7 +1169,9 @@ func (h *HarnessTest) AssertActiveHtlcs(hn *node.HarnessNode, h := hex.EncodeToString(htlc.HashLock) _, ok := htlcHashes[h] if ok { - return fmt.Errorf("duplicate HashLock") + return fmt.Errorf("duplicate HashLock "+ + "in PendingHtlcs: %v", + ch.PendingHtlcs) } htlcHashes[h] = struct{}{} } From 17f08a87db6f7ac92c77cd9ce14d979593b5b9e4 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Thu, 3 Nov 2022 18:15:02 +0800 Subject: [PATCH 19/45] lntest+itest: remove assertion while iterating mempool --- itest/lnd_revocation_test.go | 9 ++++++++- lntest/harness_miner.go | 14 +++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/itest/lnd_revocation_test.go b/itest/lnd_revocation_test.go index dba130025..1ca9ee35e 100644 --- a/itest/lnd_revocation_test.go +++ b/itest/lnd_revocation_test.go @@ -477,7 +477,14 @@ func testRevokedCloseRetributionRemoteHodl(ht *lntest.HarnessTest) { for _, txid := range mempool { // Check that the justice tx has the appropriate number // of inputs. - tx := ht.Miner.GetRawTransaction(txid) + // + // NOTE: We don't use `ht.Miner.GetRawTransaction` + // which asserts a txid must be found as the HTLC + // spending txes might be aggregated. + tx, err := ht.Miner.Client.GetRawTransaction(txid) + if err != nil { + return nil, err + } exNumInputs := 2 + numInvoices if len(tx.MsgTx().TxIn) == exNumInputs { diff --git a/lntest/harness_miner.go b/lntest/harness_miner.go index 7e829c516..189df54b1 100644 --- a/lntest/harness_miner.go +++ b/lntest/harness_miner.go @@ -372,9 +372,17 @@ func (h *HarnessMiner) AssertOutpointInMempool(op wire.OutPoint) *wire.MsgTx { } for _, txid := range mempool { - // We require the RPC call to be succeeded and won't - // wait for it as it's an unexpected behavior. - tx := h.GetRawTransaction(txid) + // We don't use `ht.Miner.GetRawTransaction` which + // asserts a txid must be found. While iterating here, + // the actual mempool state might have been changed, + // causing a given txid being removed and cannot be + // found. For instance, the aggregation logic used in + // sweeping HTLC outputs will update the mempool by + // replacing the HTLC spending txes with a single one. + tx, err := h.Client.GetRawTransaction(txid) + if err != nil { + return err + } msgTx = tx.MsgTx() for _, txIn := range msgTx.TxIn { From 29b7903a28937ad2eb21c751bc02b9e8eab1a09b Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Mon, 7 Nov 2022 19:54:16 +0800 Subject: [PATCH 20/45] lntest: use `rpc-graph-cache-duration=100ms` in itest --- lntest/node/config.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lntest/node/config.go b/lntest/node/config.go index 8bee34b6f..9a3b17a51 100644 --- a/lntest/node/config.go +++ b/lntest/node/config.go @@ -224,7 +224,6 @@ func (cfg *BaseNodeConfig) GenArgs() []string { fmt.Sprintf("--invoicemacaroonpath=%v", cfg.InvoiceMacPath), fmt.Sprintf("--trickledelay=%v", trickleDelay), fmt.Sprintf("--profile=%d", cfg.ProfilePort), - fmt.Sprintf("--caches.rpc-graph-cache-duration=%d", 0), // Use a small batch window so we can broadcast our sweep // transactions faster. @@ -233,7 +232,12 @@ func (cfg *BaseNodeConfig) GenArgs() []string { // Use a small batch delay so we can broadcast the // announcements quickly in the tests. "--gossip.sub-batch-delay=5ms", + + // Use a small cache duration so the `DescribeGraph` can be + // updated quicker. + "--caches.rpc-graph-cache-duration=100ms", } + args = append(args, nodeArgs...) if cfg.Password == nil { From 05c82d918e16f26a94e9c0a36519bd879f808c45 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Tue, 8 Nov 2022 16:48:49 +0800 Subject: [PATCH 21/45] itest: remove file `log_error_whitelist.txt` --- itest/log_error_whitelist.txt | 302 ---------------------------------- 1 file changed, 302 deletions(-) delete mode 100644 itest/log_error_whitelist.txt diff --git a/itest/log_error_whitelist.txt b/itest/log_error_whitelist.txt deleted file mode 100644 index 389694dca..000000000 --- a/itest/log_error_whitelist.txt +++ /dev/null @@ -1,302 +0,0 @@ -