Skip to content

Commit f0b41a2

Browse files
authored
Merge pull request #1675 from lightninglabs/state-machine-hookup
multi: hook up burn and mint events to the supply commit state machine
2 parents 21fb82b + 0390ec1 commit f0b41a2

31 files changed

+2117
-136
lines changed

address/book.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ var (
2828
// ErrAssetMetaNotFound is returned when an asset meta is not found in
2929
// the database.
3030
ErrAssetMetaNotFound = fmt.Errorf("asset meta not found")
31+
32+
// ErrAssetGroupQueryFailed is returned when querying for an asset group
33+
// fails.
34+
ErrAssetGroupQueryFailed = fmt.Errorf("asset group query failed")
35+
36+
// ErrAssetMetaQueryFailed is returned when querying for asset metadata
37+
// fails.
38+
ErrAssetMetaQueryFailed = fmt.Errorf("asset meta query failed")
39+
40+
// ErrDelegationKeyQueryFailed is returned when querying for delegation
41+
// key fails.
42+
ErrDelegationKeyQueryFailed = fmt.Errorf("delegation key query failed")
3143
)
3244

3345
// AddrWithKeyInfo wraps a normal Taproot Asset struct with key descriptor
@@ -165,6 +177,12 @@ type Storage interface {
165177
// database.
166178
FetchAllAssetMeta(
167179
ctx context.Context) (map[asset.ID]*proof.MetaReveal, error)
180+
181+
// FetchInternalKeyLocator attempts to fetch the key locator information
182+
// for the given raw internal key. If the key cannot be found, then
183+
// ErrInternalKeyNotFound is returned.
184+
FetchInternalKeyLocator(ctx context.Context,
185+
rawKey *btcec.PublicKey) (keychain.KeyLocator, error)
168186
}
169187

170188
// KeyRing is used to create script and internal keys for Taproot Asset
@@ -841,3 +859,73 @@ func (b *Book) RemoveSubscriber(
841859

842860
return nil
843861
}
862+
863+
// DelegationKeyChecker is used to verify that we control the delegation key
864+
// for a given asset, which is required for creating supply commitments.
865+
type DelegationKeyChecker interface {
866+
// HasDelegationKey checks if we control the delegation key for the
867+
// given asset ID. Returns true if we have the private key for the
868+
// asset's delegation key, false otherwise.
869+
HasDelegationKey(ctx context.Context, assetID asset.ID) (bool, error)
870+
}
871+
872+
// HasDelegationKey checks if we control the delegation key for the given
873+
// asset ID. Returns true if we have the private key for the asset's
874+
// delegation key, false otherwise.
875+
//
876+
// NOTE: This is part of the DelegationKeyChecker interface.
877+
func (b *Book) HasDelegationKey(ctx context.Context,
878+
assetID asset.ID) (bool, error) {
879+
880+
assetGroup, err := b.cfg.Store.QueryAssetGroupByID(ctx, assetID)
881+
if err != nil {
882+
return false, fmt.Errorf("%w: %w", ErrAssetGroupQueryFailed,
883+
err)
884+
}
885+
886+
// If the asset doesn't have a group, it can't have a delegation key. So
887+
// we just return false here.
888+
if assetGroup == nil || assetGroup.GroupKey == nil {
889+
return false, nil
890+
}
891+
892+
// Retrieve asset meta reveal for the asset ID. This will be used to
893+
// obtain the supply commitment delegation key.
894+
metaReveal, err := b.cfg.Store.FetchAssetMetaForAsset(ctx, assetID)
895+
if err != nil {
896+
return false, fmt.Errorf("%w: %w", ErrAssetMetaQueryFailed, err)
897+
}
898+
899+
// If there's no meta reveal or delegation key, we can't control it.
900+
if metaReveal == nil || metaReveal.DelegationKey.IsNone() {
901+
return false, nil
902+
}
903+
904+
delegationPubKey, err := metaReveal.DelegationKey.UnwrapOrErr(
905+
fmt.Errorf("delegation key not found for given asset"),
906+
)
907+
if err != nil {
908+
return false, err
909+
}
910+
911+
// Now that we have the delegation key, we'll see if we know of the
912+
// internal key locator. If we do, then this means that we were the ones
913+
// that created it in the first place.
914+
_, err = b.cfg.Store.FetchInternalKeyLocator(ctx, &delegationPubKey)
915+
switch {
916+
// If we get this error, then we don't control this delegation key.
917+
case errors.Is(err, ErrInternalKeyNotFound):
918+
return false, nil
919+
case err != nil:
920+
return false, fmt.Errorf("%w: %w",
921+
ErrDelegationKeyQueryFailed, err)
922+
}
923+
924+
// If we reached this point, then we know that we control the delegation
925+
// key.
926+
return true, nil
927+
}
928+
929+
// A compile-time assertion to ensure Book implements the DelegationKeyChecker
930+
// interface.
931+
var _ DelegationKeyChecker = (*Book)(nil)

0 commit comments

Comments
 (0)