@@ -192,10 +192,166 @@ func testReOrgSend(t *harnessTest) {
192
192
bobAssets , err := secondTapd .ListAssets (ctxb , listAssetRequest )
193
193
require .NoError (t .t , err )
194
194
195
+ AssertBalances (
196
+ t .t , t .tapd , sendAsset .Amount - sendAmount ,
197
+ WithAssetID (sendAssetGen .AssetId ), WithNumUtxos (1 ),
198
+ )
199
+ AssertBalances (
200
+ t .t , t .tapd , assetList [1 ].Amount ,
201
+ WithAssetID (assetList [1 ].AssetGenesis .AssetId ), WithNumUtxos (1 ),
202
+ )
203
+ for idx := range aliceAssets .Assets {
204
+ a := aliceAssets .Assets [idx ]
205
+ AssertAssetProofsInvalid (t .t , t .tapd , a )
206
+ }
207
+
208
+ AssertBalances (
209
+ t .t , secondTapd , sendAmount , WithAssetID (sendAssetGen .AssetId ),
210
+ WithNumUtxos (1 ),
211
+ )
212
+ for idx := range bobAssets .Assets {
213
+ a := bobAssets .Assets [idx ]
214
+ AssertAssetProofsInvalid (t .t , secondTapd , a )
215
+ }
216
+
217
+ // Cleanup by mining the minting tx again.
218
+ newBlock := t .lndHarness .MineBlocksAndAssertNumTxes (1 , 1 )[0 ]
219
+ newBlockHash := newBlock .BlockHash ()
220
+ _ , newBlockHeight := lndMiner .GetBestBlock ()
221
+ lndMiner .AssertTxInBlock (newBlock , * sendTXID )
222
+ t .Logf ("Send TX %v re-mined in block %v" , sendTXID , newBlockHash )
223
+
224
+ // Let's wait until we see that the proof for the first asset was
225
+ // updated to the new block height.
226
+ WaitForProofUpdate (t .t , t .tapd , aliceAssets .Assets [0 ], newBlockHeight )
227
+ WaitForProofUpdate (t .t , secondTapd , bobAssets .Assets [0 ], newBlockHeight )
228
+
229
+ // We now try to validate the send proofs of the delivered, change and
230
+ // passive assets. The re-org watcher should have updated the proofs and
231
+ // pushed them to the proof store. They should be valid now.
232
+ aliceChainClient := t .tapd .cfg .LndNode .RPC .ChainKit
233
+ for idx := range aliceAssets .Assets {
234
+ a := aliceAssets .Assets [idx ]
235
+ AssertAssetProofs (t .t , t .tapd , aliceChainClient , a )
236
+ }
237
+
238
+ bobChainClient := secondTapd .cfg .LndNode .RPC .ChainKit
239
+ for idx := range bobAssets .Assets {
240
+ a := bobAssets .Assets [idx ]
241
+ AssertAssetProofs (t .t , secondTapd , bobChainClient , a )
242
+ }
243
+
244
+ // Let's now bury the proofs under sufficient blocks to allow the re-org
245
+ // watcher to stop watching the TX.
246
+ t .lndHarness .MineBlocks (8 )
247
+
248
+ // Make sure the balances are shown correctly after the re-org.
249
+ AssertBalances (
250
+ t .t , t .tapd , sendAsset .Amount - sendAmount ,
251
+ WithAssetID (sendAssetGen .AssetId ), WithNumUtxos (1 ),
252
+ )
253
+ AssertBalances (
254
+ t .t , t .tapd , assetList [1 ].Amount ,
255
+ WithAssetID (assetList [1 ].AssetGenesis .AssetId ), WithNumUtxos (1 ),
256
+ )
257
+ AssertBalances (
258
+ t .t , secondTapd , sendAmount , WithAssetID (sendAssetGen .AssetId ),
259
+ WithNumUtxos (1 ),
260
+ )
261
+ }
262
+
263
+ // testReOrgSendV2Address tests that when a re-org occurs with a v2 address,
264
+ // sent asset proofs are updated accordingly.
265
+ func testReOrgSendV2Address (t * harnessTest ) {
266
+ // First, we'll mint a few assets and confirm the batch TX.
267
+ mintRequests := []* mintrpc.MintAssetRequest {
268
+ issuableAssets [0 ], issuableAssets [1 ],
269
+ }
270
+ lndMiner := t .lndHarness .Miner ()
271
+ assetList := MintAssetsConfirmBatch (
272
+ t .t , lndMiner .Client , t .tapd , mintRequests ,
273
+ )
274
+
275
+ ctxb := context .Background ()
276
+ ctxt , cancel := context .WithTimeout (ctxb , defaultWaitTimeout )
277
+ defer cancel ()
278
+
279
+ // Now that we have the asset created, we'll make a new node that'll
280
+ // serve as the node which'll receive the assets. The existing tapd
281
+ // node will be used to synchronize universe state.
282
+ lndBob := t .lndHarness .NewNodeWithCoins ("Bob" , nil )
283
+ secondTapd := setupTapdHarness (t .t , t , lndBob , t .universeServer )
284
+ defer func () {
285
+ require .NoError (t .t , secondTapd .stop (! * noDelete ))
286
+ }()
287
+
288
+ // Before we mine a block to confirm the mint TX, we create a temporary
289
+ // miner.
290
+ tempMiner := spawnTempMiner (t .t , t , ctxt )
291
+
292
+ // Now to the second part of the test: We'll send an asset to Bob, and
293
+ // then re-org the chain again.
294
+ sendAsset := assetList [0 ]
295
+ sendAssetGen := sendAsset .AssetGenesis
296
+ sendAmount := uint64 (500 )
297
+ bobAddrV2 , err := secondTapd .NewAddr (ctxt , & taprpc.NewAddrRequest {
298
+ GroupKey : sendAsset .AssetGroup .TweakedGroupKey ,
299
+ Amt : sendAmount ,
300
+ AddressVersion : addrV2 ,
301
+ })
302
+ require .NoError (t .t , err )
303
+ AssertAddrCreated (t .t , secondTapd , sendAsset , bobAddrV2 )
304
+
305
+ sendResp , _ := sendAssetsToAddr (t , t .tapd , bobAddrV2 )
306
+ initialBlock := ConfirmAndAssertOutboundTransfer (
307
+ t .t , lndMiner .Client , t .tapd , sendResp , sendAssetGen .AssetId ,
308
+ []uint64 {sendAsset .Amount - sendAmount , sendAmount }, 0 , 1 ,
309
+ )
310
+ AssertNonInteractiveRecvComplete (t .t , secondTapd , 1 )
311
+ initialBlockHash := initialBlock .BlockHash ()
312
+
313
+ // Make sure the original send TX was mined in the first block.
314
+ sendTXID , err := chainhash .NewHash (sendResp .Transfer .AnchorTxHash )
315
+ require .NoError (t .t , err )
316
+ lndMiner .AssertTxInBlock (initialBlock , * sendTXID )
317
+ t .Logf ("Send TX %v mined in block %v" , sendTXID , initialBlockHash )
318
+
319
+ // We now generate the re-org. That should put the minting TX back into
320
+ // the mempool.
321
+ generateReOrg (t .t , t .lndHarness , tempMiner , 3 , 2 )
322
+ lndMiner .AssertNumTxsInMempool (1 )
323
+
324
+ // This should have caused a reorg, and Alice should sync to the longer
325
+ // chain, where the funding transaction is not confirmed.
326
+ _ , tempMinerHeight , err := tempMiner .Client .GetBestBlock ()
327
+ require .NoError (t .t , err , "unable to get current block height" )
328
+ t .lndHarness .WaitForNodeBlockHeight (t .tapd .cfg .LndNode , tempMinerHeight )
329
+
330
+ // At this point, the all asset proofs should be invalid, since the send
331
+ // TX was re-organized out, and it also contained passive assets.
332
+ listAssetRequest := & taprpc.ListAssetRequest {}
333
+ aliceAssets , err := t .tapd .ListAssets (ctxb , listAssetRequest )
334
+ require .NoError (t .t , err )
335
+ bobAssets , err := secondTapd .ListAssets (ctxb , listAssetRequest )
336
+ require .NoError (t .t , err )
337
+
338
+ AssertBalances (
339
+ t .t , t .tapd , sendAsset .Amount - sendAmount ,
340
+ WithAssetID (sendAssetGen .AssetId ), WithNumUtxos (1 ),
341
+ )
342
+ AssertBalances (
343
+ t .t , t .tapd , assetList [1 ].Amount ,
344
+ WithAssetID (assetList [1 ].AssetGenesis .AssetId ), WithNumUtxos (1 ),
345
+ )
195
346
for idx := range aliceAssets .Assets {
196
347
a := aliceAssets .Assets [idx ]
197
348
AssertAssetProofsInvalid (t .t , t .tapd , a )
198
349
}
350
+
351
+ AssertBalances (
352
+ t .t , secondTapd , sendAmount , WithAssetID (sendAssetGen .AssetId ),
353
+ WithNumUtxos (1 ),
354
+ )
199
355
for idx := range bobAssets .Assets {
200
356
a := bobAssets .Assets [idx ]
201
357
AssertAssetProofsInvalid (t .t , secondTapd , a )
@@ -231,6 +387,20 @@ func testReOrgSend(t *harnessTest) {
231
387
// Let's now bury the proofs under sufficient blocks to allow the re-org
232
388
// watcher to stop watching the TX.
233
389
t .lndHarness .MineBlocks (8 )
390
+
391
+ // Make sure the balances are shown correctly after the re-org.
392
+ AssertBalances (
393
+ t .t , t .tapd , sendAsset .Amount - sendAmount ,
394
+ WithAssetID (sendAssetGen .AssetId ), WithNumUtxos (1 ),
395
+ )
396
+ AssertBalances (
397
+ t .t , t .tapd , assetList [1 ].Amount ,
398
+ WithAssetID (assetList [1 ].AssetGenesis .AssetId ), WithNumUtxos (1 ),
399
+ )
400
+ AssertBalances (
401
+ t .t , secondTapd , sendAmount , WithAssetID (sendAssetGen .AssetId ),
402
+ WithNumUtxos (1 ),
403
+ )
234
404
}
235
405
236
406
// testReOrgMintAndSend tests that when a re-org occurs, minted and directly
0 commit comments