From 429166433d59d70018476102d3695ee75278acfa Mon Sep 17 00:00:00 2001 From: ffranr Date: Mon, 12 Jun 2023 17:17:40 +0100 Subject: [PATCH 1/3] itest: fix comment --- itest/assertions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itest/assertions.go b/itest/assertions.go index 72b06c011..00fa676a6 100644 --- a/itest/assertions.go +++ b/itest/assertions.go @@ -384,7 +384,7 @@ func confirmAndAssetOutboundTransferWithOutputs(t *harnessTest, require.NoError(t.t, err) t.Logf("Got response from sending assets: %v", sendRespJSON) - // Mine a block to force the send we created above to confirm. + // Mine a block to force the send event to complete (confirm on-chain). _ = mineBlocks(t, t.lndHarness, 1, 1) // Confirm that we can externally view the transfer. From 8af90ab0ab88c4244130bbca5468c5ad9c132693 Mon Sep 17 00:00:00 2001 From: ffranr Date: Mon, 12 Jun 2023 21:28:23 +0100 Subject: [PATCH 2/3] itest: use different LND subtest harnesses for each test cases This change doesn't solve any known issue but is probably good practice. --- itest/integration_test.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/itest/integration_test.go b/itest/integration_test.go index c75ba0e04..ce7e9536f 100644 --- a/itest/integration_test.go +++ b/itest/integration_test.go @@ -47,24 +47,27 @@ func TestTaprootAssetsDaemon(t *testing.T) { testCase.name) success := t.Run(testCase.name, func(t1 *testing.T) { + // Create a subtest harness for each test case. + subTestLnd := lndHarness.Subtest(t1) + // The universe server and tapd client are both freshly // created and later discarded for each test run to // assure no state is taken over between runs. tapdHarness, universeServer, proofCourier := setupHarnesses( - t1, ht, lndHarness, + t1, ht, subTestLnd, testCase.proofCourierType, ) - lndHarness.EnsureConnected( - lndHarness.Alice, lndHarness.Bob, + subTestLnd.EnsureConnected( + subTestLnd.Alice, subTestLnd.Bob, ) - lndHarness.Alice.AddToLogf(logLine) - lndHarness.Bob.AddToLogf(logLine) + subTestLnd.Alice.AddToLogf(logLine) + subTestLnd.Bob.AddToLogf(logLine) ht := ht.newHarnessTest( - t1, lndHarness, universeServer, tapdHarness, - proofCourier, + t1, subTestLnd, universeServer, + tapdHarness, proofCourier, ) // Now we have everything to run the test case. From da65fba7edc9c29d74a8a09e42b0de6c44bad29b Mon Sep 17 00:00:00 2001 From: ffranr Date: Mon, 12 Jun 2023 20:52:37 +0100 Subject: [PATCH 3/3] itest: add test to ensure send procedure completes pending package --- itest/send_test.go | 92 ++++++++++++++++++++++++++++++++++++++ itest/test_list_on_test.go | 5 +++ 2 files changed, 97 insertions(+) diff --git a/itest/send_test.go b/itest/send_test.go index 81fd21b32..77b6c51c7 100644 --- a/itest/send_test.go +++ b/itest/send_test.go @@ -127,6 +127,98 @@ func testBasicSend(t *harnessTest) { wg.Wait() } +// testResumePendingPackageSend tests that we can properly resume a pending +// package send after a restart. +func testResumePendingPackageSend(t *harnessTest) { + ctxb := context.Background() + + sendTapd := t.tapd + + // Setup a receiver node. + recvLnd := t.lndHarness.Bob + recvTapd := setupTapdHarness( + t.t, t, recvLnd, t.universeServer, + func(params *tapdHarnessParams) { + // We expect the receiver node to exit with an error + // since it will fail to receive the asset at the first + // attempt. We will confirm that the receiver node does + // eventually receive the asset correctly via an RPC + // call. + params.expectErrExit = true + }, + ) + + // Mint (and mine) an asset for sending. + rpcAssets := mintAssetsConfirmBatch( + t, sendTapd, []*mintrpc.MintAssetRequest{simpleAssets[0]}, + ) + + genInfo := rpcAssets[0].AssetGenesis + + // Synchronize the Universe state of the sending node, with the + // receiving node. + t.syncUniverseState(sendTapd, recvTapd, len(rpcAssets)) + + // The receiver node generates a new address. + recvAddr, err := recvTapd.NewAddr( + ctxb, &taprpc.NewAddrRequest{ + AssetId: genInfo.AssetId, + Amt: 10, + }, + ) + require.NoError(t.t, err) + assertAddrCreated(t.t, recvTapd, rpcAssets[0], recvAddr) + + // We will now start two asset send events in sequence. We will stop and + // restart the sending node during each send. During one sending event + // we will mine whilst the sending node is stopped. During the other + // sending event we will only mine once the sending node is restarted. + for i := range []int{0, 1} { + mineWhileNodeDown := i == 0 + + // Start the asset send procedure. + t.t.Logf("Commencing asset send procedure") + sendAssetsToAddr(t, sendTapd, recvAddr) + + // Stop the sending node before mining the asset transfer's + // anchoring transaction. This will ensure that the send + // procedure does not complete. The sending node will be stalled + // waiting for the broadcast transaction to confirm. + t.t.Logf("Stopping sending tapd node") + err = sendTapd.stop(false) + require.NoError(t.t, err) + + if mineWhileNodeDown { + // Mine the anchoring transaction to ensure that the + // asset transfer is broadcast. + t.lndHarness.MineBlocks(6) + } + + // Re-commence the asset send procedure by restarting the + // sending node. The asset package should be picked up as a + // pending package. + t.t.Logf("Re-starting sending tapd node so as to complete " + + "transfer") + err = sendTapd.start(false) + require.NoError(t.t, err) + + if !mineWhileNodeDown { + // Complete the transfer by mining the anchoring + // transaction and sending the proof to the receiver + // node. + t.lndHarness.MineBlocks(6) + } + + _ = sendProof( + t, sendTapd, recvTapd, recvAddr.ScriptKey, genInfo, + ) + + // Confirm with the receiver node that the asset was fully + // received. + assertNonInteractiveRecvComplete(t, recvTapd, i+1) + } +} + // testBasicSendPassiveAsset tests that we can properly send assets which were // passive assets during a previous send. func testBasicSendPassiveAsset(t *harnessTest) { diff --git a/itest/test_list_on_test.go b/itest/test_list_on_test.go index a26e9619f..b151211e4 100644 --- a/itest/test_list_on_test.go +++ b/itest/test_list_on_test.go @@ -29,6 +29,11 @@ var testCases = []*testCase{ test: testBasicSend, proofCourierType: proof.ApertureCourier, }, + { + name: "resume pending package send", + test: testResumePendingPackageSend, + proofCourierType: proof.ApertureCourier, + }, { name: "reattempt failed asset send", test: testReattemptFailedAssetSend,