Skip to content

Commit da8bba4

Browse files
committed
tapdb: add new TLV fields to assets meta table
1 parent fdfc902 commit da8bba4

File tree

12 files changed

+267
-57
lines changed

12 files changed

+267
-57
lines changed

tapdb/addrs.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,11 +1131,14 @@ func (t *TapAddressBook) FetchAssetMetaByHash(ctx context.Context,
11311131

11321132
// If no record is present, we should get a sql.ErrNoRows error
11331133
// above.
1134-
parseAssetMetaReveal(dbMeta.AssetsMetum).WhenSome(
1135-
func(meta proof.MetaReveal) {
1136-
assetMeta = &meta
1137-
},
1138-
)
1134+
metaOpt, err := parseAssetMetaReveal(dbMeta.AssetsMetum)
1135+
if err != nil {
1136+
return fmt.Errorf("unable to parse asset meta: %w", err)
1137+
}
1138+
1139+
metaOpt.WhenSome(func(meta proof.MetaReveal) {
1140+
assetMeta = &meta
1141+
})
11391142

11401143
return nil
11411144
})
@@ -1164,11 +1167,14 @@ func (t *TapAddressBook) FetchAssetMetaForAsset(ctx context.Context,
11641167

11651168
// If no record is present, we should get a sql.ErrNoRows error
11661169
// above.
1167-
parseAssetMetaReveal(dbMeta.AssetsMetum).WhenSome(
1168-
func(meta proof.MetaReveal) {
1169-
assetMeta = &meta
1170-
},
1171-
)
1170+
metaOpt, err := parseAssetMetaReveal(dbMeta.AssetsMetum)
1171+
if err != nil {
1172+
return fmt.Errorf("unable to parse asset meta: %w", err)
1173+
}
1174+
1175+
metaOpt.WhenSome(func(meta proof.MetaReveal) {
1176+
assetMeta = &meta
1177+
})
11721178

11731179
return nil
11741180
})

tapdb/asset_meta.go

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package tapdb
22

