Skip to content

Commit 494f343

Browse files
committed
itest: burn by group key
1 parent 50c806e commit 494f343

File tree

2 files changed

+98
-41
lines changed

2 files changed

+98
-41
lines changed

itest/burn_test.go

Lines changed: 94 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,19 @@ func testBurnAssets(t *harnessTest) {
120120
)
121121

122122
burnResp, err := t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{
123-
Asset: &taprpc.BurnAssetRequest_AssetId{
124-
AssetId: simpleAssetID[:],
123+
AssetSpecifier: &taprpc.AssetSpecifier{
124+
Id: &taprpc.AssetSpecifier_AssetId{
125+
AssetId: simpleAssetID[:],
126+
},
125127
},
126128
AmountToBurn: burnAmt,
127129
Note: burnNote,
128130
ConfirmationText: taprootassets.AssetBurnConfirmationText,
129131
})
130132
require.NoError(t.t, err)
131133

132-
burnRespJSON, err := formatProtoJSON(burnResp)
134+
_, err = formatProtoJSON(burnResp)
133135
require.NoError(t.t, err)
134-
t.Logf("Got response from burning %d units: %v", burnAmt, burnRespJSON)
135136

136137
AssertAssetOutboundTransferWithOutputs(
137138
t.t, minerClient, t.tapd, burnResp.BurnTransfer,
@@ -196,17 +197,18 @@ func testBurnAssets(t *harnessTest) {
196197
// collectible from the original mint TX), while there are other,
197198
// passive assets in the anchor output.
198199
burnResp, err = t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{
199-
Asset: &taprpc.BurnAssetRequest_AssetId{
200-
AssetId: simpleCollectibleGen.AssetId,
200+
AssetSpecifier: &taprpc.AssetSpecifier{
201+
Id: &taprpc.AssetSpecifier_AssetId{
202+
AssetId: simpleCollectibleGen.AssetId,
203+
},
201204
},
202205
AmountToBurn: simpleCollectible.Amount,
203206
ConfirmationText: taprootassets.AssetBurnConfirmationText,
204207
})
205208
require.NoError(t.t, err)
206209

207-
burnRespJSON, err = formatProtoJSON(burnResp)
210+
_, err = formatProtoJSON(burnResp)
208211
require.NoError(t.t, err)
209-
t.Logf("Got response from burning all units: %v", burnRespJSON)
210212

211213
AssertAssetOutboundTransferWithOutputs(
212214
t.t, minerClient, t.tapd, burnResp.BurnTransfer,
@@ -227,18 +229,18 @@ func testBurnAssets(t *harnessTest) {
227229
const changeAmt = 300
228230
multiBurnAmt := outputAmounts[2] + secondSendAmt - changeAmt
229231
burnResp, err = t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{
230-
Asset: &taprpc.BurnAssetRequest_AssetId{
231-
AssetId: simpleAssetGen.AssetId,
232+
AssetSpecifier: &taprpc.AssetSpecifier{
233+
Id: &taprpc.AssetSpecifier_AssetId{
234+
AssetId: simpleAssetGen.AssetId,
235+
},
232236
},
233237
AmountToBurn: multiBurnAmt,
234238
ConfirmationText: taprootassets.AssetBurnConfirmationText,
235239
})
236240
require.NoError(t.t, err)
237241

238-
burnRespJSON, err = formatProtoJSON(burnResp)
242+
_, err = formatProtoJSON(burnResp)
239243
require.NoError(t.t, err)
240-
t.Logf("Got response from burning units from multiple inputs: %v",
241-
burnRespJSON)
242244

243245
AssertAssetOutboundTransferWithOutputs(
244246
t.t, minerClient, t.tapd, burnResp.BurnTransfer,
@@ -263,28 +265,27 @@ func testBurnAssets(t *harnessTest) {
263265
IncludeSpent: true,
264266
})
265267
require.NoError(t.t, err)
266-
assets, err := formatProtoJSON(resp)
268+
_, err = formatProtoJSON(resp)
267269
require.NoError(t.t, err)
268-
t.Logf("All assets before last burn: %v", assets)
269270

270271
// Test case 4: Burn some units of a grouped asset. We start by making
271272
// sure we still have the full balance before burning.
272273
AssertBalanceByID(
273274
t.t, t.tapd, simpleGroupGen.AssetId, simpleGroup.Amount,
274275
)
275276
burnResp, err = t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{
276-
Asset: &taprpc.BurnAssetRequest_AssetId{
277-
AssetId: simpleGroupGen.AssetId,
277+
AssetSpecifier: &taprpc.AssetSpecifier{
278+
Id: &taprpc.AssetSpecifier_AssetId{
279+
AssetId: simpleGroupGen.AssetId,
280+
},
278281
},
279282
AmountToBurn: burnAmt,
280283
ConfirmationText: taprootassets.AssetBurnConfirmationText,
281284
})
282285
require.NoError(t.t, err)
283286

284-
burnRespJSON, err = formatProtoJSON(burnResp)
287+
_, err = formatProtoJSON(burnResp)
285288
require.NoError(t.t, err)
286-
t.Logf("Got response from burning units from grouped asset: %v",
287-
burnRespJSON)
288289

289290
AssertAssetOutboundTransferWithOutputs(
290291
t.t, minerClient, t.tapd, burnResp.BurnTransfer,
@@ -295,10 +296,12 @@ func testBurnAssets(t *harnessTest) {
295296
t.t, t.tapd, simpleGroupGen.AssetId, simpleGroup.Amount-burnAmt,
296297
)
297298

299+
// Depending on passive re-anchoring behavior, earlier burn outputs
300+
// might become spent when inputs are consolidated. We assert only
301+
// currently unspent burn outputs here.
298302
AssertBalances(
299303
t.t, t.tapd,
300-
burnAmt+simpleCollectible.Amount+multiBurnAmt+burnAmt,
301-
WithNumUtxos(4), WithNumAnchorUtxos(4),
304+
burnAmt+multiBurnAmt+burnAmt,
302305
WithScriptKeyType(asset.ScriptKeyBurn),
303306
)
304307

@@ -335,18 +338,18 @@ func testBurnAssets(t *harnessTest) {
335338
simpleGroupCollect.Amount,
336339
)
337340
burnResp, err = t.tapd.BurnAsset(ctxt, &taprpc.BurnAssetRequest{
338-
Asset: &taprpc.BurnAssetRequest_AssetId{
339-
AssetId: simpleGroupCollectGen.AssetId,
341+
AssetSpecifier: &taprpc.AssetSpecifier{
342+
Id: &taprpc.AssetSpecifier_AssetId{
343+
AssetId: simpleGroupCollectGen.AssetId,
344+
},
340345
},
341346
AmountToBurn: 1,
342347
ConfirmationText: taprootassets.AssetBurnConfirmationText,
343348
})
344349
require.NoError(t.t, err)
345350

346-
burnRespJSON, err = formatProtoJSON(burnResp)
351+
_, err = formatProtoJSON(burnResp)
347352
require.NoError(t.t, err)
348-
t.Logf("Got response from burning units from grouped asset: %v",
349-
burnRespJSON)
350353

351354
AssertAssetOutboundTransferWithOutputs(
352355
t.t, minerClient, t.tapd, burnResp.BurnTransfer,
@@ -357,8 +360,7 @@ func testBurnAssets(t *harnessTest) {
357360

358361
AssertBalances(
359362
t.t, t.tapd,
360-
burnAmt+simpleCollectible.Amount+multiBurnAmt+burnAmt+1,
361-
WithNumUtxos(5), WithNumAnchorUtxos(5),
363+
burnAmt+multiBurnAmt+burnAmt+1,
362364
WithScriptKeyType(asset.ScriptKeyBurn),
363365
)
364366

@@ -406,6 +408,7 @@ func testBurnGroupedAssets(t *harnessTest) {
406408

407409
var (
408410
firstMintResp = firstMintResponses[0]
411+
burnAssetID1 = firstMintResp.AssetGenesis.AssetId
409412
assetGroupKey = firstMintResp.AssetGroup.TweakedGroupKey
410413
)
411414

@@ -440,33 +443,34 @@ func testBurnGroupedAssets(t *harnessTest) {
440443
assetGroup := assetGroups.Groups[encodedGroupKey]
441444
require.Len(t.t, assetGroup.Assets, 2)
442445

443-
// Burn some amount of the second asset.
446+
totalAmt := firstMintResp.Amount + secondMintResp.Amount
447+
AssertBalanceByGroup(t.t, t.tapd, encodedGroupKey, totalAmt)
448+
449+
// Test case 1: Burn by asset id.
444450
var (
445-
burnAssetID = secondMintResp.AssetGenesis.AssetId
451+
burnAssetID2 = secondMintResp.AssetGenesis.AssetId
446452

447453
preBurnAmt = secondMintResp.Amount
448454
burnAmt = uint64(10)
449455
postBurnAmt = preBurnAmt - burnAmt
450456
)
451457

452458
burnResp, err := t.tapd.BurnAsset(ctxb, &taprpc.BurnAssetRequest{
453-
Asset: &taprpc.BurnAssetRequest_AssetId{
454-
AssetId: burnAssetID,
459+
AssetSpecifier: &taprpc.AssetSpecifier{
460+
Id: &taprpc.AssetSpecifier_AssetId{
461+
AssetId: burnAssetID2,
462+
},
455463
},
456464
AmountToBurn: burnAmt,
457465
Note: burnNote,
458466
ConfirmationText: taprootassets.AssetBurnConfirmationText,
459467
})
460468
require.NoError(t.t, err)
461469

462-
burnRespJSON, err := formatProtoJSON(burnResp)
463-
require.NoError(t.t, err)
464-
t.Logf("Got response from burning %d units: %v", burnAmt, burnRespJSON)
465-
466470
// Assert that the asset burn transfer occurred correctly.
467471
AssertAssetOutboundTransferWithOutputs(
468472
t.t, miner, t.tapd, burnResp.BurnTransfer,
469-
[][]byte{burnAssetID}, []uint64{postBurnAmt, burnAmt}, 0, 1, 2,
473+
[][]byte{burnAssetID2}, []uint64{postBurnAmt, burnAmt}, 0, 1, 2,
470474
true,
471475
)
472476

@@ -486,7 +490,7 @@ func testBurnGroupedAssets(t *harnessTest) {
486490
)
487491

488492
// Our asset balance should have been decreased by the burned amount.
489-
AssertBalanceByID(t.t, t.tapd, burnAssetID, postBurnAmt)
493+
AssertBalanceByID(t.t, t.tapd, burnAssetID2, postBurnAmt)
490494

491495
// Confirm that the minted asset group still contains two assets.
492496
assetGroups, err = t.tapd.ListGroups(ctxb, &taprpc.ListGroupsRequest{})
@@ -507,6 +511,57 @@ func testBurnGroupedAssets(t *harnessTest) {
507511
require.Equal(t.t, burnAmt, burn.Amount)
508512
require.Equal(t.t, burnNote, burn.Note)
509513
require.Equal(t.t, assetGroupKey, burn.TweakedGroupKey)
514+
515+
// Test case 2: Burn by group key to we select multiple inputs.
516+
burnAmt = totalAmt - burnAmt - 1
517+
burnResp, err = t.tapd.BurnAsset(ctxb, &taprpc.BurnAssetRequest{
518+
AssetSpecifier: &taprpc.AssetSpecifier{
519+
Id: &taprpc.AssetSpecifier_GroupKey{
520+
GroupKey: assetGroupKey,
521+
},
522+
},
523+
AmountToBurn: burnAmt,
524+
ConfirmationText: taprootassets.AssetBurnConfirmationText,
525+
})
526+
require.NoError(t.t, err)
527+
528+
// When burning by group key with multiple inputs, the coin selection
529+
// can vary. We verify that:
530+
// 1. There are 3 outputs total (1 change + 2 burn outputs)
531+
// 2. The sum of all outputs equals the total remaining balance
532+
// 3. One output is the change amount (1 unit)
533+
actualBurnOutputAmounts := transferOutputAmounts(
534+
burnResp.BurnTransfer.Outputs,
535+
)
536+
require.Len(t.t, actualBurnOutputAmounts, 3)
537+
538+
// Sum should equal total balance before this burn.
539+
totalBeforeBurn := firstMintResp.Amount + postBurnAmt
540+
actualSum := uint64(0)
541+
for _, amt := range actualBurnOutputAmounts {
542+
actualSum += amt
543+
}
544+
require.Equal(t.t, totalBeforeBurn, actualSum)
545+
546+
// One output should be the change (1 unit).
547+
require.Contains(t.t, actualBurnOutputAmounts, uint64(1))
548+
549+
AssertAssetOutboundTransferWithOutputs(
550+
t.t, miner, t.tapd, burnResp.BurnTransfer,
551+
[][]byte{burnAssetID1, burnAssetID2},
552+
actualBurnOutputAmounts,
553+
1, 2, 3, true,
554+
)
555+
AssertBalanceByGroup(t.t, t.tapd, encodedGroupKey, 1)
556+
}
557+
558+
func transferOutputAmounts(outputs []*taprpc.TransferOutput) []uint64 {
559+
amounts := make([]uint64, len(outputs))
560+
for i, out := range outputs {
561+
amounts[i] = out.Amount
562+
}
563+
564+
return amounts
510565
}
511566

512567
// testFullBurnUTXO tests that we can burn the full amount of an asset UTXO.

itest/supply_commit_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -895,8 +895,10 @@ func testSupplyCommitMintBurn(t *harnessTest) {
895895
)
896896

897897
burnResp, err := t.tapd.BurnAsset(ctxb, &taprpc.BurnAssetRequest{
898-
Asset: &taprpc.BurnAssetRequest_AssetId{
899-
AssetId: rpcFirstAsset.AssetGenesis.AssetId,
898+
AssetSpecifier: &taprpc.AssetSpecifier{
899+
Id: &taprpc.AssetSpecifier_AssetId{
900+
AssetId: rpcFirstAsset.AssetGenesis.AssetId,
901+
},
900902
},
901903
AmountToBurn: burnAmt,
902904
Note: burnNote,

0 commit comments

Comments
 (0)