Skip to content

Commit cd914b3

Browse files
authored
Merge pull request #1799 from lightninglabs/wip/fix-itest-flakes
itest: introduce `rpcassert` package with RPC helpers to reduce flakes
2 parents 189e165 + bc3e474 commit cd914b3

File tree

3 files changed

+336
-140
lines changed

3 files changed

+336
-140
lines changed

itest/assertions.go

Lines changed: 171 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/lightninglabs/taproot-assets/cmd/commands"
2424
"github.com/lightninglabs/taproot-assets/commitment"
2525
"github.com/lightninglabs/taproot-assets/fn"
26+
"github.com/lightninglabs/taproot-assets/itest/rpcassert"
2627
"github.com/lightninglabs/taproot-assets/proof"
2728
"github.com/lightninglabs/taproot-assets/rpcutils"
2829
"github.com/lightninglabs/taproot-assets/tapfreighter"
@@ -2395,17 +2396,7 @@ func AssertBalances(t *testing.T, client taprpc.TaprootAssetsClient,
23952396

23962397
// First, we'll ensure that we're able to get the balances of all the
23972398
// assets grouped by their asset IDs.
2398-
assetIDBalances, err := client.ListBalances(
2399-
ctxt, &taprpc.ListBalancesRequest{
2400-
GroupBy: groupBalancesByAssetID,
2401-
IncludeLeased: config.includeLeased,
2402-
ScriptKeyType: rpcTypeQuery,
2403-
AssetFilter: config.assetID,
2404-
GroupKeyFilter: config.groupKey,
2405-
},
2406-
)
2407-
require.NoError(t, err)
2408-
2399+
//
24092400
// Spent assets (burns/tombstones) are never included in the balance,
24102401
// even if we specifically query for their type. So we skip the balance
24112402
// check in that case. We also skip if we're looking for a specific
@@ -2415,154 +2406,110 @@ func AssertBalances(t *testing.T, client taprpc.TaprootAssetsClient,
24152406
*config.scriptKeyType != asset.ScriptKeyTombstone)) &&
24162407
len(config.scriptKey) == 0
24172408
if checkBalance {
2418-
require.Equal(
2419-
t, balance, balanceSum(assetIDBalances, false),
2420-
"asset balance, wanted %d, got: %v", balance,
2421-
toJSON(t, assetIDBalances),
2422-
)
2409+
assertPred := func(resp *taprpc.ListBalancesResponse) error {
2410+
actualBalance := balanceSum(resp, false)
2411+
if balance != actualBalance {
2412+
return fmt.Errorf("asset balance, wanted %d, "+
2413+
"got: %v", balance, toJSON(t, resp))
2414+
}
24232415

2424-
// If we query for grouped asset balances too, it means we do
2425-
// have at least some assets with a group key. So the output of
2426-
// the ListBalances call should contain at least one asset
2427-
// balance with a group key set.
2428-
if config.groupedAssetBalance > 0 {
2429-
numGrouped := 0
2430-
for _, bal := range assetIDBalances.AssetBalances {
2431-
if len(bal.GroupKey) > 0 {
2432-
numGrouped++
2416+
// If we query for grouped asset balances too, it means
2417+
// we do have at least some assets with a group key. So
2418+
// the output of the ListBalances call should contain at
2419+
// least one asset balance with a group key set.
2420+
if config.groupedAssetBalance > 0 {
2421+
numGrouped := 0
2422+
for _, bal := range resp.AssetBalances {
2423+
if len(bal.GroupKey) > 0 {
2424+
numGrouped++
2425+
}
2426+
}
2427+
if numGrouped == 0 {
2428+
return fmt.Errorf("expected at least " +
2429+
"one asset in ListBalances " +
2430+
"response to have a group " +
2431+
"key set")
24332432
}
24342433
}
2435-
require.Greater(
2436-
t, numGrouped, 0, "expected at least one "+
2437-
"asset in ListBalances response to "+
2438-
"have a group key set",
2439-
)
2434+
2435+
return nil
24402436
}
2441-
}
24422437

2443-
// Next, we do the same but grouped by group keys (if requested, since
2444-
// this only returns the balances for actually grouped assets).
2445-
if config.groupedAssetBalance > 0 {
2446-
assetGroupBalances, err := client.ListBalances(
2447-
ctxt, &taprpc.ListBalancesRequest{
2448-
GroupBy: groupBalancesByGroupKey,
2438+
rpcassert.ListBalancesRPC(
2439+
t, ctxt, client, assertPred,
2440+
&taprpc.ListBalancesRequest{
2441+
GroupBy: groupBalancesByAssetID,
24492442
IncludeLeased: config.includeLeased,
24502443
ScriptKeyType: rpcTypeQuery,
24512444
AssetFilter: config.assetID,
24522445
GroupKeyFilter: config.groupKey,
24532446
},
24542447
)
2455-
require.NoError(t, err)
2456-
2457-
// Spent assets (burns/tombstones) are never included in the
2458-
// balance, even if we specifically query for their type. So we
2459-
// skip the balance check in that case.
2460-
if checkBalance {
2461-
require.Equalf(
2462-
t, config.groupedAssetBalance,
2463-
balanceSum(assetGroupBalances, true),
2464-
"grouped balance, wanted %d, got: %v", balance,
2465-
toJSON(t, assetGroupBalances),
2466-
)
2467-
2468-
// Because we query for grouped assets, the group key
2469-
// field should be set for all asset balances.
2470-
for _, bal := range assetGroupBalances.AssetBalances {
2471-
require.Equal(t, config.groupKey, bal.GroupKey)
2472-
}
2473-
}
24742448
}
24752449

2476-
// Finally, we assert that the sum of all assets queried with the given
2477-
// query parameters matches the expected balance.
2478-
assetList, err := client.ListAssets(ctxt, &taprpc.ListAssetRequest{
2479-
IncludeLeased: config.includeLeased,
2480-
ScriptKeyType: rpcTypeQuery,
2481-
})
2482-
require.NoError(t, err)
2483-
2484-
var (
2485-
totalBalance uint64
2486-
numUtxos uint32
2487-
)
2488-
for _, a := range assetList.Assets {
2489-
if len(config.assetID) > 0 {
2490-
if !bytes.Equal(
2491-
a.AssetGenesis.AssetId, config.assetID,
2492-
) {
2493-
2494-
continue
2495-
}
2496-
}
2497-
2498-
if len(config.groupKey) > 0 {
2499-
if a.AssetGroup == nil {
2500-
continue
2450+
// Next, we do the same but grouped by group keys (if requested, since
2451+
// this only returns the balances for actually grouped assets).
2452+
if config.groupedAssetBalance > 0 && checkBalance {
2453+
assertPred := func(resp *taprpc.ListBalancesResponse) error {
2454+
actualBalance := balanceSum(resp, true)
2455+
if config.groupedAssetBalance != actualBalance {
2456+
return fmt.Errorf("grouped asset balance, "+
2457+
"wanted %d, got: %v", balance,
2458+
toJSON(t, resp))
25012459
}
25022460

2503-
if !bytes.Equal(
2504-
a.AssetGroup.TweakedGroupKey, config.groupKey,
2505-
) {
2461+
// Because we query for grouped assets, the group key
2462+
// field should be set for all asset balances.
2463+
for _, bal := range resp.AssetBalances {
2464+
if !bytes.Equal(config.groupKey, bal.GroupKey) {
2465+
return fmt.Errorf("expected group "+
2466+
"key %x, got: %x",
2467+
config.groupKey, bal)
2468+
}
25062469

2507-
continue
2470+
require.Equal(t, config.groupKey, bal.GroupKey)
25082471
}
2509-
}
25102472

2511-
if len(config.scriptKey) > 0 {
2512-
if !bytes.Equal(a.ScriptKey, config.scriptKey) {
2513-
continue
2514-
}
2473+
return nil
25152474
}
25162475

2517-
totalBalance += a.Amount
2518-
numUtxos++
2519-
}
2520-
require.Equalf(
2521-
t, balance, totalBalance, "ListAssets balance, wanted %d, "+
2522-
"got: %v", balance, toJSON(t, assetList),
2523-
)
2524-
2525-
// The number of UTXOs means asset outputs in this case. We check the
2526-
// BTC-level UTXOs below as well, but that's just to make sure the
2527-
// output of that RPC lists the same assets.
2528-
if config.numAssetUtxos > 0 {
2529-
require.Equal(
2530-
t, config.numAssetUtxos, numUtxos, "ListAssets num "+
2531-
"asset utxos",
2476+
rpcassert.ListBalancesRPC(
2477+
t, ctxt, client, assertPred,
2478+
&taprpc.ListBalancesRequest{
2479+
GroupBy: groupBalancesByGroupKey,
2480+
IncludeLeased: config.includeLeased,
2481+
ScriptKeyType: rpcTypeQuery,
2482+
AssetFilter: config.assetID,
2483+
GroupKeyFilter: config.groupKey,
2484+
},
25322485
)
25332486
}
25342487

2535-
utxoList, err := client.ListUtxos(ctxt, &taprpc.ListUtxosRequest{
2536-
IncludeLeased: config.includeLeased,
2537-
ScriptKeyType: rpcTypeQuery,
2538-
})
2539-
require.NoError(t, err)
2488+
// Finally, we assert that the sum of all assets queried with the given
2489+
// query parameters matches the expected balance.
2490+
assertPred := func(resp *taprpc.ListAssetResponse) error {
2491+
var (
2492+
totalBalance uint64
2493+
numUtxos uint32
2494+
)
25402495

2541-
// Make sure the ListUtxos call returns the same number of (asset) UTXOs
2542-
// as the ListAssets call.
2543-
var numAnchorUtxos uint32
2544-
totalBalance = 0
2545-
numUtxos = 0
2546-
for _, btcUtxo := range utxoList.ManagedUtxos {
2547-
numAnchorUtxos++
2548-
for _, assetUtxo := range btcUtxo.Assets {
2496+
for _, a := range resp.Assets {
25492497
if len(config.assetID) > 0 {
25502498
if !bytes.Equal(
2551-
assetUtxo.AssetGenesis.AssetId,
2552-
config.assetID,
2499+
a.AssetGenesis.AssetId, config.assetID,
25532500
) {
25542501

25552502
continue
25562503
}
25572504
}
25582505

25592506
if len(config.groupKey) > 0 {
2560-
if assetUtxo.AssetGroup == nil {
2507+
if a.AssetGroup == nil {
25612508
continue
25622509
}
25632510

25642511
if !bytes.Equal(
2565-
assetUtxo.AssetGroup.TweakedGroupKey,
2512+
a.AssetGroup.TweakedGroupKey,
25662513
config.groupKey,
25672514
) {
25682515

@@ -2571,32 +2518,118 @@ func AssertBalances(t *testing.T, client taprpc.TaprootAssetsClient,
25712518
}
25722519

25732520
if len(config.scriptKey) > 0 {
2574-
if !bytes.Equal(
2575-
assetUtxo.ScriptKey, config.scriptKey,
2576-
) {
2577-
2521+
if !bytes.Equal(a.ScriptKey, config.scriptKey) {
25782522
continue
25792523
}
25802524
}
25812525

2582-
totalBalance += assetUtxo.Amount
2526+
totalBalance += a.Amount
25832527
numUtxos++
25842528
}
2585-
}
2586-
require.Equal(t, balance, totalBalance, "ListUtxos balance")
2529+
if balance != totalBalance {
2530+
return fmt.Errorf("ListAssets balance, wanted %d, "+
2531+
"got: %v", balance, toJSON(t, resp))
2532+
}
25872533

2588-
if config.numAnchorUtxos > 0 {
2589-
require.Equal(
2590-
t, config.numAnchorUtxos, numAnchorUtxos, "num anchor "+
2591-
"utxos",
2592-
)
2534+
// The number of UTXOs means asset outputs in this case. We
2535+
// check the BTC-level UTXOs below as well, but that's just to
2536+
// make sure the output of that RPC lists the same assets.
2537+
if config.numAssetUtxos > 0 {
2538+
if config.numAssetUtxos != numUtxos {
2539+
return fmt.Errorf("unexpected number of UTXOs")
2540+
}
2541+
}
2542+
2543+
return nil
25932544
}
2594-
if config.numAssetUtxos > 0 {
2595-
require.Equal(
2596-
t, config.numAssetUtxos, numUtxos, "ListUtxos num "+
2597-
"asset utxos",
2545+
2546+
rpcassert.ListAssetsRPC(t, ctxt, client, assertPred,
2547+
&taprpc.ListAssetRequest{
2548+
IncludeLeased: config.includeLeased,
2549+
ScriptKeyType: rpcTypeQuery,
2550+
},
2551+
)
2552+
2553+
// Make sure the ListUtxos call returns the same number of (asset) UTXOs
2554+
// as the ListAssets call.
2555+
assertPredUtxos := func(resp *taprpc.ListUtxosResponse) error {
2556+
var (
2557+
numAnchorUtxos uint32
2558+
totalBalance uint64
2559+
numUtxos uint32
25982560
)
2561+
2562+
for _, btcUtxo := range resp.ManagedUtxos {
2563+
numAnchorUtxos++
2564+
for _, assetUtxo := range btcUtxo.Assets {
2565+
if len(config.assetID) > 0 {
2566+
if !bytes.Equal(
2567+
assetUtxo.AssetGenesis.AssetId,
2568+
config.assetID,
2569+
) {
2570+
2571+
continue
2572+
}
2573+
}
2574+
2575+
if len(config.groupKey) > 0 {
2576+
if assetUtxo.AssetGroup == nil {
2577+
continue
2578+
}
2579+
2580+
// nolint: lll
2581+
actualGK := assetUtxo.AssetGroup.TweakedGroupKey
2582+
2583+
if !bytes.Equal(
2584+
actualGK, config.groupKey,
2585+
) {
2586+
2587+
continue
2588+
}
2589+
}
2590+
2591+
if len(config.scriptKey) > 0 {
2592+
if !bytes.Equal(
2593+
assetUtxo.ScriptKey,
2594+
config.scriptKey,
2595+
) {
2596+
2597+
continue
2598+
}
2599+
}
2600+
2601+
totalBalance += assetUtxo.Amount
2602+
numUtxos++
2603+
}
2604+
}
2605+
2606+
if balance != totalBalance {
2607+
return fmt.Errorf("ListUtxos balance, wanted %d, "+
2608+
"got: %v", balance, toJSON(t, resp))
2609+
}
2610+
2611+
if config.numAnchorUtxos > 0 {
2612+
if config.numAnchorUtxos != numAnchorUtxos {
2613+
return fmt.Errorf("unexpected number of " +
2614+
"anchor UTXOs")
2615+
}
2616+
}
2617+
if config.numAssetUtxos > 0 {
2618+
if config.numAssetUtxos != numUtxos {
2619+
return fmt.Errorf("unexpected number of " +
2620+
"asset UTXOs")
2621+
}
2622+
}
2623+
2624+
return nil
25992625
}
2626+
2627+
rpcassert.ListUtxosRPC(t, ctxt, client, assertPredUtxos,
2628+
&taprpc.ListUtxosRequest{
2629+
IncludeLeased: config.includeLeased,
2630+
ScriptKeyType: rpcTypeQuery,
2631+
},
2632+
)
26002633
}
26012634

26022635
func assertGroups(t *testing.T, client taprpc.TaprootAssetsClient,

0 commit comments

Comments
 (0)