Skip to content

Commit 70b62f2

Browse files
authored
Merge pull request #1517 from lightninglabs/re-issuance-external-group-key
minting: fix re-issuing into existing group with external key
2 parents 5b21215 + 8863f04 commit 70b62f2

File tree

7 files changed

+63
-19
lines changed

7 files changed

+63
-19
lines changed

itest/mint_fund_seal_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,9 @@ func testMintExternalGroupKeyChantools(t *harnessTest) {
577577
mintReq2 := CopyRequest(issuableAssets[0])
578578
mintReq2.Asset.Name = "itestbuxx-money-printer-brrr-tranche-2"
579579
mintReq2.Asset.ExternalGroupKey = externalGroupKey
580+
mintReq2.Asset.GroupedAsset = true
581+
mintReq2.Asset.NewGroupedAsset = false
582+
mintReq2.Asset.GroupKey = batchAssets[0].AssetGroup.TweakedGroupKey
580583

581584
assetReqs2 := []*mintrpc.MintAssetRequest{mintReq2}
582585

itest/multi_asset_group_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ func testMintMultiAssetGroupErrors(t *harnessTest) {
245245

246246
groupedAsset.Asset.GroupAnchor = validAnchorName
247247
_, err = t.tapd.MintAsset(ctxb, groupedAsset)
248-
require.ErrorContains(t.t, err, "has emission disabled")
248+
require.ErrorContains(t.t, err, "isn't starting a new group")
249249

250250
// Finally, we'll modify the assets to make the multi-asset group valid.
251251
validAnchor.Asset.NewGroupedAsset = true

itest/re-issuance_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,9 @@ func testMintWithGroupKeyErrors(t *harnessTest) {
329329
reissueRequest.Asset.NewGroupedAsset = true
330330
reissueRequest.Asset.GroupedAsset = false
331331
_, err = t.tapd.MintAsset(ctxb, reissueRequest)
332-
require.ErrorContains(t.t, err, "must disable emission to specify")
332+
require.ErrorContains(
333+
t.t, err, "must not create new grouped asset to specify",
334+
)
333335

334336
// Restore the correct flags for a new grouped asset.
335337
reissueRequest.Asset.NewGroupedAsset = false

rpcserver.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -443,19 +443,19 @@ func (r *rpcServer) MintAsset(ctx context.Context,
443443
// Using a specific group key or anchor implies disabling emission.
444444
case req.Asset.NewGroupedAsset:
445445
if specificGroupKey || specificGroupAnchor {
446-
return nil, fmt.Errorf("must disable emission to " +
447-
"specify a group")
446+
return nil, fmt.Errorf("must not create new grouped " +
447+
"asset to specify an existing group")
448448
}
449449

450450
// A group tapscript root cannot be specified if emission is disabled.
451451
case !req.Asset.NewGroupedAsset && groupTapscriptRootSize != 0:
452452
return nil, fmt.Errorf("cannot specify a group tapscript root" +
453-
"with emission disabled")
453+
"when not creating a new grouped asset")
454454

455455
// A group internal key cannot be specified if emission is disabled.
456456
case !req.Asset.NewGroupedAsset && specificGroupInternalKey:
457457
return nil, fmt.Errorf("cannot specify a group internal key" +
458-
"with emission disabled")
458+
"when not creating a new grouped asset")
459459

460460
// If the asset is intended to be part of an existing group, a group key
461461
// or anchor must be specified, but not both. Neither a group tapscript
@@ -473,12 +473,14 @@ func (r *rpcServer) MintAsset(ctx context.Context,
473473

474474
if groupTapscriptRootSize != 0 {
475475
return nil, fmt.Errorf("cannot specify a group " +
476-
"tapscript root with emission disabled")
476+
"tapscript root when not creating a new " +
477+
"grouped asset")
477478
}
478479

479480
if specificGroupInternalKey {
480481
return nil, fmt.Errorf("cannot specify a group " +
481-
"internal key with emission disabled")
482+
"internal key when not creating a new " +
483+
"grouped asset")
482484
}
483485

484486
// A group was specified without GroupedAsset being set.
@@ -608,8 +610,9 @@ func (r *rpcServer) MintAsset(ctx context.Context,
608610
}
609611

610612
rpcsLog.Infof("[MintAsset]: version=%v, type=%v, name=%v, amt=%v, "+
611-
"enable_emission=%v", seedling.AssetVersion, seedling.AssetType,
612-
seedling.AssetName, seedling.Amount, seedling.EnableEmission)
613+
"new_grouped_asset=%v", seedling.AssetVersion,
614+
seedling.AssetType, seedling.AssetName, seedling.Amount,
615+
seedling.EnableEmission)
613616

