@@ -258,14 +258,15 @@ func createTestAssetNetwork(t *harnessTest, net *NetworkHarness, charlieTap,
258
258
// Make sure the channel shows the correct asset information.
259
259
assertAssetChan (
260
260
t .t , charlieTap .node , daveTap .node , charlieFundingAmount ,
261
- mintedAsset ,
261
+ [] * taprpc. Asset { mintedAsset } ,
262
262
)
263
263
assertAssetChan (
264
- t .t , daveTap .node , yaraTap .node , daveFundingAmount , mintedAsset ,
264
+ t .t , daveTap .node , yaraTap .node , daveFundingAmount ,
265
+ []* taprpc.Asset {mintedAsset },
265
266
)
266
267
assertAssetChan (
267
268
t .t , erinTap .node , fabiaTap .node , erinFundingAmount ,
268
- mintedAsset ,
269
+ [] * taprpc. Asset { mintedAsset } ,
269
270
)
270
271
271
272
chanPointCD := & lnrpc.ChannelPoint {
@@ -473,7 +474,7 @@ func assertPendingChannels(t *testing.T, node *HarnessNode,
473
474
pendingChan .Channel .CustomChannelData , & pendingJSON ,
474
475
)
475
476
require .NoError (t , err )
476
- require .Len (t , pendingJSON .FundingAssets , 1 )
477
+ require .GreaterOrEqual (t , len ( pendingJSON .FundingAssets ) , 1 )
477
478
478
479
require .NotZero (t , pendingJSON .Capacity )
479
480
@@ -494,9 +495,7 @@ func assertPendingChannels(t *testing.T, node *HarnessNode,
494
495
// Check the balance of the pending channel.
495
496
assetID := mintedAsset .AssetGenesis .AssetId
496
497
pendingLocalBalance , pendingRemoteBalance , _ , _ :=
497
- getAssetChannelBalance (
498
- t , node , assetID , true ,
499
- )
498
+ getAssetChannelBalance (t , node , [][]byte {assetID }, true )
500
499
require .EqualValues (t , localSum , pendingLocalBalance )
501
500
require .EqualValues (t , remoteSum , pendingRemoteBalance )
502
501
}
@@ -517,18 +516,20 @@ func haveFundingAsset(assetChannel *rfqmsg.JsonAssetChannel,
517
516
}
518
517
519
518
func assertAssetChan (t * testing.T , src , dst * HarnessNode , fundingAmount uint64 ,
520
- channelAsset * taprpc.Asset ) {
519
+ channelAssets [] * taprpc.Asset ) {
521
520
522
521
err := wait .NoError (func () error {
523
522
a , err := getChannelCustomData (src , dst )
524
523
if err != nil {
525
524
return err
526
525
}
527
526
528
- assetID := channelAsset .AssetGenesis .AssetId
529
- if ! haveFundingAsset (a , assetID ) {
530
- return fmt .Errorf ("expected asset ID %x, to " +
531
- "be in channel" , assetID )
527
+ for _ , channelAsset := range channelAssets {
528
+ assetID := channelAsset .AssetGenesis .AssetId
529
+ if ! haveFundingAsset (a , assetID ) {
530
+ return fmt .Errorf ("expected asset ID %x, to " +
531
+ "be in channel" , assetID )
532
+ }
532
533
}
533
534
534
535
if a .Capacity != fundingAmount {
@@ -541,9 +542,9 @@ func assertAssetChan(t *testing.T, src, dst *HarnessNode, fundingAmount uint64,
541
542
// We only need to check the first funding asset, since we
542
543
// enforce them to be the same.
543
544
var expectedDecimalDisplay uint8
544
- if channelAsset .DecimalDisplay != nil {
545
+ if channelAssets [ 0 ] .DecimalDisplay != nil {
545
546
expectedDecimalDisplay = uint8 (
546
- channelAsset .DecimalDisplay .DecimalDisplay ,
547
+ channelAssets [ 0 ] .DecimalDisplay .DecimalDisplay ,
547
548
)
548
549
}
549
550
@@ -639,7 +640,7 @@ func getChannelCustomData(src, dst *HarnessNode) (*rfqmsg.JsonAssetChannel,
639
640
return & assetData , nil
640
641
}
641
642
642
- func getAssetChannelBalance (t * testing.T , node * HarnessNode , assetID []byte ,
643
+ func getAssetChannelBalance (t * testing.T , node * HarnessNode , assetIDs [] []byte ,
643
644
pending bool ) (uint64 , uint64 , uint64 , uint64 ) {
644
645
645
646
ctxb := context .Background ()
@@ -651,18 +652,34 @@ func getAssetChannelBalance(t *testing.T, node *HarnessNode, assetID []byte,
651
652
)
652
653
require .NoError (t , err )
653
654
655
+ // In case there are no channels, the custom channel data will just be
656
+ // empty. Which means the total asset balance is zero.
657
+ if len (balance .CustomChannelData ) == 0 {
658
+ return 0 , 0 , 0 , 0
659
+ }
660
+
654
661
var assetBalance rfqmsg.JsonAssetChannelBalances
655
662
err = json .Unmarshal (balance .CustomChannelData , & assetBalance )
656
- require .NoError (t , err )
663
+ require .NoErrorf (t , err , "json: '%x'" , balance . CustomChannelData )
657
664
658
665
balances := assetBalance .OpenChannels
659
666
if pending {
660
667
balances = assetBalance .PendingChannels
661
668
}
662
669
670
+ idMatch := func (assetIDString string ) bool {
671
+ for _ , groupedID := range assetIDs {
672
+ if assetIDString == hex .EncodeToString (groupedID ) {
673
+ return true
674
+ }
675
+ }
676
+
677
+ return false
678
+ }
679
+
663
680
var localSum , remoteSum uint64
664
681
for assetIDString := range balances {
665
- if assetIDString != hex . EncodeToString ( assetID ) {
682
+ if ! idMatch ( assetIDString ) {
666
683
continue
667
684
}
668
685
@@ -1368,12 +1385,12 @@ func waitForSendEvent(t *testing.T,
1368
1385
// transaction.
1369
1386
type coOpCloseBalanceCheck func (t * testing.T , local , remote * HarnessNode ,
1370
1387
closeTx * wire.MsgTx , closeUpdate * lnrpc.ChannelCloseUpdate ,
1371
- assetID , groupKey []byte , universeTap * tapClient )
1388
+ assetIDs [][] byte , groupKey []byte , universeTap * tapClient )
1372
1389
1373
1390
// noOpCoOpCloseBalanceCheck is a no-op implementation of the co-op close
1374
1391
// balance check that can be used in tests.
1375
1392
func noOpCoOpCloseBalanceCheck (_ * testing.T , _ , _ * HarnessNode , _ * wire.MsgTx ,
1376
- _ * lnrpc.ChannelCloseUpdate , _ , _ []byte , _ * tapClient ) {
1393
+ _ * lnrpc.ChannelCloseUpdate , _ [][] byte , _ []byte , _ * tapClient ) {
1377
1394
1378
1395
// This is a no-op function.
1379
1396
}
@@ -1382,7 +1399,7 @@ func noOpCoOpCloseBalanceCheck(_ *testing.T, _, _ *HarnessNode, _ *wire.MsgTx,
1382
1399
// node and asserts the final balances of the closing transaction.
1383
1400
func closeAssetChannelAndAssert (t * harnessTest , net * NetworkHarness ,
1384
1401
local , remote * HarnessNode , chanPoint * lnrpc.ChannelPoint ,
1385
- assetID , groupKey []byte , universeTap * tapClient ,
1402
+ assetIDs [][] byte , groupKey []byte , universeTap * tapClient ,
1386
1403
balanceCheck coOpCloseBalanceCheck ) {
1387
1404
1388
1405
t .t .Helper ()
@@ -1422,7 +1439,7 @@ func closeAssetChannelAndAssert(t *harnessTest, net *NetworkHarness,
1422
1439
1423
1440
// Check the final balance of the closing transaction.
1424
1441
balanceCheck (
1425
- t .t , local , remote , closeTx , closeUpdate , assetID , groupKey ,
1442
+ t .t , local , remote , closeTx , closeUpdate , assetIDs , groupKey ,
1426
1443
universeTap ,
1427
1444
)
1428
1445
@@ -1439,10 +1456,10 @@ func assertDefaultCoOpCloseBalance(remoteBtcBalance,
1439
1456
1440
1457
return func (t * testing.T , local , remote * HarnessNode ,
1441
1458
closeTx * wire.MsgTx , closeUpdate * lnrpc.ChannelCloseUpdate ,
1442
- assetID , groupKey []byte , universeTap * tapClient ) {
1459
+ assetIDs [][] byte , groupKey []byte , universeTap * tapClient ) {
1443
1460
1444
1461
defaultCoOpCloseBalanceCheck (
1445
- t , local , remote , closeTx , closeUpdate , assetID ,
1462
+ t , local , remote , closeTx , closeUpdate , assetIDs ,
1446
1463
groupKey , universeTap , remoteBtcBalance ,
1447
1464
remoteAssetBalance ,
1448
1465
)
@@ -1455,8 +1472,8 @@ func assertDefaultCoOpCloseBalance(remoteBtcBalance,
1455
1472
// with the boolean variables.
1456
1473
func defaultCoOpCloseBalanceCheck (t * testing.T , local , remote * HarnessNode ,
1457
1474
closeTx * wire.MsgTx , closeUpdate * lnrpc.ChannelCloseUpdate ,
1458
- assetID , groupKey []byte , universeTap * tapClient , remoteBtcBalance ,
1459
- remoteAssetBalance bool ) {
1475
+ assetIDs [][] byte , groupKey []byte , universeTap * tapClient ,
1476
+ remoteBtcBalance , remoteAssetBalance bool ) {
1460
1477
1461
1478
// With the channel closed, we'll now assert that the co-op close
1462
1479
// transaction was inserted into the local universe.
@@ -1563,11 +1580,15 @@ func defaultCoOpCloseBalanceCheck(t *testing.T, local, remote *HarnessNode,
1563
1580
)
1564
1581
require .NoError (t , err )
1565
1582
1583
+ assetIDStrings := fn .Map (hex .EncodeToString , assetIDs )
1566
1584
for assetIDStr , scriptKeyStr := range localAssetCloseOut .ScriptKeys {
1567
1585
scriptKeyBytes , err := hex .DecodeString (scriptKeyStr )
1568
1586
require .NoError (t , err )
1569
1587
1570
- require .Equal (t , hex .EncodeToString (assetID ), assetIDStr )
1588
+ require .Contains (t , assetIDStrings , assetIDStr )
1589
+
1590
+ assetID , err := hex .DecodeString (assetIDStr )
1591
+ require .NoError (t , err )
1571
1592
1572
1593
a := assertUniverseProofExists (
1573
1594
t , universeTap , assetID , groupKey , scriptKeyBytes ,
@@ -1605,7 +1626,10 @@ func defaultCoOpCloseBalanceCheck(t *testing.T, local, remote *HarnessNode,
1605
1626
scriptKeyBytes , err := hex .DecodeString (scriptKeyStr )
1606
1627
require .NoError (t , err )
1607
1628
1608
- require .Equal (t , hex .EncodeToString (assetID ), assetIDStr )
1629
+ require .Contains (t , assetIDStrings , assetIDStr )
1630
+
1631
+ assetID , err := hex .DecodeString (assetIDStr )
1632
+ require .NoError (t , err )
1609
1633
1610
1634
a := assertUniverseProofExists (
1611
1635
t , universeTap , assetID , groupKey , scriptKeyBytes ,
@@ -1627,8 +1651,8 @@ func defaultCoOpCloseBalanceCheck(t *testing.T, local, remote *HarnessNode,
1627
1651
// function that can be used when the initiator has a zero asset balance.
1628
1652
func initiatorZeroAssetBalanceCoOpBalanceCheck (t * testing.T , _ ,
1629
1653
remote * HarnessNode , closeTx * wire.MsgTx ,
1630
- closeUpdate * lnrpc.ChannelCloseUpdate , assetID , groupKey []byte ,
1631
- universeTap * tapClient ) {
1654
+ closeUpdate * lnrpc.ChannelCloseUpdate , assetIDs [] []byte ,
1655
+ groupKey [] byte , universeTap * tapClient ) {
1632
1656
1633
1657
// With the channel closed, we'll now assert that the co-op close
1634
1658
// transaction was inserted into the local universe.
@@ -1674,11 +1698,15 @@ func initiatorZeroAssetBalanceCoOpBalanceCheck(t *testing.T, _,
1674
1698
)
1675
1699
require .NoError (t , err )
1676
1700
1701
+ assetIDStrings := fn .Map (hex .EncodeToString , assetIDs )
1677
1702
for assetIDStr , scriptKeyStr := range remoteAssetCloseOut .ScriptKeys {
1678
1703
scriptKeyBytes , err := hex .DecodeString (scriptKeyStr )
1679
1704
require .NoError (t , err )
1680
1705
1681
- require .Equal (t , hex .EncodeToString (assetID ), assetIDStr )
1706
+ require .Contains (t , assetIDStrings , assetIDStr )
1707
+
1708
+ assetID , err := hex .DecodeString (assetIDStr )
1709
+ require .NoError (t , err )
1682
1710
1683
1711
a := assertUniverseProofExists (
1684
1712
t , universeTap , assetID , groupKey , scriptKeyBytes ,
@@ -1821,12 +1849,15 @@ func assertAssetBalance(t *testing.T, client *tapClient, assetID []byte,
1821
1849
},
1822
1850
}
1823
1851
1852
+ var lastBalances * taprpc.ListBalancesResponse
1824
1853
err := wait .NoError (func () error {
1825
1854
assetIDBalances , err := client .ListBalances (ctxt , req )
1826
1855
if err != nil {
1827
1856
return err
1828
1857
}
1829
1858
1859
+ lastBalances = assetIDBalances
1860
+
1830
1861
assetIDFound := false
1831
1862
for _ , balance := range assetIDBalances .AssetBalances {
1832
1863
if ! bytes .Equal (balance .AssetGenesis .AssetId , assetID ) {
@@ -1847,11 +1878,16 @@ func assertAssetBalance(t *testing.T, client *tapClient, assetID []byte,
1847
1878
return nil
1848
1879
}, shortTimeout )
1849
1880
if err != nil {
1850
- r , err2 := client .ListAssets (ctxb , & taprpc.ListAssetRequest {})
1881
+ listAssetsResp , err2 := client .ListAssets (
1882
+ ctxb , & taprpc.ListAssetRequest {},
1883
+ )
1851
1884
require .NoError (t , err2 )
1852
1885
1853
- t .Logf ("Failed to assert expected balance of %d, current " +
1854
- "assets: %v" , expectedBalance , toProtoJSON (t , r ))
1886
+ t .Logf ("Failed to assert expected balance of %d for asset ID " +
1887
+ "%x: %v" , expectedBalance , assetID , err )
1888
+
1889
+ t .Logf ("Last balances: %v" , toProtoJSON (t , lastBalances ))
1890
+ t .Logf ("Current assets: %v" , toProtoJSON (t , listAssetsResp ))
1855
1891
1856
1892
utxos , err3 := client .ListUtxos (
1857
1893
ctxb , & taprpc.ListUtxosRequest {},
@@ -2031,8 +2067,9 @@ func logBalance(t *testing.T, nodes []*HarnessNode, assetID []byte,
2031
2067
time .Sleep (time .Millisecond * 250 )
2032
2068
2033
2069
for _ , node := range nodes {
2034
- local , remote , localSat , remoteSat :=
2035
- getAssetChannelBalance (t , node , assetID , false )
2070
+ local , remote , localSat , remoteSat := getAssetChannelBalance (
2071
+ t , node , [][]byte {assetID }, false ,
2072
+ )
2036
2073
2037
2074
t .Logf ("%-7s balance: local=%-9d remote=%-9d, localSat=%-9d, " +
2038
2075
"remoteSat=%-9d (%v)" , node .Cfg .Name , local , remote ,
@@ -2265,9 +2302,9 @@ func assertPendingChannelAssetData(t *testing.T, node *HarnessNode,
2265
2302
"data: %v" , err )
2266
2303
}
2267
2304
2268
- if len (closeData .FundingAssets ) != 1 {
2269
- return fmt .Errorf ("expected 1 funding asset, got %d" ,
2270
- len (closeData .FundingAssets ))
2305
+ if len (closeData .FundingAssets ) == 0 {
2306
+ return fmt .Errorf ("expected at least 1 funding asset, " +
2307
+ "got %d" , len (closeData .FundingAssets ))
2271
2308
}
2272
2309
2273
2310
return nil
@@ -2363,3 +2400,47 @@ func assertClosedChannelAssetData(t *testing.T, node *HarnessNode,
2363
2400
2364
2401
require .GreaterOrEqual (t , len (closeData .FundingAssets ), 1 )
2365
2402
}
2403
+
2404
+ func findForceCloseTransfer (t * testing.T , node1 , node2 * tapClient ,
2405
+ closeTxid * chainhash.Hash ) * taprpc.ListTransfersResponse {
2406
+
2407
+ var (
2408
+ ctxb = context .Background ()
2409
+ result * taprpc.ListTransfersResponse
2410
+ err error
2411
+ )
2412
+ fErr := wait .NoError (func () error {
2413
+ result , err = node1 .ListTransfers (
2414
+ ctxb , & taprpc.ListTransfersRequest {
2415
+ AnchorTxid : closeTxid .String (),
2416
+ },
2417
+ )
2418
+ if err != nil {
2419
+ return fmt .Errorf ("unable to list node1 transfers: %w" ,
2420
+ err )
2421
+ }
2422
+ if len (result .Transfers ) != 1 {
2423
+ return fmt .Errorf ("node1 is missing force close " +
2424
+ "transfer" )
2425
+ }
2426
+
2427
+ forceCloseTransfer2 , err := node2 .ListTransfers (
2428
+ ctxb , & taprpc.ListTransfersRequest {
2429
+ AnchorTxid : closeTxid .String (),
2430
+ },
2431
+ )
2432
+ if err != nil {
2433
+ return fmt .Errorf ("unable to list node2 transfers: %w" ,
2434
+ err )
2435
+ }
2436
+ if len (forceCloseTransfer2 .Transfers ) != 1 {
2437
+ return fmt .Errorf ("node2 is missing force close " +
2438
+ "transfer" )
2439
+ }
2440
+
2441
+ return nil
2442
+ }, defaultTimeout )
2443
+ require .NoError (t , fErr )
2444
+
2445
+ return result
2446
+ }
0 commit comments