|
4 | 4 | "context" |
5 | 5 | "fmt" |
6 | 6 | prand "math/rand" |
| 7 | + "math/rand/v2" |
7 | 8 | "testing" |
8 | 9 | "time" |
9 | 10 |
|
@@ -54,7 +55,155 @@ func sendTest(t *testing.T, ctx context.Context, cfg *Config) { |
54 | 55 | } |
55 | 56 | } |
56 | 57 |
|
57 | | -// sendAssets sends the given number of assets of the given type from the given |
| 58 | +// sendTestV2 checks that we are able to send assets between the two nodes. It |
| 59 | +// is a more performant and lightweight version of sendTest, as it uses less |
| 60 | +// assertions and RPC calls. |
| 61 | +func sendTestV2(t *testing.T, ctx context.Context, cfg *Config) { |
| 62 | + // Start by initializing all our client connections. |
| 63 | + alice, bob, bitcoinClient := initClients(t, ctx, cfg) |
| 64 | + |
| 65 | + ctxb := context.Background() |
| 66 | + ctxt, cancel := context.WithTimeout(ctxb, cfg.TestTimeout) |
| 67 | + defer cancel() |
| 68 | + |
| 69 | + sendType := stringToAssetType(cfg.SendAssetType) |
| 70 | + |
| 71 | + // Alice is set to be the minter in mintV2, so we use Alice's universe. |
| 72 | + uniHost := fmt.Sprintf("%s:%d", alice.cfg.Host, alice.cfg.Port) |
| 73 | + |
| 74 | + // Let's make sure Bob is aware of all the assets that Alice may have |
| 75 | + // minted. |
| 76 | + itest.SyncUniverses( |
| 77 | + ctx, t, bob, alice, uniHost, cfg.TestTimeout, |
| 78 | + itest.WithSyncMode(itest.SyncModeFull), |
| 79 | + ) |
| 80 | + |
| 81 | + // We now retrieve Alice and Bob's balances just once, and will re-use |
| 82 | + // them in future function calls. Any update to the balances will be |
| 83 | + // directly applied to these response objects, to skip future calls to |
| 84 | + // ListBalances. |
| 85 | + resAlice, err := alice.ListBalances(ctx, &taprpc.ListBalancesRequest{ |
| 86 | + GroupBy: &taprpc.ListBalancesRequest_AssetId{ |
| 87 | + AssetId: true, |
| 88 | + }, |
| 89 | + }) |
| 90 | + require.NoError(t, err) |
| 91 | + |
| 92 | + resBob, err := bob.ListBalances(ctx, &taprpc.ListBalancesRequest{ |
| 93 | + GroupBy: &taprpc.ListBalancesRequest_AssetId{ |
| 94 | + AssetId: true, |
| 95 | + }, |
| 96 | + }) |
| 97 | + require.NoError(t, err) |
| 98 | + |
| 99 | + for i := 1; i <= cfg.NumSends; i++ { |
| 100 | + var ( |
| 101 | + sender, receiver *rpcClient |
| 102 | + senderAssets map[string]*taprpc.AssetBalance |
| 103 | + ) |
| 104 | + |
| 105 | + // Assets may be sent in both directions, so we make a random |
| 106 | + // draw to conclude who the sender is. |
| 107 | + draw := rand.IntN(2) |
| 108 | + |
| 109 | + switch draw { |
| 110 | + case 0: |
| 111 | + sender = alice |
| 112 | + senderAssets = resAlice.AssetBalances |
| 113 | + receiver = bob |
| 114 | + |
| 115 | + case 1: |
| 116 | + sender = bob |
| 117 | + senderAssets = resBob.AssetBalances |
| 118 | + receiver = alice |
| 119 | + } |
| 120 | + |
| 121 | + sendAssetV2( |
| 122 | + t, ctxt, cfg.NumAssets, sendType, senderAssets, |
| 123 | + sender, receiver, bitcoinClient, cfg.TestTimeout, |
| 124 | + ) |
| 125 | + } |
| 126 | +} |
| 127 | + |
| 128 | +// sendAssetV2 sends a certain amount of assets of a specific type from a sender |
| 129 | +// to a receiver. It will scan the balance of the sender and find a suitable |
| 130 | +// asset to carry out the send, then will dispatch the send and assert its |
| 131 | +// completion. |
| 132 | +func sendAssetV2(t *testing.T, ctx context.Context, numAssets uint64, |
| 133 | + assetType taprpc.AssetType, assets map[string]*taprpc.AssetBalance, |
| 134 | + sender, receiver *rpcClient, bitcoinClient *rpcclient.Client, |
| 135 | + timeout time.Duration) { |
| 136 | + |
| 137 | + // Look over the sender's balances to see if any asset balance qualifies |
| 138 | + // for this send. |
| 139 | + var ( |
| 140 | + assetID []byte |
| 141 | + balance *taprpc.AssetBalance |
| 142 | + ) |
| 143 | + for _, v := range assets { |
| 144 | + if v.Balance >= numAssets && |
| 145 | + v.AssetGenesis.AssetType == assetType { |
| 146 | + |
| 147 | + assetID = v.AssetGenesis.AssetId |
| 148 | + balance = v |
| 149 | + |
| 150 | + break |
| 151 | + } |
| 152 | + } |
| 153 | + |
| 154 | + // No balance satisfies the amount of this send, we can skip this round. |
| 155 | + if assetID == nil { |
| 156 | + t.Logf("%s could not send %v assets, no available balance", |
| 157 | + sender.cfg.Name, numAssets) |
| 158 | + |
| 159 | + return |
| 160 | + } |
| 161 | + |
| 162 | + t.Logf("%s sending %v assets to %s", sender.cfg.Name, numAssets, |
| 163 | + receiver.cfg.Name) |
| 164 | + |
| 165 | + // Receiver creates the address to receive the assets. |
| 166 | + addr, err := receiver.NewAddr(ctx, &taprpc.NewAddrRequest{ |
| 167 | + AssetId: assetID, |
| 168 | + Amt: numAssets, |
| 169 | + ProofCourierAddr: fmt.Sprintf( |
| 170 | + "%s://%s:%d", proof.UniverseRpcCourierType, |
| 171 | + sender.cfg.Host, sender.cfg.Port, |
| 172 | + ), |
| 173 | + }) |
| 174 | + require.NoError(t, err) |
| 175 | + |
| 176 | + t.Logf("%s created address %v", receiver.cfg.Name, addr.String()) |
| 177 | + |
| 178 | + // Sender initiates the send. |
| 179 | + _, err = sender.SendAsset(ctx, &taprpc.SendAssetRequest{ |
| 180 | + TapAddrs: []string{addr.Encoded}, |
| 181 | + }) |
| 182 | + require.NoError(t, err) |
| 183 | + t.Logf("%s sent assets to address %v", sender.cfg.Name, addr.String()) |
| 184 | + |
| 185 | + // We assert the receiver detects the spend. |
| 186 | + itest.AssertAddrEventCustomTimeout( |
| 187 | + t, receiver, addr, 1, statusDetected, timeout, |
| 188 | + ) |
| 189 | + t.Logf("%s detected send", receiver.cfg.Name) |
| 190 | + |
| 191 | + // Mine a block to confirm the transfer. |
| 192 | + itest.MineBlocks(t, bitcoinClient, 1, 0) |
| 193 | + t.Log("Mined 1 block") |
| 194 | + |
| 195 | + // Assert that the transfer is now completed |
| 196 | + itest.AssertAddrEventCustomTimeout( |
| 197 | + t, receiver, addr, 1, statusCompleted, timeout, |
| 198 | + ) |
| 199 | + t.Logf("%s completed send of %v assets", sender.cfg.Name, numAssets) |
| 200 | + |
| 201 | + // If everything completed correctly, subtract the asset amount from the |
| 202 | + // sender's asset balance. |
| 203 | + balance.Balance -= numAssets |
| 204 | +} |
| 205 | + |
| 206 | +// sendAsset sends the given number of assets of the given type from the given |
58 | 207 | // node to the other node. |
59 | 208 | func sendAssets(t *testing.T, ctx context.Context, numAssets uint64, |
60 | 209 | assetType taprpc.AssetType, send, receive *rpcClient, |
|
0 commit comments