614617
if scriptKey != nil {
615618
seedling.ScriptKey = *scriptKey

tapgarden/batch.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ func (m *MintingBatch) validateGroupAnchor(s *Seedling) error {
149149
s.GroupAnchor)
150150
}
151151
if !anchor.EnableEmission {
152-
return fmt.Errorf("group anchor %v has emission disabled",
152+
return fmt.Errorf("group anchor %v isn't starting a new group",
153153
*s.GroupAnchor)
154154
}
155155

@@ -414,9 +414,9 @@ func (m *MintingBatch) validateUniCommitment(newSeedling Seedling) error {
414414
// seedling has the universe commitment flag enabled, it must
415415
// specify a re-issuable asset group key.
416416
if !newSeedling.EnableEmission {
417-
return fmt.Errorf("the emission flag must be enabled " +
418-
"for the first asset in a batch with the " +
419-
"universe commitment flag enabled")
417+
return fmt.Errorf("the 'new grouped asset' flag must " +
418+
"be enabled for the first asset in a batch " +
419+
"with the universe commitment flag enabled")
420420
}
421421

422422
if !newSeedling.HasGroupKey() {

tapgarden/planter.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,14 +2668,19 @@ func (c *ChainPlanter) prepAssetSeedling(ctx context.Context,
26682668
// If a group internal key or tapscript root is specified, emission must
26692669
// also be enabled.
26702670
if !req.EnableEmission {
2671-
if req.GroupInternalKey != nil {
2671+
// For re-issuing grouped assets or regular (non-grouped)
2672+
// assets, the group internal key shouldn't be set. It is,
2673+
// however, set for re-issuance with an external key, because
2674+
// the internal group key is the key we compare the external key
2675+
// against.
2676+
if req.GroupInternalKey != nil && req.ExternalKey.IsNone() {
26722677
return fmt.Errorf("cannot specify group internal key " +
2673-
"without enabling emission")
2678+
"without creating a new grouped asset")
26742679
}
26752680

26762681
if req.GroupTapscriptRoot != nil {
26772682
return fmt.Errorf("cannot specify group tapscript " +
2678-
"root without enabling emission")
2683+
"root without creating a new grouped asset")
26792684
}
26802685
}
26812686

tapgarden/seedling.go

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,43 @@ func (c Seedling) validateFields() error {
183183
func (c Seedling) validateGroupKey(group asset.AssetGroup,
184184
anchorMeta *proof.MetaReveal) error {
185185

186-
// We must be able to sign with the group key.
187-
if !group.GroupKey.IsLocal() {
186+
// If an external key isn't specified but the actual group key used
187+
// isn't local to this daemon, we won't be able to sign with it.
188+
if c.ExternalKey.IsNone() && !group.GroupKey.IsLocal() {
188189
groupKeyBytes := c.GroupInfo.GroupPubKey.SerializeCompressed()
189190
return fmt.Errorf("can't sign with group key %x", groupKeyBytes)
190191
}
191192

193+
// If there is an external key defined, we need to check that it matches
194+
// the group key.
195+
err := fn.MapOptionZ(
196+
c.ExternalKey, func(extKey asset.ExternalKey) error {
197+
if group.GroupKey == nil {
198+
return fmt.Errorf("group key is nil")
199+
}
200+
201+
if group.GroupKey.RawKey.PubKey == nil {
202+
return fmt.Errorf("group raw key is nil")
203+
}
204+
205+
pk, err := extKey.PubKey()
206+
if err != nil {
207+
return fmt.Errorf("error getting external "+
208+
"key: %w", err)
209+
}
210+
211+
if !pk.IsEqual(group.RawKey.PubKey) {
212+
return fmt.Errorf("external key does not " +
213+
"match group key")
214+
}
215+
216+
return nil
217+
},
218+
)
219+
if err != nil {
220+
return fmt.Errorf("error validating external key: %w", err)
221+
}
222+
192223
// The seedling asset type must match the group asset type.
193224
if c.AssetType != group.Genesis.Type {
194225
return fmt.Errorf("seedling type does not match "+

0 commit comments

Comments
 (0)