Skip to content

Commit 9c85a55

Browse files
author
Robyn Ffrancon
authored
Merge pull request #732 from ffranr/burn-asset-bug
Add asset group burn itest, logging, and missing error handling
2 parents 3b71255 + 2f09b7e commit 9c85a55

File tree

3 files changed

+136
-1
lines changed

3 files changed

+136
-1
lines changed

itest/burn_test.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package itest
22

33
import (
44
"context"
5+
"encoding/hex"
56

67
taprootassets "github.com/lightninglabs/taproot-assets"
78
"github.com/lightninglabs/taproot-assets/address"
@@ -301,3 +302,112 @@ func testBurnAssets(t *harnessTest) {
301302
)
302303
AssertBalanceByID(t.t, t.tapd, simpleGroupCollectGen.AssetId, 0)
303304
}
305+
306+
// testBurnGroupedAssets tests that some amount of an asset from an asset group
307+
// can be burnt successfully.
308+
func testBurnGroupedAssets(t *harnessTest) {
309+
var (
310+
ctxb = context.Background()
311+
miner = t.lndHarness.Miner.Client
312+
313+
firstMintReq = issuableAssets[0]
314+
)
315+
316+
// We start off without any asset groups.
317+
AssertNumGroups(t.t, t.tapd, 0)
318+
319+
// Next, we mint a re-issuable asset, creating a new asset group.
320+
firstMintResponses := MintAssetsConfirmBatch(
321+
t.t, miner, t.tapd, []*mintrpc.MintAssetRequest{firstMintReq},
322+
)
323+
require.Len(t.t, firstMintResponses, 1)
324+
325+
var (
326+
firstMintResp = firstMintResponses[0]
327+
assetGroupKey = firstMintResp.AssetGroup.TweakedGroupKey
328+
)
329+
330+
// Ensure that an asset group was created.
331+
AssertNumGroups(t.t, t.tapd, 1)
332+
333+
// Issue a further asset into the asset group.
334+
simpleAssetsCopy := CopyRequests(simpleAssets)
335+
secondMintReq := simpleAssetsCopy[0]
336+
secondMintReq.Asset.Amount = 1010
337+
secondMintReq.Asset.GroupKey = assetGroupKey
338+
secondMintReq.Asset.GroupedAsset = true
339+
340+
secondMintResponses := MintAssetsConfirmBatch(
341+
t.t, miner, t.tapd,
342+
[]*mintrpc.MintAssetRequest{secondMintReq},
343+
)
344+
require.Len(t.t, secondMintResponses, 1)
345+
346+
// Ensure that we haven't created a new group.
347+
AssertNumGroups(t.t, t.tapd, 1)
348+
349+
secondMintResp := secondMintResponses[0]
350+
351+
// Confirm that the minted asset group contains two assets.
352+
assetGroups, err := t.tapd.ListGroups(
353+
ctxb, &taprpc.ListGroupsRequest{},
354+
)
355+
require.NoError(t.t, err)
356+
357+
encodedGroupKey := hex.EncodeToString(assetGroupKey)
358+
assetGroup := assetGroups.Groups[encodedGroupKey]
359+
require.Len(t.t, assetGroup.Assets, 2)
360+
361+
// Burn some amount of the second asset.
362+
var (
363+
burnAssetID = secondMintResp.AssetGenesis.AssetId
364+
365+
preBurnAmt = secondMintResp.Amount
366+
burnAmt = uint64(10)
367+
postBurnAmt = preBurnAmt - burnAmt
368+
)
369+
370+
burnResp, err := t.tapd.BurnAsset(ctxb, &taprpc.BurnAssetRequest{
371+
Asset: &taprpc.BurnAssetRequest_AssetId{
372+
AssetId: burnAssetID,
373+
},
374+
AmountToBurn: burnAmt,
375+
ConfirmationText: taprootassets.AssetBurnConfirmationText,
376+
})
377+
require.NoError(t.t, err)
378+
379+
burnRespJSON, err := formatProtoJSON(burnResp)
380+
require.NoError(t.t, err)
381+
t.Logf("Got response from burning %d units: %v", burnAmt, burnRespJSON)
382+
383+
// Assert that the asset burn transfer occurred correctly.
384+
AssertAssetOutboundTransferWithOutputs(
385+
t.t, miner, t.tapd, burnResp.BurnTransfer,
386+
burnAssetID, []uint64{postBurnAmt, burnAmt}, 0, 1, 2, true,
387+
)
388+
389+
// Ensure that the burnt asset has the correct state.
390+
burnedAsset := burnResp.BurnProof.Asset
391+
allAssets, err := t.tapd.ListAssets(
392+
ctxb, &taprpc.ListAssetRequest{IncludeSpent: true},
393+
)
394+
require.NoError(t.t, err)
395+
AssertAssetStateByScriptKey(
396+
t.t, allAssets.Assets, burnedAsset.ScriptKey,
397+
AssetAmountCheck(burnedAsset.Amount),
398+
AssetTypeCheck(burnedAsset.AssetGenesis.AssetType),
399+
AssetScriptKeyIsLocalCheck(false),
400+
AssetScriptKeyIsBurnCheck(true),
401+
)
402+
403+
// Our asset balance should have been decreased by the burned amount.
404+
AssertBalanceByID(t.t, t.tapd, burnAssetID, postBurnAmt)
405+
406+
// Confirm that the minted asset group still contains two assets.
407+
assetGroups, err = t.tapd.ListGroups(ctxb, &taprpc.ListGroupsRequest{})
408+
require.NoError(t.t, err)
409+
410+
encodedGroupKey = hex.EncodeToString(assetGroupKey)
411+
assetGroup = assetGroups.Groups[encodedGroupKey]
412+
require.Len(t.t, assetGroup.Assets, 2)
413+
}

