Skip to content

Commit

Permalink
itest: add test to ensure backoff procedure works for proof retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
ffranr committed Nov 1, 2023
1 parent d7e5c2f commit aaa4ea5
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
114 changes: 114 additions & 0 deletions itest/send_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,120 @@ func testReattemptFailedSendUniCourier(t *harnessTest) {
wg.Wait()
}

// testReattemptFailedReceiveUniCourier tests that a failed attempt at
// receiving an asset proof will be reattempted by the receiving tapd node. This
// test targets the universe proof courier.
func testReattemptFailedReceiveUniCourier(t *harnessTest) {
var (
ctxb = context.Background()
wg sync.WaitGroup
)

// Make a new node which will send the asset to the primary tapd node.
// We expect this node to fail because our send call will time out
// whilst the porter continues to attempt to send the asset.
sendTapd := setupTapdHarness(
t.t, t, t.lndHarness.Bob, t.universeServer,
func(params *tapdHarnessParams) {
params.expectErrExit = true
},
)

// Use the primary node as the receiver node.
receiveTapd := t.tapd

// Subscribe to receive asset receive events from receiving tapd node.
eventNtfns, err := receiveTapd.SubscribeSendAssetEventNtfns(
ctxb, &taprpc.SubscribeSendAssetEventNtfnsRequest{},
)
require.NoError(t.t, err)

// Test to ensure that we receive the expected number of backoff wait
// event notifications.
// This test is executed in a goroutine to ensure that we can receive
// the event notification(s) from the tapd node as the rest of the test
// proceeds.
wg.Add(1)
go func() {
defer wg.Done()

// Define a target event selector to match the backoff wait
// event. This function selects for a specific event type.
targetEventSelector := func(event *taprpc.SendAssetEvent) bool {
switch eventTyped := event.Event.(type) {
case *taprpc.SendAssetEvent_ProofTransferBackoffWaitEvent:
ev := eventTyped.ProofTransferBackoffWaitEvent

// We are attempting to identify receive
// transfer types. Skip the event if it is not
// a receiving transfer type.
if ev.TransferType != taprpc.ProofTransferType_PROOF_TRANSFER_TYPE_RECEIVE {
return false
}

t.Logf("Found event ntfs: %v", ev)
return true
}

return false
}

// Expected number of events is one less than the number of
// tries because the first attempt does not count as a backoff
// event.
nodeBackoffCfg := t.tapd.clientCfg.HashMailCourier.BackoffCfg
expectedEventCount := nodeBackoffCfg.NumTries - 1

// Context timeout scales with expected number of events.
timeout := time.Duration(expectedEventCount) *
defaultProofTransferReceiverAckTimeout
// Add overhead buffer to context timeout.
timeout += 5 * time.Second
ctx, cancel := context.WithTimeout(ctxb, timeout)
defer cancel()

assertRecvNtfsEvent(
t, ctx, eventNtfns, targetEventSelector,
expectedEventCount,
)
}()

// Mint an asset for sending.
rpcAssets := MintAssetsConfirmBatch(
t.t, t.lndHarness.Miner.Client, sendTapd,
[]*mintrpc.MintAssetRequest{simpleAssets[0]},
)

genInfo := rpcAssets[0].AssetGenesis

// Synchronize the Universe state of the second node, with the main
// node.
t.syncUniverseState(sendTapd, receiveTapd, len(rpcAssets))

// Create a new address for the receiver node.
recvAddr, err := t.tapd.NewAddr(ctxb, &taprpc.NewAddrRequest{
AssetId: genInfo.AssetId,
Amt: 10,
})
require.NoError(t.t, err)
AssertAddrCreated(t.t, receiveTapd, rpcAssets[0], recvAddr)

// Simulate a failed attempt at sending the asset proof by stopping
// the proof courier service.
//
// In following the hashmail proof courier protocol, the receiver node
// returns a proof received confirmation message via the courier.
// We can simulate a proof transfer failure by stopping the receiving
// tapd node. The courier service should still be operational.
require.NoError(t.t, t.proofCourier.Stop())

// Send asset and then mine to confirm the associated on-chain tx.
sendAssetsToAddr(t, sendTapd, recvAddr)
_ = MineBlocks(t.t, t.lndHarness.Miner.Client, 1, 1)

wg.Wait()
}

// testOfflineReceiverEventuallyReceives tests that a receiver node will
// eventually receive an asset even if it is offline whilst the sender node
// makes multiple attempts to send the asset. This test explicitly listens for
Expand Down
5 changes: 5 additions & 0 deletions itest/test_list_on_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ var testCases = []*testCase{
test: testReattemptFailedSendUniCourier,
proofCourierType: proof.UniverseRpcCourierType,
},
{
name: "reattempt failed receive uni courier",
test: testReattemptFailedReceiveUniCourier,
proofCourierType: proof.UniverseRpcCourierType,
},
{
name: "offline receiver eventually receives",
test: testOfflineReceiverEventuallyReceives,
Expand Down

0 comments on commit aaa4ea5

Please sign in to comment.