52
52
AllTypes : true ,
53
53
},
54
54
}
55
+
56
+ groupBalancesByAssetID = & taprpc.ListBalancesRequest_AssetId {
57
+ AssetId : true ,
58
+ }
59
+
60
+ groupBalancesByGroupKey = & taprpc.ListBalancesRequest_GroupKey {
61
+ GroupKey : true ,
62
+ }
55
63
)
56
64
57
65
// tapClient is an interface that covers all currently available RPC interfaces
@@ -2010,7 +2018,7 @@ func AssertGenesisOutput(t *testing.T, output *taprpc.ManagedUtxo,
2010
2018
require .Equal (t , expectedMerkleRoot [:], output .MerkleRoot )
2011
2019
}
2012
2020
2013
- func AssertAssetBalances (t * testing.T , client taprpc.TaprootAssetsClient ,
2021
+ func AssertMintedAssetBalances (t * testing.T , client taprpc.TaprootAssetsClient ,
2014
2022
simpleAssets , issuableAssets []* taprpc.Asset , includeLeased bool ) {
2015
2023
2016
2024
t .Helper ()
@@ -2021,12 +2029,9 @@ func AssertAssetBalances(t *testing.T, client taprpc.TaprootAssetsClient,
2021
2029
2022
2030
// First, we'll ensure that we're able to get the balances of all the
2023
2031
// assets grouped by their asset IDs.
2024
- balanceReq := & taprpc.ListBalancesRequest_AssetId {
2025
- AssetId : true ,
2026
- }
2027
2032
assetIDBalances , err := client .ListBalances (
2028
2033
ctxt , & taprpc.ListBalancesRequest {
2029
- GroupBy : balanceReq ,
2034
+ GroupBy : groupBalancesByAssetID ,
2030
2035
IncludeLeased : includeLeased ,
2031
2036
},
2032
2037
)
@@ -2067,20 +2072,17 @@ func AssertAssetBalances(t *testing.T, client taprpc.TaprootAssetsClient,
2067
2072
require .NoError (t , err )
2068
2073
2069
2074
var totalAssetListBalance uint64
2070
- for _ , asset := range assetList .Assets {
2071
- totalAssetListBalance += asset .Amount
2075
+ for _ , a := range assetList .Assets {
2076
+ totalAssetListBalance += a .Amount
2072
2077
}
2073
2078
2074
2079
require .Equal (t , totalBalance , totalAssetListBalance )
2075
2080
2076
2081
// We'll also ensure that we're able to get the balance by key group
2077
2082
// for all the assets that have one specified.
2078
- groupBalanceReq := & taprpc.ListBalancesRequest_GroupKey {
2079
- GroupKey : true ,
2080
- }
2081
2083
assetGroupBalances , err := client .ListBalances (
2082
2084
ctxt , & taprpc.ListBalancesRequest {
2083
- GroupBy : groupBalanceReq ,
2085
+ GroupBy : groupBalancesByGroupKey ,
2084
2086
},
2085
2087
)
2086
2088
require .NoError (t , err )
@@ -2089,19 +2091,274 @@ func AssertAssetBalances(t *testing.T, client taprpc.TaprootAssetsClient,
2089
2091
t , len (issuableAssets ),
2090
2092
len (assetGroupBalances .AssetGroupBalances ),
2091
2093
)
2094
+ }
2092
2095
2093
- for _ , balance := range assetGroupBalances .AssetBalances {
2094
- for _ , rpcAsset := range issuableAssets {
2095
- if balance .AssetGenesis .Name == rpcAsset .AssetGenesis .Name {
2096
- require .Equal (
2097
- t , balance .Balance , rpcAsset .Amount ,
2098
- )
2099
- require .Equal (
2100
- t , balance .AssetGenesis ,
2101
- rpcAsset .AssetGenesis ,
2102
- )
2096
+ type balanceConfig struct {
2097
+ assetID []byte
2098
+ groupKey []byte
2099
+ groupedAssetBalance uint64
2100
+ numAssetUtxos uint32
2101
+ numAnchorUtxos uint32
2102
+ includeLeased bool
2103
+ allScriptKeyTypes bool
2104
+ scriptKeyType * asset.ScriptKeyType
2105
+ }
2106
+
2107
+ type BalanceOption func (* balanceConfig )
2108
+
2109
+ func WithAssetID (assetID []byte ) BalanceOption {
2110
+ return func (c * balanceConfig ) {
2111
+ c .assetID = assetID
2112
+ }
2113
+ }
2114
+
2115
+ func WithGroupKey (groupKey []byte ) BalanceOption {
2116
+ return func (c * balanceConfig ) {
2117
+ c .groupKey = groupKey
2118
+ }
2119
+ }
2120
+
2121
+ func WithGroupedAssetBalance (groupedAssetBalance uint64 ) BalanceOption {
2122
+ return func (c * balanceConfig ) {
2123
+ c .groupedAssetBalance = groupedAssetBalance
2124
+ }
2125
+ }
2126
+
2127
+ func WithNumUtxos (numAssetUtxos uint32 ) BalanceOption {
2128
+ return func (c * balanceConfig ) {
2129
+ c .numAssetUtxos = numAssetUtxos
2130
+ }
2131
+ }
2132
+
2133
+ func WithNumAnchorUtxos (numAnchorUtxos uint32 ) BalanceOption {
2134
+ return func (c * balanceConfig ) {
2135
+ c .numAnchorUtxos = numAnchorUtxos
2136
+ }
2137
+ }
2138
+
2139
+ func WithIncludeLeased () BalanceOption {
2140
+ return func (c * balanceConfig ) {
2141
+ c .includeLeased = true
2142
+ }
2143
+ }
2144
+
2145
+ func WithAllScriptKeyTypes () BalanceOption {
2146
+ return func (c * balanceConfig ) {
2147
+ c .allScriptKeyTypes = true
2148
+ }
2149
+ }
2150
+
2151
+ func WithScriptKeyType (scriptKeyType asset.ScriptKeyType ) BalanceOption {
2152
+ return func (c * balanceConfig ) {
2153
+ c .scriptKeyType = & scriptKeyType
2154
+ }
2155
+ }
2156
+
2157
+ func AssertBalances (t * testing.T , client taprpc.TaprootAssetsClient ,
2158
+ balance uint64 , opts ... BalanceOption ) {
2159
+
2160
+ t .Helper ()
2161
+
2162
+ config := & balanceConfig {}
2163
+ for _ , opt := range opts {
2164
+ opt (config )
2165
+ }
2166
+
2167
+ var rpcTypeQuery * taprpc.ScriptKeyTypeQuery
2168
+ switch {
2169
+ case config .allScriptKeyTypes :
2170
+ rpcTypeQuery = & taprpc.ScriptKeyTypeQuery {
2171
+ Type : & taprpc.ScriptKeyTypeQuery_AllTypes {
2172
+ AllTypes : true ,
2173
+ },
2174
+ }
2175
+
2176
+ case config .scriptKeyType != nil :
2177
+ rpcTypeQuery = & taprpc.ScriptKeyTypeQuery {
2178
+ Type : & taprpc.ScriptKeyTypeQuery_ExplicitType {
2179
+ ExplicitType : taprpc .MarshalScriptKeyType (
2180
+ * config .scriptKeyType ,
2181
+ ),
2182
+ },
2183
+ }
2184
+ }
2185
+
2186
+ balanceSum := func (resp * taprpc.ListBalancesResponse ,
2187
+ group bool ) uint64 {
2188
+
2189
+ var totalBalance uint64
2190
+
2191
+ if group {
2192
+ for _ , currentBalance := range resp .AssetGroupBalances {
2193
+ totalBalance += currentBalance .Balance
2194
+ }
2195
+ } else {
2196
+ for _ , currentBalance := range resp .AssetBalances {
2197
+ totalBalance += currentBalance .Balance
2198
+ }
2199
+ }
2200
+
2201
+ return totalBalance
2202
+ }
2203
+
2204
+ ctxb := context .Background ()
2205
+ ctxt , cancel := context .WithTimeout (ctxb , defaultWaitTimeout )
2206
+ defer cancel ()
2207
+
2208
+ // First, we'll ensure that we're able to get the balances of all the
2209
+ // assets grouped by their asset IDs.
2210
+ assetIDBalances , err := client .ListBalances (
2211
+ ctxt , & taprpc.ListBalancesRequest {
2212
+ GroupBy : groupBalancesByAssetID ,
2213
+ IncludeLeased : config .includeLeased ,
2214
+ ScriptKeyType : rpcTypeQuery ,
2215
+ AssetFilter : config .assetID ,
2216
+ GroupKeyFilter : config .groupKey ,
2217
+ },
2218
+ )
2219
+ require .NoError (t , err )
2220
+
2221
+ // Spent assets (burns/tombstones) are never included in the balance,
2222
+ // even if we specifically query for their type. So we skip the balance
2223
+ // check in that case.
2224
+ checkBalance := config .scriptKeyType == nil ||
2225
+ (* config .scriptKeyType != asset .ScriptKeyBurn &&
2226
+ * config .scriptKeyType != asset .ScriptKeyTombstone )
2227
+ if checkBalance {
2228
+ require .Equal (
2229
+ t , balance , balanceSum (assetIDBalances , false ),
2230
+ "asset balance, wanted %d, got: %v" , balance ,
2231
+ toJSON (t , assetIDBalances ),
2232
+ )
2233
+ }
2234
+
2235
+ // Next, we do the same but grouped by group keys (if requested, since
2236
+ // this only returns the balances for actually grouped assets).
2237
+ if config .groupedAssetBalance > 0 {
2238
+ assetGroupBalances , err := client .ListBalances (
2239
+ ctxt , & taprpc.ListBalancesRequest {
2240
+ GroupBy : groupBalancesByGroupKey ,
2241
+ IncludeLeased : config .includeLeased ,
2242
+ ScriptKeyType : rpcTypeQuery ,
2243
+ AssetFilter : config .assetID ,
2244
+ GroupKeyFilter : config .groupKey ,
2245
+ },
2246
+ )
2247
+ require .NoError (t , err )
2248
+
2249
+ // Spent assets (burns/tombstones) are never included in the
2250
+ // balance, even if we specifically query for their type. So we
2251
+ // skip the balance check in that case.
2252
+ if checkBalance {
2253
+ require .Equalf (
2254
+ t , config .groupedAssetBalance ,
2255
+ balanceSum (assetGroupBalances , true ),
2256
+ "grouped balance, wanted %d, got: %v" , balance ,
2257
+ toJSON (t , assetGroupBalances ),
2258
+ )
2259
+ }
2260
+ }
2261
+
2262
+ // Finally, we assert that the sum of all assets queried with the given
2263
+ // query parameters matches the expected balance.
2264
+ assetList , err := client .ListAssets (ctxt , & taprpc.ListAssetRequest {
2265
+ IncludeLeased : config .includeLeased ,
2266
+ ScriptKeyType : rpcTypeQuery ,
2267
+ })
2268
+ require .NoError (t , err )
2269
+
2270
+ var (
2271
+ totalBalance uint64
2272
+ numUtxos uint32
2273
+ )
2274
+ for _ , a := range assetList .Assets {
2275
+ if len (config .assetID ) > 0 {
2276
+ if ! bytes .Equal (
2277
+ a .AssetGenesis .AssetId , config .assetID ,
2278
+ ) {
2279
+
2280
+ continue
2281
+ }
2282
+ }
2283
+
2284
+ if len (config .groupKey ) > 0 {
2285
+ if ! bytes .Equal (
2286
+ a .AssetGroup .TweakedGroupKey , config .groupKey ,
2287
+ ) {
2288
+
2289
+ continue
2103
2290
}
2104
2291
}
2292
+
2293
+ totalBalance += a .Amount
2294
+ numUtxos ++
2295
+ }
2296
+ require .Equalf (
2297
+ t , balance , totalBalance , "ListAssets balance, wanted %d, " +
2298
+ "got: %v" , balance , toJSON (t , assetList ),
2299
+ )
2300
+
2301
+ // The number of UTXOs means asset outputs in this case. We check the
2302
+ // BTC-level UTXOs below as well, but that's just to make sure the
2303
+ // output of that RPC lists the same assets.
2304
+ if config .numAssetUtxos > 0 {
2305
+ require .Equal (
2306
+ t , config .numAssetUtxos , numUtxos , "ListAssets num " +
2307
+ "asset utxos" ,
2308
+ )
2309
+ }
2310
+
2311
+ utxoList , err := client .ListUtxos (ctxt , & taprpc.ListUtxosRequest {
2312
+ IncludeLeased : config .includeLeased ,
2313
+ ScriptKeyType : rpcTypeQuery ,
2314
+ })
2315
+ require .NoError (t , err )
2316
+
2317
+ // Make sure the ListUtxos call returns the same number of (asset) UTXOs
2318
+ // as the ListAssets call.
2319
+ var numAnchorUtxos uint32
2320
+ totalBalance = 0
2321
+ numUtxos = 0
2322
+ for _ , btcUtxo := range utxoList .ManagedUtxos {
2323
+ numAnchorUtxos ++
2324
+ for _ , assetUtxo := range btcUtxo .Assets {
2325
+ if len (config .assetID ) > 0 {
2326
+ if ! bytes .Equal (
2327
+ assetUtxo .AssetGenesis .AssetId ,
2328
+ config .assetID ,
2329
+ ) {
2330
+
2331
+ continue
2332
+ }
2333
+ }
2334
+
2335
+ if len (config .groupKey ) > 0 {
2336
+ if ! bytes .Equal (
2337
+ btcUtxo .TaprootAssetRoot ,
2338
+ config .groupKey ,
2339
+ ) {
2340
+
2341
+ continue
2342
+ }
2343
+ }
2344
+
2345
+ totalBalance += assetUtxo .Amount
2346
+ numUtxos ++
2347
+ }
2348
+ }
2349
+ require .Equal (t , balance , totalBalance , "ListUtxos balance" )
2350
+
2351
+ if config .numAnchorUtxos > 0 {
2352
+ require .Equal (
2353
+ t , config .numAnchorUtxos , numAnchorUtxos , "num anchor " +
2354
+ "utxos" ,
2355
+ )
2356
+ }
2357
+ if config .numAssetUtxos > 0 {
2358
+ require .Equal (
2359
+ t , config .numAssetUtxos , numUtxos , "ListUtxos num " +
2360
+ "asset utxos" ,
2361
+ )
2105
2362
}
2106
2363
}
2107
2364
0 commit comments