Skip to content

Commit e2388fc

Browse files
committed
itest: refactor to prepare for grouped assets
This commit prepares some of the helper functions to be able to handle channels that have multiple asset pieces in them.
1 parent 322f818 commit e2388fc

File tree

2 files changed

+154
-95
lines changed

2 files changed

+154
-95
lines changed

itest/assets_test.go

+119-38
Original file line numberDiff line numberDiff line change
@@ -258,14 +258,15 @@ func createTestAssetNetwork(t *harnessTest, net *NetworkHarness, charlieTap,
258258
// Make sure the channel shows the correct asset information.
259259
assertAssetChan(
260260
t.t, charlieTap.node, daveTap.node, charlieFundingAmount,
261-
mintedAsset,
261+
[]*taprpc.Asset{mintedAsset},
262262
)
263263
assertAssetChan(
264-
t.t, daveTap.node, yaraTap.node, daveFundingAmount, mintedAsset,
264+
t.t, daveTap.node, yaraTap.node, daveFundingAmount,
265+
[]*taprpc.Asset{mintedAsset},
265266
)
266267
assertAssetChan(
267268
t.t, erinTap.node, fabiaTap.node, erinFundingAmount,
268-
mintedAsset,
269+
[]*taprpc.Asset{mintedAsset},
269270
)
270271

271272
chanPointCD := &lnrpc.ChannelPoint{
@@ -473,7 +474,7 @@ func assertPendingChannels(t *testing.T, node *HarnessNode,
473474
pendingChan.Channel.CustomChannelData, &pendingJSON,
474475
)
475476
require.NoError(t, err)
476-
require.Len(t, pendingJSON.FundingAssets, 1)
477+
require.GreaterOrEqual(t, len(pendingJSON.FundingAssets), 1)
477478

478479
require.NotZero(t, pendingJSON.Capacity)
479480

@@ -494,9 +495,7 @@ func assertPendingChannels(t *testing.T, node *HarnessNode,
494495
// Check the balance of the pending channel.
495496
assetID := mintedAsset.AssetGenesis.AssetId
496497
pendingLocalBalance, pendingRemoteBalance, _, _ :=
497-
getAssetChannelBalance(
498-
t, node, assetID, true,
499-
)
498+
getAssetChannelBalance(t, node, [][]byte{assetID}, true)
500499
require.EqualValues(t, localSum, pendingLocalBalance)
501500
require.EqualValues(t, remoteSum, pendingRemoteBalance)
502501
}
@@ -517,18 +516,20 @@ func haveFundingAsset(assetChannel *rfqmsg.JsonAssetChannel,
517516
}
518517

519518
func assertAssetChan(t *testing.T, src, dst *HarnessNode, fundingAmount uint64,
520-
channelAsset *taprpc.Asset) {
519+
channelAssets []*taprpc.Asset) {
521520

522521
err := wait.NoError(func() error {
523522
a, err := getChannelCustomData(src, dst)
524523
if err != nil {
525524
return err
526525
}
527526

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+
}
532533
}
533534

534535
if a.Capacity != fundingAmount {
@@ -541,9 +542,9 @@ func assertAssetChan(t *testing.T, src, dst *HarnessNode, fundingAmount uint64,
541542
// We only need to check the first funding asset, since we
542543
// enforce them to be the same.
543544
var expectedDecimalDisplay uint8
544-
if channelAsset.DecimalDisplay != nil {
545+
if channelAssets[0].DecimalDisplay != nil {
545546
expectedDecimalDisplay = uint8(
546-
channelAsset.DecimalDisplay.DecimalDisplay,
547+
channelAssets[0].DecimalDisplay.DecimalDisplay,
547548
)
548549
}
549550

@@ -639,7 +640,7 @@ func getChannelCustomData(src, dst *HarnessNode) (*rfqmsg.JsonAssetChannel,
639640
return &assetData, nil
640641
}
641642

642-
func getAssetChannelBalance(t *testing.T, node *HarnessNode, assetID []byte,
643+
func getAssetChannelBalance(t *testing.T, node *HarnessNode, assetIDs [][]byte,
643644
pending bool) (uint64, uint64, uint64, uint64) {
644645

645646
ctxb := context.Background()
@@ -651,18 +652,34 @@ func getAssetChannelBalance(t *testing.T, node *HarnessNode, assetID []byte,
651652
)
652653
require.NoError(t, err)
653654

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+
654661
var assetBalance rfqmsg.JsonAssetChannelBalances
655662
err = json.Unmarshal(balance.CustomChannelData, &assetBalance)
656-
require.NoError(t, err)
663+
require.NoErrorf(t, err, "json: '%x'", balance.CustomChannelData)
657664

658665
balances := assetBalance.OpenChannels
659666
if pending {
660667
balances = assetBalance.PendingChannels
661668
}
662669

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+
663680
var localSum, remoteSum uint64
664681
for assetIDString := range balances {
665-
if assetIDString != hex.EncodeToString(assetID) {
682+
if !idMatch(assetIDString) {
666683
continue
667684
}
668685

@@ -1368,12 +1385,12 @@ func waitForSendEvent(t *testing.T,
13681385
// transaction.
13691386
type coOpCloseBalanceCheck func(t *testing.T, local, remote *HarnessNode,
13701387
closeTx *wire.MsgTx, closeUpdate *lnrpc.ChannelCloseUpdate,
1371-
assetID, groupKey []byte, universeTap *tapClient)
1388+
assetIDs [][]byte, groupKey []byte, universeTap *tapClient)
13721389

13731390
// noOpCoOpCloseBalanceCheck is a no-op implementation of the co-op close
13741391
// balance check that can be used in tests.
13751392
func noOpCoOpCloseBalanceCheck(_ *testing.T, _, _ *HarnessNode, _ *wire.MsgTx,
1376-
_ *lnrpc.ChannelCloseUpdate, _, _ []byte, _ *tapClient) {
1393+
_ *lnrpc.ChannelCloseUpdate, _ [][]byte, _ []byte, _ *tapClient) {
13771394

13781395
// This is a no-op function.
13791396
}
@@ -1382,7 +1399,7 @@ func noOpCoOpCloseBalanceCheck(_ *testing.T, _, _ *HarnessNode, _ *wire.MsgTx,
13821399
// node and asserts the final balances of the closing transaction.
13831400
func closeAssetChannelAndAssert(t *harnessTest, net *NetworkHarness,
13841401
local, remote *HarnessNode, chanPoint *lnrpc.ChannelPoint,
1385-
assetID, groupKey []byte, universeTap *tapClient,
1402+
assetIDs [][]byte, groupKey []byte, universeTap *tapClient,
13861403
balanceCheck coOpCloseBalanceCheck) {
13871404

13881405
t.t.Helper()
@@ -1422,7 +1439,7 @@ func closeAssetChannelAndAssert(t *harnessTest, net *NetworkHarness,
14221439

14231440
// Check the final balance of the closing transaction.
14241441
balanceCheck(
1425-
t.t, local, remote, closeTx, closeUpdate, assetID, groupKey,
1442+
t.t, local, remote, closeTx, closeUpdate, assetIDs, groupKey,
14261443
universeTap,
14271444
)
14281445

@@ -1439,10 +1456,10 @@ func assertDefaultCoOpCloseBalance(remoteBtcBalance,
14391456

14401457
return func(t *testing.T, local, remote *HarnessNode,
14411458
closeTx *wire.MsgTx, closeUpdate *lnrpc.ChannelCloseUpdate,
1442-
assetID, groupKey []byte, universeTap *tapClient) {
1459+
assetIDs [][]byte, groupKey []byte, universeTap *tapClient) {
14431460

14441461
defaultCoOpCloseBalanceCheck(
1445-
t, local, remote, closeTx, closeUpdate, assetID,
1462+
t, local, remote, closeTx, closeUpdate, assetIDs,
14461463
groupKey, universeTap, remoteBtcBalance,
14471464
remoteAssetBalance,
14481465
)
@@ -1455,8 +1472,8 @@ func assertDefaultCoOpCloseBalance(remoteBtcBalance,
14551472
// with the boolean variables.
14561473
func defaultCoOpCloseBalanceCheck(t *testing.T, local, remote *HarnessNode,
14571474
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) {
14601477

14611478
// With the channel closed, we'll now assert that the co-op close
14621479
// transaction was inserted into the local universe.
@@ -1563,11 +1580,15 @@ func defaultCoOpCloseBalanceCheck(t *testing.T, local, remote *HarnessNode,
15631580
)
15641581
require.NoError(t, err)
15651582

1583+
assetIDStrings := fn.Map(hex.EncodeToString, assetIDs)
15661584
for assetIDStr, scriptKeyStr := range localAssetCloseOut.ScriptKeys {
15671585
scriptKeyBytes, err := hex.DecodeString(scriptKeyStr)
15681586
require.NoError(t, err)
15691587

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)
15711592

15721593
a := assertUniverseProofExists(
15731594
t, universeTap, assetID, groupKey, scriptKeyBytes,
@@ -1605,7 +1626,10 @@ func defaultCoOpCloseBalanceCheck(t *testing.T, local, remote *HarnessNode,
16051626
scriptKeyBytes, err := hex.DecodeString(scriptKeyStr)
16061627
require.NoError(t, err)
16071628

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)
16091633

16101634
a := assertUniverseProofExists(
16111635
t, universeTap, assetID, groupKey, scriptKeyBytes,
@@ -1627,8 +1651,8 @@ func defaultCoOpCloseBalanceCheck(t *testing.T, local, remote *HarnessNode,
16271651
// function that can be used when the initiator has a zero asset balance.
16281652
func initiatorZeroAssetBalanceCoOpBalanceCheck(t *testing.T, _,
16291653
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) {
16321656

16331657
// With the channel closed, we'll now assert that the co-op close
16341658
// transaction was inserted into the local universe.
@@ -1674,11 +1698,15 @@ func initiatorZeroAssetBalanceCoOpBalanceCheck(t *testing.T, _,
16741698
)
16751699
require.NoError(t, err)
16761700

1701+
assetIDStrings := fn.Map(hex.EncodeToString, assetIDs)
16771702
for assetIDStr, scriptKeyStr := range remoteAssetCloseOut.ScriptKeys {
16781703
scriptKeyBytes, err := hex.DecodeString(scriptKeyStr)
16791704
require.NoError(t, err)
16801705

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)
16821710

16831711
a := assertUniverseProofExists(
16841712
t, universeTap, assetID, groupKey, scriptKeyBytes,
@@ -1821,12 +1849,15 @@ func assertAssetBalance(t *testing.T, client *tapClient, assetID []byte,
18211849
},
18221850
}
18231851

1852+
var lastBalances *taprpc.ListBalancesResponse
18241853
err := wait.NoError(func() error {
18251854
assetIDBalances, err := client.ListBalances(ctxt, req)
18261855
if err != nil {
18271856
return err
18281857
}
18291858

1859+
lastBalances = assetIDBalances
1860+
18301861
assetIDFound := false
18311862
for _, balance := range assetIDBalances.AssetBalances {
18321863
if !bytes.Equal(balance.AssetGenesis.AssetId, assetID) {
@@ -1847,11 +1878,16 @@ func assertAssetBalance(t *testing.T, client *tapClient, assetID []byte,
18471878
return nil
18481879
}, shortTimeout)
18491880
if err != nil {
1850-
r, err2 := client.ListAssets(ctxb, &taprpc.ListAssetRequest{})
1881+
listAssetsResp, err2 := client.ListAssets(
1882+
ctxb, &taprpc.ListAssetRequest{},
1883+
)
18511884
require.NoError(t, err2)
18521885

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))
18551891

18561892
utxos, err3 := client.ListUtxos(
18571893
ctxb, &taprpc.ListUtxosRequest{},
@@ -2031,8 +2067,9 @@ func logBalance(t *testing.T, nodes []*HarnessNode, assetID []byte,
20312067
time.Sleep(time.Millisecond * 250)
20322068

20332069
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+
)
20362073

20372074
t.Logf("%-7s balance: local=%-9d remote=%-9d, localSat=%-9d, "+
20382075
"remoteSat=%-9d (%v)", node.Cfg.Name, local, remote,
@@ -2265,9 +2302,9 @@ func assertPendingChannelAssetData(t *testing.T, node *HarnessNode,
22652302
"data: %v", err)
22662303
}
22672304

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))
22712308
}
22722309

22732310
return nil
@@ -2363,3 +2400,47 @@ func assertClosedChannelAssetData(t *testing.T, node *HarnessNode,
23632400

23642401
require.GreaterOrEqual(t, len(closeData.FundingAssets), 1)
23652402
}
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

Comments
 (0)