@@ -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.
0 commit comments