itest/test_list_on_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ var testCases = []*testCase{
187187
name: "burn test",
188188
test: testBurnAssets,
189189
},
190+
{
191+
name: "burn grouped assets",
192+
test: testBurnGroupedAssets,
193+
},
190194
{
191195
name: "federation sync config",
192196
test: testFederationSyncConfig,

rpcserver.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2063,6 +2063,8 @@ func (r *rpcServer) SendAsset(_ context.Context,
20632063
func (r *rpcServer) BurnAsset(ctx context.Context,
20642064
in *taprpc.BurnAssetRequest) (*taprpc.BurnAssetResponse, error) {
20652065

2066+
rpcsLog.Debug("Executing asset burn")
2067+
20662068
var assetID asset.ID
20672069
switch {
20682070
case len(in.GetAssetId()) > 0:
@@ -2092,10 +2094,29 @@ func (r *rpcServer) BurnAsset(ctx context.Context,
20922094

20932095
var groupKey *btcec.PublicKey
20942096
assetGroup, err := r.cfg.TapAddrBook.QueryAssetGroup(ctx, assetID)
2095-
if err == nil && assetGroup.GroupKey != nil {
2097+
switch {
2098+
case err == nil && assetGroup.GroupKey != nil:
2099+
// We found the asset group, so we can use the group key to
2100+
// burn the asset.
20962101
groupKey = &assetGroup.GroupPubKey
2102+
case errors.Is(err, address.ErrAssetGroupUnknown):
2103+
// We don't know the asset group, so we'll try to burn the
2104+
// asset using the asset ID only.
2105+
rpcsLog.Debug("Asset group key not found, asset may not be " +
2106+
"part of a group")
2107+
case err != nil:
2108+
return nil, fmt.Errorf("error querying asset group: %w", err)
20972109
}
20982110

2111+
var serializedGroupKey []byte
2112+
if groupKey != nil {
2113+
serializedGroupKey = groupKey.SerializeCompressed()
2114+
}
2115+
2116+
rpcsLog.Infof("Burning asset (asset_id=%x, group_key=%x, "+
2117+
"burn_amount=%d)", assetID[:], serializedGroupKey,
2118+
in.AmountToBurn)
2119+
20992120
fundResp, err := r.cfg.AssetWallet.FundBurn(
21002121
ctx, &tapscript.FundingDescriptor{
21012122
ID: assetID,

0 commit comments

Comments
 (0)