From 36dc4b3abf7f35fff705a47ca062a9c09e46b926 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 14 Oct 2021 15:42:59 +0200 Subject: [PATCH] itest: refactor tests to be re-used --- lntest/itest/lnd_onchain_test.go | 22 +++++++++++++++------- lntest/itest/lnd_open_channel_test.go | 20 ++++++++++++++------ lntest/itest/lnd_payment_test.go | 23 +++++++++++++++-------- lntest/itest/lnd_psbt_test.go | 14 +++++++++++--- lntest/itest/lnd_signer_test.go | 20 ++++++++++++++------ lntest/itest/lnd_wallet_import_test.go | 12 +++++++++--- 6 files changed, 78 insertions(+), 33 deletions(-) diff --git a/lntest/itest/lnd_onchain_test.go b/lntest/itest/lnd_onchain_test.go index b59eeb202..da4af2fa0 100644 --- a/lntest/itest/lnd_onchain_test.go +++ b/lntest/itest/lnd_onchain_test.go @@ -22,6 +22,14 @@ import ( // // TODO(wilmer): Add RBF case once btcd supports it. func testCPFP(net *lntest.NetworkHarness, t *harnessTest) { + runCPFP(net, t, net.Alice, net.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(net *lntest.NetworkHarness, t *harnessTest, + alice, bob *lntest.HarnessNode) { + // Skip this test for neutrino, as it's not aware of mempool // transactions. if net.BackendCfg.Name() == lntest.NeutrinoBackendName { @@ -31,14 +39,14 @@ func testCPFP(net *lntest.NetworkHarness, t *harnessTest) { // We'll start the test by sending Alice some coins, which she'll use to // send to Bob. ctxb := context.Background() - net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, net.Alice) + net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, alice) // Create an address for Bob to send the coins to. addrReq := &lnrpc.NewAddressRequest{ Type: lnrpc.AddressType_WITNESS_PUBKEY_HASH, } ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - resp, err := net.Bob.NewAddress(ctxt, addrReq) + resp, err := bob.NewAddress(ctxt, addrReq) if err != nil { t.Fatalf("unable to get new address for bob: %v", err) } @@ -50,7 +58,7 @@ func testCPFP(net *lntest.NetworkHarness, t *harnessTest) { Amount: btcutil.SatoshiPerBitcoin, } ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - if _, err = net.Alice.SendCoins(ctxt, sendReq); err != nil { + if _, err = alice.SendCoins(ctxt, sendReq); err != nil { t.Fatalf("unable to send coins to bob: %v", err) } @@ -88,7 +96,7 @@ func testCPFP(net *lntest.NetworkHarness, t *harnessTest) { TxidBytes: txid[:], OutputIndex: uint32(bobOutputIdx), } - assertWalletUnspent(t, net.Bob, op) + assertWalletUnspent(t, bob, op) // We'll attempt to bump the fee of this transaction by performing a // CPFP from Alice's point of view. @@ -99,7 +107,7 @@ func testCPFP(net *lntest.NetworkHarness, t *harnessTest) { ), } ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - _, err = net.Bob.WalletKitClient.BumpFee(ctxt, bumpFeeReq) + _, err = bob.WalletKitClient.BumpFee(ctxt, bumpFeeReq) if err != nil { t.Fatalf("unable to bump fee: %v", err) } @@ -115,7 +123,7 @@ func testCPFP(net *lntest.NetworkHarness, t *harnessTest) { // UtxoSweeper. We'll ensure it's using the fee rate specified. pendingSweepsReq := &walletrpc.PendingSweepsRequest{} ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - pendingSweepsResp, err := net.Bob.WalletKitClient.PendingSweeps( + pendingSweepsResp, err := bob.WalletKitClient.PendingSweeps( ctxt, pendingSweepsReq, ) if err != nil { @@ -146,7 +154,7 @@ func testCPFP(net *lntest.NetworkHarness, t *harnessTest) { err = wait.NoError(func() error { req := &walletrpc.PendingSweepsRequest{} ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - resp, err := net.Bob.WalletKitClient.PendingSweeps(ctxt, req) + resp, err := bob.WalletKitClient.PendingSweeps(ctxt, req) if err != nil { return fmt.Errorf("unable to retrieve bob's pending "+ "sweeps: %v", err) diff --git a/lntest/itest/lnd_open_channel_test.go b/lntest/itest/lnd_open_channel_test.go index c7be76adf..2864558c2 100644 --- a/lntest/itest/lnd_open_channel_test.go +++ b/lntest/itest/lnd_open_channel_test.go @@ -259,6 +259,15 @@ func testOpenChannelAfterReorg(net *lntest.NetworkHarness, t *harnessTest) { // 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(net *lntest.NetworkHarness, t *harnessTest) { + runBasicChannelCreationAndUpdates(net, t, net.Alice, net.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(net *lntest.NetworkHarness, + t *harnessTest, alice, bob *lntest.HarnessNode) { + ctxb := context.Background() const ( numChannels = 2 @@ -266,10 +275,10 @@ func testBasicChannelCreationAndUpdates(net *lntest.NetworkHarness, t *harnessTe ) // Subscribe Bob and Alice to channel event notifications. - bobChanSub := subscribeChannelNotifications(ctxb, t, net.Bob) + bobChanSub := subscribeChannelNotifications(ctxb, t, bob) defer close(bobChanSub.quit) - aliceChanSub := subscribeChannelNotifications(ctxb, t, net.Alice) + aliceChanSub := subscribeChannelNotifications(ctxb, t, alice) defer close(aliceChanSub.quit) // Open the channels between Alice and Bob, asserting that the channels @@ -277,8 +286,7 @@ func testBasicChannelCreationAndUpdates(net *lntest.NetworkHarness, t *harnessTe chanPoints := make([]*lnrpc.ChannelPoint, numChannels) for i := 0; i < numChannels; i++ { chanPoints[i] = openChannelAndAssert( - t, net, net.Alice, net.Bob, - lntest.OpenChannelParams{ + t, net, alice, bob, lntest.OpenChannelParams{ Amt: amount, }, ) @@ -346,9 +354,9 @@ func testBasicChannelCreationAndUpdates(net *lntest.NetworkHarness, t *harnessTe for i, chanPoint := range chanPoints { // Force close the first of the two channels. force := i%2 == 0 - closeChannelAndAssert(t, net, net.Alice, chanPoint, force) + closeChannelAndAssert(t, net, alice, chanPoint, force) if force { - cleanupForceClose(t, net, net.Alice, chanPoint) + cleanupForceClose(t, net, alice, chanPoint) } } diff --git a/lntest/itest/lnd_payment_test.go b/lntest/itest/lnd_payment_test.go index 5cf3330c6..aef6158c0 100644 --- a/lntest/itest/lnd_payment_test.go +++ b/lntest/itest/lnd_payment_test.go @@ -243,6 +243,13 @@ func testPaymentFollowingChannelOpen(net *lntest.NetworkHarness, t *harnessTest) // testAsyncPayments tests the performance of the async payments. func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { + runAsyncPayments(net, t, net.Alice, net.Bob) +} + +// runAsyncPayments tests the performance of the async payments. +func runAsyncPayments(net *lntest.NetworkHarness, t *harnessTest, alice, + bob *lntest.HarnessNode) { + ctxb := context.Background() const ( @@ -254,13 +261,13 @@ func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { // Alice should send all money from her side to Bob. channelCapacity := btcutil.Amount(paymentAmt * 2000) chanPoint := openChannelAndAssert( - t, net, net.Alice, net.Bob, + t, net, alice, bob, lntest.OpenChannelParams{ Amt: channelCapacity, }, ) - info, err := getChanInfo(net.Alice) + info, err := getChanInfo(alice) if err != nil { t.Fatalf("unable to get alice channel info: %v", err) } @@ -278,7 +285,7 @@ func testAsyncPayments(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, + bob, paymentAmt, numInvoices, ) if err != nil { t.Fatalf("unable to create pay reqs: %v", err) @@ -286,7 +293,7 @@ func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { // Wait for Alice to receive the channel edge from the funding manager. ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - err = net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint) + err = alice.WaitForNetworkChannelOpen(ctxt, chanPoint) if err != nil { t.Fatalf("alice didn't see the alice->bob channel before "+ "timeout: %v", err) @@ -301,7 +308,7 @@ func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { payReq := bobPayReqs[i] go func() { ctxt, _ = context.WithTimeout(ctxb, lntest.AsyncBenchmarkTimeout) - stream, err := net.Alice.RouterClient.SendPaymentV2( + stream, err := alice.RouterClient.SendPaymentV2( ctxt, &routerrpc.SendPaymentRequest{ PaymentRequest: payReq, @@ -344,7 +351,7 @@ func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { // htlcs listed and has correct balances. This is needed due to the fact // that we now pipeline the settles. err = wait.Predicate(func() bool { - aliceChan, err := getChanInfo(net.Alice) + aliceChan, err := getChanInfo(alice) if err != nil { return false } @@ -366,7 +373,7 @@ func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { // Wait for Bob to receive revocation from Alice. err = wait.NoError(func() error { - bobChan, err := getChanInfo(net.Bob) + bobChan, err := getChanInfo(bob) if err != nil { t.Fatalf("unable to get bob's channel info: %v", err) } @@ -399,7 +406,7 @@ func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { // 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) + closeChannelAndAssert(t, net, alice, chanPoint, false) } // testBidirectionalAsyncPayments tests that nodes are able to send the diff --git a/lntest/itest/lnd_psbt_test.go b/lntest/itest/lnd_psbt_test.go index 478432395..afdef552a 100644 --- a/lntest/itest/lnd_psbt_test.go +++ b/lntest/itest/lnd_psbt_test.go @@ -19,9 +19,6 @@ import ( // by using a Partially Signed Bitcoin Transaction that funds the channel // multisig funding output. func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) { - ctxb := context.Background() - const chanSize = funding.MaxBtcFundingAmount - // 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. @@ -31,6 +28,17 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) { dave := net.NewNode(t.t, "dave", nil) defer shutdownAndAssert(net, t, dave) + runPsbtChanFunding(net, t, carol, dave) +} + +// 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(net *lntest.NetworkHarness, t *harnessTest, carol, + dave *lntest.HarnessNode) { + + ctxb := context.Background() + const chanSize = funding.MaxBtcFundingAmount net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, dave) // Before we start the test, we'll ensure both sides are connected so diff --git a/lntest/itest/lnd_signer_test.go b/lntest/itest/lnd_signer_test.go index 02402145a..9630b9fdd 100644 --- a/lntest/itest/lnd_signer_test.go +++ b/lntest/itest/lnd_signer_test.go @@ -16,6 +16,14 @@ import ( // the node's pubkey and a customized public key to check the validity of the // result. func testDeriveSharedKey(net *lntest.NetworkHarness, t *harnessTest) { + runDeriveSharedKey(t, net.Alice) +} + +// runDeriveSharedKey checks the ECDH performed by the endpoint +// 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(t *harnessTest, alice *lntest.HarnessNode) { ctxb := context.Background() // Create an ephemeral key, extracts its public key, and make a @@ -32,7 +40,7 @@ func testDeriveSharedKey(net *lntest.NetworkHarness, t *harnessTest) { req *signrpc.SharedKeyRequest) { ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - resp, err := net.Alice.SignerClient.DeriveSharedKey(ctxt, req) + resp, err := alice.SignerClient.DeriveSharedKey(ctxt, req) require.NoError(t.t, err, "calling DeriveSharedKey failed") sharedKey, _ := privKeyECDH.ECDH(pub) @@ -42,13 +50,13 @@ func testDeriveSharedKey(net *lntest.NetworkHarness, t *harnessTest) { ) } - nodePub, err := btcec.ParsePubKey(net.Alice.PubKey[:], btcec.S256()) + nodePub, err := btcec.ParsePubKey(alice.PubKey[:], btcec.S256()) require.NoError(t.t, err, "failed to parse node pubkey") customizedKeyFamily := int32(keychain.KeyFamilyMultiSig) customizedIndex := int32(1) customizedPub, err := deriveCustomizedKey( - ctxb, net.Alice, customizedKeyFamily, customizedIndex, + ctxb, alice, customizedKeyFamily, customizedIndex, ) require.NoError(t.t, err, "failed to create customized pubkey") @@ -85,7 +93,7 @@ func testDeriveSharedKey(net *lntest.NetworkHarness, t *harnessTest) { req = &signrpc.SharedKeyRequest{ EphemeralPubkey: ephemeralPubBytes, KeyDesc: &signrpc.KeyDescriptor{ - RawKeyBytes: net.Alice.PubKey[:], + RawKeyBytes: alice.PubKey[:], KeyLoc: &signrpc.KeyLocator{ KeyFamily: int32(keychain.KeyFamilyNodeKey), }, @@ -135,7 +143,7 @@ func testDeriveSharedKey(net *lntest.NetworkHarness, t *harnessTest) { // params, the expected error is returned. assertErrorMatch := func(match string, req *signrpc.SharedKeyRequest) { ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - _, err := net.Alice.SignerClient.DeriveSharedKey(ctxt, req) + _, err := alice.SignerClient.DeriveSharedKey(ctxt, req) require.Error(t.t, err, "expected to have an error") require.Contains( t.t, err.Error(), match, "error failed to match", @@ -163,7 +171,7 @@ func testDeriveSharedKey(net *lntest.NetworkHarness, t *harnessTest) { req = &signrpc.SharedKeyRequest{ EphemeralPubkey: ephemeralPubBytes, KeyDesc: &signrpc.KeyDescriptor{ - RawKeyBytes: net.Alice.PubKey[:], + RawKeyBytes: alice.PubKey[:], }, } assertErrorMatch("key_desc.key_loc must also be set", req) diff --git a/lntest/itest/lnd_wallet_import_test.go b/lntest/itest/lnd_wallet_import_test.go index 1a62c7da4..db898282d 100644 --- a/lntest/itest/lnd_wallet_import_test.go +++ b/lntest/itest/lnd_wallet_import_test.go @@ -594,9 +594,6 @@ func testWalletImportAccount(net *lntest.NetworkHarness, t *harnessTest) { func testWalletImportAccountScenario(net *lntest.NetworkHarness, t *harnessTest, addrType walletrpc.AddressType) { - ctxb := context.Background() - const utxoAmt int64 = btcutil.SatoshiPerBitcoin - // We'll start our test by having two nodes, Carol and Dave. Carol's // default wallet account will be imported into Dave's node. carol := net.NewNode(t.t, "carol", nil) @@ -605,6 +602,15 @@ func testWalletImportAccountScenario(net *lntest.NetworkHarness, t *harnessTest, dave := net.NewNode(t.t, "dave", nil) defer shutdownAndAssert(net, t, dave) + runWalletImportAccountScenario(net, t, addrType, carol, dave) +} + +func runWalletImportAccountScenario(net *lntest.NetworkHarness, t *harnessTest, + addrType walletrpc.AddressType, carol, dave *lntest.HarnessNode) { + + ctxb := context.Background() + const utxoAmt int64 = btcutil.SatoshiPerBitcoin + ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) defer cancel() listReq := &walletrpc.ListAccountsRequest{