33
import (
4+
"net/url"
5+
"strings"
6+
7+
"github.com/btcsuite/btcd/btcec/v2"
48
"github.com/lightninglabs/taproot-assets/fn"
59
"github.com/lightninglabs/taproot-assets/proof"
610
"github.com/lightninglabs/taproot-assets/tapdb/sqlc"
@@ -11,13 +15,48 @@ import (
1115
// the case if there is no database entry for the asset meta and there was a
1216
// LEFT JOIN in a query. Non-existence of a standalone asset metadata record
1317
// should be decided by the sql.ErrNoRows instead.
14-
func parseAssetMetaReveal(meta sqlc.AssetsMetum) fn.Option[proof.MetaReveal] {
18+
func parseAssetMetaReveal(
19+
meta sqlc.AssetsMetum) (fn.Option[proof.MetaReveal], error) {
20+
1521
if len(meta.MetaDataHash) == 0 {
16-
return fn.None[proof.MetaReveal]()
22+
return fn.None[proof.MetaReveal](), nil
23+
}
24+
25+
var canonicalUniverse fn.Option[[]url.URL]
26+
if len(meta.MetaCanonicalUniverses) > 0 {
27+
urls := strings.Split(
28+
string(meta.MetaCanonicalUniverses), "\x00",
29+
)
30+
canonicalUniverseURLs := make([]url.URL, len(urls))
31+
for i, u := range urls {
32+
canonicalUniverseURL, err := url.ParseRequestURI(u)
33+
if err != nil {
34+
return fn.None[proof.MetaReveal](), err
35+
}
36+
canonicalUniverseURLs[i] = *canonicalUniverseURL
37+
}
38+
39+
canonicalUniverse = fn.Some(canonicalUniverseURLs)
40+
}
41+
42+
var delegationKey fn.Option[btcec.PublicKey]
43+
if len(meta.MetaDelegationKey) > 0 {
44+
key, err := btcec.ParsePubKey(meta.MetaDelegationKey)
45+
if err != nil {
46+
return fn.None[proof.MetaReveal](), err
47+
}
48+
49+
delegationKey = fn.Some(*key)
1750
}
1851

1952
return fn.Some(proof.MetaReveal{
2053
Data: meta.MetaDataBlob,
2154
Type: proof.MetaType(meta.MetaDataType.Int16),
22-
})
55+
DecimalDisplay: extractOptSqlInt32[uint32](
56+
meta.MetaDecimalDisplay,
57+
),
58+
UniverseCommitments: extractBool(meta.MetaUniverseCommitments),
59+
CanonicalUniverses: canonicalUniverse,
60+
DelegationKey: delegationKey,
61+
}), nil
2362
}

tapdb/asset_meta_test.go

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ package tapdb
33
import (
44
"context"
55
"math/rand"
6+
"net/url"
67
"testing"
78

9+
"github.com/lightninglabs/taproot-assets/asset"
10+
"github.com/lightninglabs/taproot-assets/fn"
811
"github.com/lightninglabs/taproot-assets/proof"
912
"github.com/stretchr/testify/require"
1013
)
@@ -46,15 +49,54 @@ func TestAssetMetaUpsert(t *testing.T) {
4649
// Now we'll insert the meta hash again, but this time we'll add the
4750
// blob.
4851
metaID, err = db.UpsertAssetMeta(ctx, NewAssetMeta{
49-
MetaDataHash: metaHash[:],
50-
MetaDataBlob: assetMeta.Data,
52+
MetaDataHash: metaHash[:],
53+
MetaDataBlob: assetMeta.Data,
54+
MetaDecimalDisplay: sqlInt32(11),
55+
MetaUniverseCommitments: sqlBool(true),
56+
MetaCanonicalUniverses: []byte("http://test1\x00http://test2"),
57+
MetaDelegationKey: asset.NUMSBytes,
5158
})
5259
require.NoError(t, err)
5360

5461
// If we fetch the meta, then we should get the blob back this time.
5562
fetchedMeta, err := db.FetchAssetMeta(ctx, metaID)
5663
require.NoError(t, err)
5764
require.Equal(t, metaBlob[:], fetchedMeta.AssetsMetum.MetaDataBlob)
65+
require.Equal(
66+
t, sqlInt32(11), fetchedMeta.AssetsMetum.MetaDecimalDisplay,
67+
)
68+
require.Equal(
69+
t, sqlBool(true),
70+
fetchedMeta.AssetsMetum.MetaUniverseCommitments,
71+
)
72+
require.Equal(
73+
t, []byte("http://test1\x00http://test2"),
74+
fetchedMeta.AssetsMetum.MetaCanonicalUniverses,
75+
)
76+
require.Equal(
77+
t, asset.NUMSBytes,
78+
fetchedMeta.AssetsMetum.MetaDelegationKey,
79+
)
80+
81+
parsed, err := parseAssetMetaReveal(fetchedMeta.AssetsMetum)
82+
require.NoError(t, err)
83+
require.True(t, parsed.IsSome())
84+
85+
url1, err := url.ParseRequestURI("http://test1")
86+
require.NoError(t, err)
87+
url2, err := url.ParseRequestURI("http://test2")
88+
require.NoError(t, err)
89+
parsed.WhenSome(func(reveal proof.MetaReveal) {
90+
require.Equal(t, fn.Some(uint32(11)), reveal.DecimalDisplay)
91+
require.Equal(t, true, reveal.UniverseCommitments)
92+
require.Equal(
93+
t, fn.Some([]url.URL{*url1, *url2}),
94+
reveal.CanonicalUniverses,
95+
)
96+
require.Equal(
97+
t, fn.MaybeSome(asset.NUMSPubKey), reveal.DelegationKey,
98+
)
99+
})
58100

59101
// If we insert a meta of all zeroes twice, then we should get the same
60102
// value back.

tapdb/asset_minting.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -738,11 +738,15 @@ func fetchAssetSeedlings(ctx context.Context, q PendingAssetStore,
738738
seedling.GroupAnchor = &seedlingAnchor.AssetName
739739
}
740740

741-
parseAssetMetaReveal(dbSeedling.AssetsMetum).WhenSome(
742-
func(meta proof.MetaReveal) {
743-
seedling.Meta = &meta
744-
},
745-
)
741+
metaOpt, err := parseAssetMetaReveal(dbSeedling.AssetsMetum)
742+
if err != nil {
743+
return nil, fmt.Errorf("unable to parse asset meta: %w",
744+
err)
745+
}
746+
747+
metaOpt.WhenSome(func(meta proof.MetaReveal) {
748+
seedling.Meta = &meta
749+
})
746750

747751
seedlings[seedling.AssetName] = seedling
748752
}
@@ -968,9 +972,12 @@ func fetchMetaByAssetID(ctx context.Context, db PendingAssetStore,
968972

969973
// Parse the meta reveal from the database. We expect it to exist at
970974
// this point, as we didn't get an sql.ErrNoRows error above.
971-
meta, err := parseAssetMetaReveal(assetMeta.AssetsMetum).UnwrapOrErr(
972-
ErrNoAssetMeta,
973-
)
975+
metaOpt, err := parseAssetMetaReveal(assetMeta.AssetsMetum)
976+
if err != nil {
977+
return nil, fmt.Errorf("unable to parse asset meta: %w", err)
978+
}
979+
980+
meta, err := metaOpt.UnwrapOrErr(ErrNoAssetMeta)
974981
if err != nil {
975982
return nil, err
976983
}

tapdb/assets_common.go

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"database/sql"
88
"errors"
99
"fmt"
10+
"net/url"
11+
"strings"
1012

1113
"github.com/btcsuite/btcd/btcec/v2"
1214
"github.com/btcsuite/btcd/chaincfg/chainhash"
@@ -688,9 +690,13 @@ func maybeUpsertAssetMeta(ctx context.Context, db UpsertAssetStore,
688690
assetGen *asset.Genesis, metaReveal *proof.MetaReveal) (int64, error) {
689691

690692
var (
691-
metaHash [32]byte
692-
metaBlob []byte
693-
metaType sql.NullInt16
693+
metaHash [32]byte
694+
metaBlob []byte
695+
metaType sql.NullInt16
696+
metaDecimalDisplay sql.NullInt32
697+
metaUniverseCommitments sql.NullBool
698+
metaCanonicalUniverses []byte
699+
metaDelegationKey []byte
694700

695701
err error
696702
)
@@ -701,10 +707,22 @@ func maybeUpsertAssetMeta(ctx context.Context, db UpsertAssetStore,
701707
case metaReveal != nil:
702708
metaHash = metaReveal.MetaHash()
703709
metaBlob = metaReveal.Data
704-
metaType = sql.NullInt16{
705-
Int16: int16(metaReveal.Type),
706-
Valid: true,
707-
}
710+
metaType = sqlInt16(metaReveal.Type)
711+
metaDecimalDisplay = sqlOptInt32(metaReveal.DecimalDisplay)
712+
metaUniverseCommitments = sqlBool(
713+
metaReveal.UniverseCommitments,
714+
)
715+
metaReveal.CanonicalUniverses.WhenSome(func(u []url.URL) {
716+
urlStrings := fn.Map(u, func(u url.URL) string {
717+
return u.String()
718+
})
719+
metaCanonicalUniverses = []byte(
720+
strings.Join(urlStrings, "\x00"),
721+
)
722+
})
723+
metaReveal.DelegationKey.WhenSome(func(key btcec.PublicKey) {
724+
metaDelegationKey = key.SerializeCompressed()
725+
})
708726

709727
// Otherwise, we'll just be inserting only the meta hash. At a later
710728
// time, the reveal/blob can also be inserted.
@@ -717,9 +735,13 @@ func maybeUpsertAssetMeta(ctx context.Context, db UpsertAssetStore,
717735
}
718736

719737
assetMetaID, err := db.UpsertAssetMeta(ctx, NewAssetMeta{
720-
MetaDataHash: metaHash[:],
721-
MetaDataBlob: metaBlob,
722-
MetaDataType: metaType,
738+
MetaDataHash: metaHash[:],
739+
MetaDataBlob: metaBlob,
740+
MetaDataType: metaType,
741+
MetaDecimalDisplay: metaDecimalDisplay,
742+
MetaUniverseCommitments: metaUniverseCommitments,
743+
MetaCanonicalUniverses: metaCanonicalUniverses,
744+
MetaDelegationKey: metaDelegationKey,
723745
})
724746
if err != nil {
725747
return assetMetaID, err

tapdb/migrations.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const (
2222
// daemon.
2323
//
2424
// NOTE: This MUST be updated when a new migration is added.
25-
LatestMigrationVersion = 27
25+
LatestMigrationVersion = 28
2626
)
2727

2828
// MigrationTarget is a functional option that can be passed to applyMigrations

0 commit comments

Comments
 (0)