itest+lntemp: refactor testMaxPendingChannels

This commit is contained in:
yyforyongyu 2022-08-03 21:29:25 +08:00
parent d1ac08b336
commit ba61e9edff
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868
5 changed files with 78 additions and 63 deletions

View File

@ -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

View File

@ -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

View File

@ -87,4 +87,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
Name: "list channels",
TestFunc: testListChannels,
},
{
Name: "max pending channel",
TestFunc: testMaxPendingChannels,
},
}

View File

@ -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)
}
}

View File

@ -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,