Skip to content

Commit 49dd668

Browse files
authored
Merge pull request #1611 from lightninglabs/misc-refactor
[group key addrs 3/5]: misc refactor
2 parents 24b4960 + c7c21af commit 49dd668

31 files changed

+694
-197
lines changed

address/book.go

Lines changed: 97 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/lightninglabs/taproot-assets/commitment"
1717
"github.com/lightninglabs/taproot-assets/fn"
1818
"github.com/lightninglabs/taproot-assets/proof"
19+
lfn "github.com/lightningnetwork/lnd/fn/v2"
1920
"github.com/lightningnetwork/lnd/keychain"
2021
)
2122

@@ -105,6 +106,12 @@ type Storage interface {
105106
// (genesis + group key) associated with a given asset.
106107
QueryAssetGroup(context.Context, asset.ID) (*asset.AssetGroup, error)
107108

109+
// QueryAssetGroupByGroupKey fetches the asset group with a matching
110+
// tweaked key, including the genesis information used to create the
111+
// group.
112+
QueryAssetGroupByGroupKey(context.Context,
113+
*btcec.PublicKey) (*asset.AssetGroup, error)
114+
108115
// FetchAssetMetaByHash attempts to fetch an asset meta based on an
109116
// asset hash.
110117
FetchAssetMetaByHash(ctx context.Context,
@@ -210,38 +217,68 @@ func NewBook(cfg BookConfig) *Book {
210217
// geneses already known to this node. If asset issuance was not previously
211218
// verified, we then query universes in our federation for issuance proofs.
212219
func (b *Book) QueryAssetInfo(ctx context.Context,
213-
id asset.ID) (*asset.AssetGroup, error) {
220+
specifier asset.Specifier) (asset.AssetGroup, error) {
221+
222+
switch {
223+
case specifier.HasGroupPubKey():
224+
return fn.MapOptionZ(
225+
specifier.GroupKey(),
226+
func(gk btcec.PublicKey) lfn.Result[asset.AssetGroup] {
227+
return b.queryAssetInfoByGroupKey(ctx, gk)
228+
},
229+
).Unpack()
230+
231+
case specifier.HasId():
232+
return fn.MapOptionZ(
233+
specifier.ID(),
234+
func(id asset.ID) lfn.Result[asset.AssetGroup] {
235+
return b.queryAssetInfoByID(ctx, id)
236+
},
237+
).Unpack()
238+
239+
default:
240+
return asset.AssetGroup{}, fmt.Errorf("invalid specifier: %s",
241+
&specifier)
242+
}
243+
}
244+
245+
// queryAssetInfoByID attempts to locate asset genesis information by querying
246+
// geneses by ID already known to this node. If asset issuance was not
247+
// previously verified, we then query universes in our federation for issuance
248+
// proofs.
249+
func (b *Book) queryAssetInfoByID(ctx context.Context,
250+
id asset.ID) lfn.Result[asset.AssetGroup] {
214251

215252
// Check if we know of this asset ID already.
216253
assetGroup, err := b.cfg.Store.QueryAssetGroup(ctx, id)
217254
switch {
218255
case assetGroup != nil:
219-
return assetGroup, nil
256+
return lfn.Ok(*assetGroup)
220257

221258
// Asset lookup failed gracefully; continue to asset lookup using the
222259
// AssetSyncer if enabled.
223260
case errors.Is(err, ErrAssetGroupUnknown):
224261
if b.cfg.Syncer == nil {
225-
return nil, ErrAssetGroupUnknown
262+
return lfn.Err[asset.AssetGroup](ErrAssetGroupUnknown)
226263
}
227264

228265
case err != nil:
229-
return nil, err
266+
return lfn.Err[asset.AssetGroup](err)
230267
}
231268

232269
log.Debugf("Asset %v is unknown, attempting to bootstrap", id.String())
233270

234271
// Use the AssetSyncer to query our universe federation for the asset.
235272
err = b.cfg.Syncer.SyncAssetInfo(ctx, asset.NewSpecifierFromId(id))
236273
if err != nil {
237-
return nil, err
274+
return lfn.Err[asset.AssetGroup](err)
238275
}
239276

240277
// The asset genesis info may have been synced from a universe
241278
// server; query for the asset ID again.
242279
assetGroup, err = b.cfg.Store.QueryAssetGroup(ctx, id)
243280
if err != nil {
244-
return nil, err
281+
return lfn.Err[asset.AssetGroup](err)
245282
}
246283

247284
log.Debugf("Bootstrap succeeded for asset %v", id.String())
@@ -257,11 +294,57 @@ func (b *Book) QueryAssetInfo(ctx context.Context,
257294
))
258295
err = b.cfg.Syncer.EnableAssetSync(ctx, assetGroup)
259296
if err != nil {
260-
return nil, err
297+
return lfn.Err[asset.AssetGroup](err)
298+
}
299+
}
300+
301+
return lfn.Ok(*assetGroup)
302+
}
303+
304+
// queryAssetInfoByID attempts to locate asset genesis information by querying
305+
// geneses by group key already known to this node. If asset issuance was not
306+
// previously verified, we then query universes in our federation for issuance
307+
// proofs.
308+
func (b *Book) queryAssetInfoByGroupKey(ctx context.Context,
309+
gk btcec.PublicKey) lfn.Result[asset.AssetGroup] {
310+
311+
// Check if we know of this group key already.
312+
gkBytes := gk.SerializeCompressed()
313+
assetGroup, err := b.cfg.Store.QueryAssetGroupByGroupKey(ctx, &gk)
314+
switch {
315+
case assetGroup != nil:
316+
return lfn.Ok(*assetGroup)
317+
318+
// Asset lookup failed gracefully; continue to asset lookup using the
319+
// AssetSyncer if enabled.
320+
case errors.Is(err, ErrAssetGroupUnknown):
321+
if b.cfg.Syncer == nil {
322+
return lfn.Err[asset.AssetGroup](ErrAssetGroupUnknown)
261323
}
324+
325+
case err != nil:
326+
return lfn.Err[asset.AssetGroup](err)
262327
}
263328

264-
return assetGroup, nil
329+
log.Debugf("Asset group %x is unknown, attempting to bootstrap",
330+
gkBytes)
331+
332+
// Use the AssetSyncer to query our universe federation for the asset.
333+
err = b.SyncAssetGroup(ctx, gk)
334+
if err != nil {
335+
return lfn.Err[asset.AssetGroup](err)
336+
}
337+
338+
// The asset genesis info may have been synced from a universe
339+
// server; query for the group key again.
340+
assetGroup, err = b.cfg.Store.QueryAssetGroupByGroupKey(ctx, &gk)
341+
if err != nil {
342+
return lfn.Err[asset.AssetGroup](err)
343+
}
344+
345+
log.Debugf("Bootstrap succeeded for group %x", gkBytes)
346+
347+
return lfn.Ok(*assetGroup)
265348
}
266349

267350
// SyncAssetGroup attempts to enable asset sync for the given asset group, then
@@ -336,16 +419,16 @@ func (b *Book) FetchAssetMetaForAsset(ctx context.Context,
336419

337420
// NewAddress creates a new Taproot Asset address based on the input parameters.
338421
func (b *Book) NewAddress(ctx context.Context, addrVersion Version,
339-
assetID asset.ID, amount uint64,
422+
specifier asset.Specifier, amount uint64,
340423
tapscriptSibling *commitment.TapscriptPreimage,
341424
proofCourierAddr url.URL, addrOpts ...NewAddrOpt) (*AddrWithKeyInfo,
342425
error) {
343426

344427
// Before we proceed and make new keys, make sure that we actually know
345428
// of this asset ID, or can import it.
346-
if _, err := b.QueryAssetInfo(ctx, assetID); err != nil {
429+
if _, err := b.QueryAssetInfo(ctx, specifier); err != nil {
347430
return nil, fmt.Errorf("unable to make address for unknown "+
348-
"asset %x: %w", assetID[:], err)
431+
"asset %s: %w", &specifier, err)
349432
}
350433

351434
rawScriptKeyDesc, err := b.cfg.KeyRing.DeriveNextTaprootAssetKey(ctx)
@@ -364,15 +447,15 @@ func (b *Book) NewAddress(ctx context.Context, addrVersion Version,
364447
}
365448

366449
return b.NewAddressWithKeys(
367-
ctx, addrVersion, assetID, amount, scriptKey, internalKeyDesc,
450+
ctx, addrVersion, specifier, amount, scriptKey, internalKeyDesc,
368451
tapscriptSibling, proofCourierAddr, addrOpts...,
369452
)
370453
}
371454

372455
// NewAddressWithKeys creates a new Taproot Asset address based on the input
373456
// parameters that include pre-derived script and internal keys.
374457
func (b *Book) NewAddressWithKeys(ctx context.Context, addrVersion Version,
375-
assetID asset.ID, amount uint64, scriptKey asset.ScriptKey,
458+
specifier asset.Specifier, amount uint64, scriptKey asset.ScriptKey,
376459
internalKeyDesc keychain.KeyDescriptor,
377460
tapscriptSibling *commitment.TapscriptPreimage,
378461
proofCourierAddr url.URL, addrOpts ...NewAddrOpt) (*AddrWithKeyInfo,
@@ -381,7 +464,7 @@ func (b *Book) NewAddressWithKeys(ctx context.Context, addrVersion Version,
381464
// Before we proceed, we'll make sure that the asset group is known to
382465
// the local store. Otherwise, we can't make an address as we haven't
383466
// bootstrapped it.
384-
assetGroup, err := b.QueryAssetInfo(ctx, assetID)
467+
assetGroup, err := b.QueryAssetInfo(ctx, specifier)
385468
if err != nil {
386469
return nil, err
387470
}

0 commit comments

Comments
 (0)