diff --git a/lntemp/harness.go b/lntemp/harness.go index 927f8c7cd..397ba3524 100644 --- a/lntemp/harness.go +++ b/lntemp/harness.go @@ -693,12 +693,10 @@ type OpenChannelParams struct { ScidAlias bool } -// OpenChannelAssertPending attempts to open a channel between srcNode and -// destNode with the passed channel funding parameters. Once the `OpenChannel` -// is called, it will consume the first event it receives from the open channel -// client and asserts it's a channel pending event. -func (h *HarnessTest) OpenChannelAssertPending(srcNode, - destNode *node.HarnessNode, p OpenChannelParams) rpc.OpenChanClient { +// prepareOpenChannel waits for both nodes to be synced to chain and returns an +// OpenChannelRequest. +func (h *HarnessTest) prepareOpenChannel(srcNode, destNode *node.HarnessNode, + p OpenChannelParams) *lnrpc.OpenChannelRequest { // Wait until srcNode and destNode have the latest chain synced. // Otherwise, we may run into a check within the funding manager that @@ -714,8 +712,8 @@ func (h *HarnessTest) OpenChannelAssertPending(srcNode, minConfs = 0 } - // Prepare the request and open the channel. - openReq := &lnrpc.OpenChannelRequest{ + // Prepare the request. + return &lnrpc.OpenChannelRequest{ NodePubkey: destNode.PubKey[:], LocalFundingAmount: int64(p.Amt), PushSat: int64(p.PushAmt), @@ -730,6 +728,17 @@ func (h *HarnessTest) OpenChannelAssertPending(srcNode, ZeroConf: p.ZeroConf, ScidAlias: p.ScidAlias, } +} + +// OpenChannelAssertPending attempts to open a channel between srcNode and +// destNode with the passed channel funding parameters. Once the `OpenChannel` +// is called, it will consume the first event it receives from the open channel +// client and asserts it's a channel pending event. +func (h *HarnessTest) OpenChannelAssertPending(srcNode, + destNode *node.HarnessNode, p OpenChannelParams) rpc.OpenChanClient { + + // Prepare the request and open the channel. + openReq := h.prepareOpenChannel(srcNode, destNode, p) respStream := srcNode.RPC.OpenChannel(openReq) // Consume the "channel pending" update. This waits until the node @@ -785,6 +794,24 @@ func (h *HarnessTest) OpenChannel(alice, bob *node.HarnessNode, return fundingChanPoint } +// OpenChannelAssertErr opens a channel between node srcNode and destNode, +// asserts that the expected error is returned from the channel opening. +func (h *HarnessTest) OpenChannelAssertErr(srcNode, destNode *node.HarnessNode, + p OpenChannelParams, expectedErr error) { + + // Prepare the request and open the channel. + openReq := h.prepareOpenChannel(srcNode, destNode, p) + respStream := srcNode.RPC.OpenChannel(openReq) + + // Receive an error to be sent from the stream. + _, err := h.receiveOpenChannelUpdate(respStream) + + // Use string comparison here as we haven't codified all the RPC errors + // yet. + require.Containsf(h, err.Error(), expectedErr.Error(), "unexpected "+ + "error returned, want %v, got %v", expectedErr, err) +} + // CloseChannelAssertPending attempts to close the channel indicated by the // passed channel point, initiated by the passed node. Once the CloseChannel // rpc is called, it will consume one event and assert it's a close pending diff --git a/lntemp/harness_assertion.go b/lntemp/harness_assertion.go index fc0351160..ecbbbb178 100644 --- a/lntemp/harness_assertion.go +++ b/lntemp/harness_assertion.go @@ -199,6 +199,20 @@ func (h *HarnessTest) AssertNumEdges(hn *node.HarnessNode, func (h *HarnessTest) ReceiveOpenChannelUpdate( stream rpc.OpenChanClient) *lnrpc.OpenStatusUpdate { + update, err := h.receiveOpenChannelUpdate(stream) + require.NoError(h, err, "received err from open channel stream") + + return update +} + +// receiveOpenChannelUpdate waits until a message or an error is received on +// the stream or the timeout is reached. +// +// TODO(yy): use generics to unify all receiving stream update once go@1.18 is +// used. +func (h *HarnessTest) receiveOpenChannelUpdate( + stream rpc.OpenChanClient) (*lnrpc.OpenStatusUpdate, error) { + chanMsg := make(chan *lnrpc.OpenStatusUpdate) errChan := make(chan error) go func() { @@ -216,16 +230,14 @@ func (h *HarnessTest) ReceiveOpenChannelUpdate( case <-time.After(DefaultTimeout): require.Fail(h, "timeout", "timeout waiting for open channel "+ "update sent") + return nil, nil case err := <-errChan: - require.Failf(h, "open channel stream", - "received err from open channel stream: %v", err) + return nil, err case updateMsg := <-chanMsg: - return updateMsg + return updateMsg, nil } - - return nil } // WaitForChannelOpenEvent waits for a notification that a channel is open by diff --git a/lntest/itest/list_on_test.go b/lntest/itest/list_on_test.go index 77ec03502..e6194cbfb 100644 --- a/lntest/itest/list_on_test.go +++ b/lntest/itest/list_on_test.go @@ -87,4 +87,8 @@ var allTestCasesTemp = []*lntemp.TestCase{ Name: "list channels", TestFunc: testListChannels, }, + { + Name: "max pending channel", + TestFunc: testMaxPendingChannels, + }, } diff --git a/lntest/itest/lnd_misc_test.go b/lntest/itest/lnd_misc_test.go index f95ab658e..709f6ff11 100644 --- a/lntest/itest/lnd_misc_test.go +++ b/lntest/itest/lnd_misc_test.go @@ -10,7 +10,6 @@ import ( "time" "github.com/btcsuite/btcd/btcutil" - "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcwallet/wallet" "github.com/lightningnetwork/lnd/chainreg" "github.com/lightningnetwork/lnd/funding" @@ -342,7 +341,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(net *lntest.NetworkHarness, t *harnessTest) { +func testMaxPendingChannels(ht *lntemp.HarnessTest) { maxPendingChannels := lncfg.DefaultMaxPendingChannels + 1 amount := funding.MaxBtcFundingAmount @@ -351,22 +350,23 @@ func testMaxPendingChannels(net *lntest.NetworkHarness, t *harnessTest) { args := []string{ fmt.Sprintf("--maxpendingchannels=%v", maxPendingChannels), } - carol := net.NewNode(t.t, "Carol", args) - defer shutdownAndAssert(net, t, carol) + carol := ht.NewNode("Carol", args) - net.ConnectNodes(t.t, net.Alice, carol) + alice := ht.Alice + ht.ConnectNodes(alice, carol) carolBalance := btcutil.Amount(maxPendingChannels) * amount - net.SendCoins(t.t, carolBalance, carol) + ht.FundCoins(carolBalance, carol) // Send open channel requests without generating new blocks thereby // increasing pool of pending channels. Then check that we can't open // the channel if the number of pending channels exceed max value. - openStreams := make([]lnrpc.Lightning_OpenChannelClient, maxPendingChannels) + openStreams := make( + []lnrpc.Lightning_OpenChannelClient, maxPendingChannels, + ) for i := 0; i < maxPendingChannels; i++ { - stream := openChannelStream( - t, net, net.Alice, carol, - lntest.OpenChannelParams{ + stream := ht.OpenChannelAssertPending( + alice, carol, lntemp.OpenChannelParams{ Amt: amount, }, ) @@ -375,60 +375,36 @@ func testMaxPendingChannels(net *lntest.NetworkHarness, t *harnessTest) { // Carol exhausted available amount of pending channels, next open // channel request should cause ErrorGeneric to be sent back to Alice. - _, err := net.OpenChannel( - net.Alice, carol, lntest.OpenChannelParams{ + ht.OpenChannelAssertErr( + alice, carol, lntemp.OpenChannelParams{ Amt: amount, - }, + }, lnwire.ErrMaxPendingChannels, ) - if err == nil { - t.Fatalf("error wasn't received") - } else if !strings.Contains( - err.Error(), lnwire.ErrMaxPendingChannels.Error(), - ) { - - t.Fatalf("not expected error was received: %v", err) - } - // For now our channels are in pending state, in order to not interfere // with other tests we should clean up - complete opening of the // channel and then close it. - // Mine 6 blocks, then wait for node's to notify us that the channel has - // been opened. The funding transactions should be found within the + // Mine 6 blocks, then wait for node's to notify us that the channel + // has been opened. The funding transactions should be found within the // first newly mined block. 6 blocks make sure the funding transaction // has enough confirmations to be announced publicly. - block := mineBlocks(t, net, 6, maxPendingChannels)[0] + block := ht.MineBlocksAndAssertNumTxes(6, maxPendingChannels)[0] chanPoints := make([]*lnrpc.ChannelPoint, maxPendingChannels) for i, stream := range openStreams { - fundingChanPoint, err := net.WaitForChannelOpen(stream) - if err != nil { - t.Fatalf("error while waiting for channel open: %v", err) - } + fundingChanPoint := ht.WaitForChannelOpenEvent(stream) - fundingTxID, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint) - if err != nil { - t.Fatalf("unable to get txid: %v", err) - } + fundingTxID := ht.GetChanPointFundingTxid(fundingChanPoint) // Ensure that the funding transaction enters a block, and is // properly advertised by Alice. - assertTxInBlock(t, block, fundingTxID) - err = net.Alice.WaitForNetworkChannelOpen(fundingChanPoint) - if err != nil { - t.Fatalf("channel not seen on network before "+ - "timeout: %v", err) - } + ht.Miner.AssertTxInBlock(block, fundingTxID) + ht.AssertTopologyChannelOpen(alice, fundingChanPoint) // The channel should be listed in the peer information // returned by both peers. - chanPoint := wire.OutPoint{ - Hash: *fundingTxID, - Index: fundingChanPoint.OutputIndex, - } - err = net.AssertChannelExists(net.Alice, &chanPoint) - require.NoError(t.t, err, "unable to assert channel existence") + ht.AssertChannelExists(alice, fundingChanPoint) chanPoints[i] = fundingChanPoint } @@ -436,7 +412,7 @@ func testMaxPendingChannels(net *lntest.NetworkHarness, t *harnessTest) { // Next, close the channel between Alice and Carol, asserting that the // channel has been properly closed on-chain. for _, chanPoint := range chanPoints { - closeChannelAndAssert(t, net, net.Alice, chanPoint, false) + ht.CloseChannel(alice, chanPoint) } } diff --git a/lntest/itest/lnd_test_list_on_test.go b/lntest/itest/lnd_test_list_on_test.go index bb3f27921..23a034d78 100644 --- a/lntest/itest/lnd_test_list_on_test.go +++ b/lntest/itest/lnd_test_list_on_test.go @@ -72,10 +72,6 @@ var allTestCases = []*testCase{ name: "list outgoing payments", test: testListPayments, }, - { - name: "max pending channel", - test: testMaxPendingChannels, - }, { name: "multi-hop payments", test: testMultiHopPayments,