github.com/decred/dcrlnd@v0.7.6/lntest/itest/lnd_wipe_fwdpkgs_test.go (about)

     1  package itest
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/decred/dcrlnd/chainreg"
     9  	"github.com/decred/dcrlnd/lnrpc"
    10  	"github.com/decred/dcrlnd/lnrpc/routerrpc"
    11  	"github.com/decred/dcrlnd/lntest"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  type pendingChan *lnrpc.PendingChannelsResponse_PendingChannel
    16  
    17  // testWipeForwardingPackagesLocal tests that when a channel is closed, either
    18  // through local force close, remote close, or coop close, all the forwarding
    19  // packages of that particular channel are deleted. The test creates a
    20  // topology as Alice -> Bob -> Carol, and sends payments from Alice to Carol
    21  // through Bob. It then performs the test in two steps,
    22  //   - Bob force closes the channel Alice->Bob, and checks from both Bob's
    23  //     PoV(local force close) and Alice's Pov(remote close) that the forwarding
    24  //     packages are wiped.
    25  //   - Bob coop closes the channel Bob->Carol, and checks from both Bob PoVs that
    26  //     the forwarding packages are wiped.
    27  func testWipeForwardingPackages(net *lntest.NetworkHarness,
    28  	t *harnessTest) {
    29  
    30  	// Setup the test and get the channel points.
    31  	pointAB, pointBC, carol, cleanUp := setupFwdPkgTest(net, t)
    32  	defer cleanUp()
    33  
    34  	// Firstly, Bob force closes the channel.
    35  	_, _, err := net.CloseChannel(net.Bob, pointAB, true)
    36  	require.NoError(t.t, err, "unable to force close channel")
    37  
    38  	// Now that the channel has been force closed, it should show up in
    39  	// bob's PendingChannels RPC under the waiting close section.
    40  	pendingChan := assertWaitingCloseChannel(t.t, net.Bob)
    41  
    42  	// Check that Bob has created forwarding packages. We don't care the
    43  	// exact number here as long as these packages are deleted when the
    44  	// channel is closed.
    45  	require.NotZero(t.t, pendingChan.NumForwardingPackages)
    46  
    47  	// Mine 1 block to get the closing transaction confirmed.
    48  	mineBlocks(t, net, 1, 0)
    49  	require.NoError(t.t, err, "unable to mine blocks")
    50  
    51  	// Now that the closing transaction is confirmed, the above waiting
    52  	// close channel should now become pending force closed channel.
    53  	pendingChan = assertPendingForceClosedChannel(t.t, net.Bob)
    54  
    55  	// Check the forwarding pacakges are deleted.
    56  	require.Zero(t.t, pendingChan.NumForwardingPackages)
    57  
    58  	// For Alice, the forwarding packages should have been wiped too.
    59  	pendingChanAlice := assertPendingForceClosedChannel(t.t, net.Alice)
    60  	require.Zero(t.t, pendingChanAlice.NumForwardingPackages)
    61  
    62  	// Secondly, Bob coop closes the channel.
    63  	_, _, err = net.CloseChannel(net.Bob, pointBC, false)
    64  	require.NoError(t.t, err, "unable to coop close channel")
    65  
    66  	// Now that the channel has been coop closed, it should show up in
    67  	// bob's PendingChannels RPC under the waiting close section.
    68  	pendingChan = assertWaitingCloseChannel(t.t, net.Bob)
    69  
    70  	// Check that Bob has created forwarding packages. We don't care the
    71  	// exact number here as long as these packages are deleted when the
    72  	// channel is closed.
    73  	require.NotZero(t.t, pendingChan.NumForwardingPackages)
    74  
    75  	// Since it's a coop close, Carol should see the waiting close channel
    76  	// too.
    77  	pendingChanCarol := assertWaitingCloseChannel(t.t, carol)
    78  	require.NotZero(t.t, pendingChanCarol.NumForwardingPackages)
    79  
    80  	// Mine 1 block to get the closing transaction confirmed.
    81  	mineBlocks(t, net, 1, 0)
    82  	require.NoError(t.t, err, "unable to mine blocks")
    83  
    84  	// Now that the closing transaction is confirmed, the above waiting
    85  	// close channel should now become pending closed channel. Note that
    86  	// the name PendingForceClosingChannels is a bit confusing, what it
    87  	// really contains is channels whose closing tx has been broadcast.
    88  	pendingChan = assertPendingForceClosedChannel(t.t, net.Bob)
    89  
    90  	// Check the forwarding pacakges are deleted.
    91  	require.Zero(t.t, pendingChan.NumForwardingPackages)
    92  
    93  	// Mine a block to confirm sweep transactions such that they
    94  	// don't remain in the mempool for any subsequent tests.
    95  	mineBlocks(t, net, 1, 0)
    96  	require.NoError(t.t, err, "unable to mine blocks")
    97  
    98  	// Cleanup the force closed channel.
    99  	cleanupForceClose(t, net, net.Bob, pointAB)
   100  }
   101  
   102  // setupFwdPkgTest prepares the wipe forwarding packages tests. It creates a
   103  // network topology that has a channel direction: Alice -> Bob -> Carol, sends
   104  // several payments from Alice to Carol, and returns the two channel points(one
   105  // for Alice and Bob, the other for Bob and Carol), the node Carol, and a
   106  // cleanup function to be used when the test finishes.
   107  func setupFwdPkgTest(net *lntest.NetworkHarness,
   108  	t *harnessTest) (*lnrpc.ChannelPoint, *lnrpc.ChannelPoint,
   109  	*lntest.HarnessNode, func()) {
   110  
   111  	ctxb := context.Background()
   112  
   113  	const (
   114  		chanAmt        = 10e6
   115  		paymentAmt     = 10e4
   116  		finalCTLVDelta = chainreg.DefaultDecredTimeLockDelta
   117  		numInvoices    = 3
   118  	)
   119  
   120  	// Grab Alice and Bob from harness net.
   121  	alice, bob := net.Alice, net.Bob
   122  
   123  	// Create a new node Carol, which will create invoices that require
   124  	// Alice to pay.
   125  	carol := net.NewNode(t.t, "Carol", nil)
   126  
   127  	// Connect Bob to Carol.
   128  	net.ConnectNodes(t.t, bob, carol)
   129  
   130  	// Open a channel between Alice and Bob.
   131  	chanPointAB := openChannelAndAssert(
   132  		t, net, alice, bob, lntest.OpenChannelParams{
   133  			Amt: chanAmt,
   134  		},
   135  	)
   136  
   137  	// Open a channel between Bob and Carol.
   138  	chanPointBC := openChannelAndAssert(
   139  		t, net, bob, carol, lntest.OpenChannelParams{
   140  			Amt: chanAmt,
   141  		},
   142  	)
   143  
   144  	// Before we continue, make sure Alice has seen the channel between Bob
   145  	// and Carol.
   146  	err := alice.WaitForNetworkChannelOpen(chanPointBC)
   147  	require.NoError(t.t, err)
   148  
   149  	ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
   150  	defer cancel()
   151  
   152  	// Alice sends several payments to Carol through Bob, which triggers
   153  	// Bob to create forwarding packages.
   154  	for i := 0; i < numInvoices; i++ {
   155  		// Add an invoice for Carol.
   156  		invoice := &lnrpc.Invoice{Memo: "testing", Value: paymentAmt}
   157  		invoiceResp, err := carol.AddInvoice(ctxt, invoice)
   158  		require.NoError(t.t, err, "unable to add invoice")
   159  
   160  		// Alice sends a payment to Carol through Bob.
   161  		sendAndAssertSuccess(
   162  			t, net.Alice, &routerrpc.SendPaymentRequest{
   163  				PaymentRequest: invoiceResp.PaymentRequest,
   164  				TimeoutSeconds: 60,
   165  				FeeLimitAtoms:  noFeeLimitMAtoms,
   166  			},
   167  		)
   168  	}
   169  
   170  	return chanPointAB, chanPointBC, carol, func() {
   171  		shutdownAndAssert(net, t, carol)
   172  	}
   173  }
   174  
   175  // assertWaitingCloseChannel checks there is a single channel that is waiting
   176  // for close and returns the channel found.
   177  func assertWaitingCloseChannel(t *testing.T,
   178  	node *lntest.HarnessNode) pendingChan {
   179  
   180  	ctxb := context.Background()
   181  
   182  	var channel pendingChan
   183  	require.Eventually(t, func() bool {
   184  		ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
   185  		defer cancel()
   186  
   187  		req := &lnrpc.PendingChannelsRequest{}
   188  		resp, err := node.PendingChannels(ctxt, req)
   189  
   190  		// We require the RPC call to be succeeded and won't retry upon
   191  		// an error.
   192  		require.NoError(t, err, "unable to query for pending channels")
   193  
   194  		if err := checkNumWaitingCloseChannels(resp, 1); err != nil {
   195  			return false
   196  		}
   197  
   198  		channel = resp.WaitingCloseChannels[0].Channel
   199  		return true
   200  	}, defaultTimeout, 200*time.Millisecond)
   201  
   202  	return channel
   203  }
   204  
   205  // assertForceClosedChannel checks there is a single channel that is pending
   206  // force closed and returns the channel found.
   207  func assertPendingForceClosedChannel(t *testing.T,
   208  	node *lntest.HarnessNode) pendingChan {
   209  
   210  	ctxb := context.Background()
   211  
   212  	var channel pendingChan
   213  	require.Eventually(t, func() bool {
   214  		ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
   215  		defer cancel()
   216  
   217  		req := &lnrpc.PendingChannelsRequest{}
   218  		resp, err := node.PendingChannels(ctxt, req)
   219  
   220  		// We require the RPC call to be succeeded and won't retry upon
   221  		// an error.
   222  		require.NoError(t, err, "unable to query for pending channels")
   223  
   224  		if err := checkNumForceClosedChannels(resp, 1); err != nil {
   225  			return false
   226  		}
   227  
   228  		channel = resp.PendingForceClosingChannels[0].Channel
   229  		return true
   230  	}, defaultTimeout, 200*time.Millisecond)
   231  
   232  	return channel
   233  }