Skip to content

Commit 94a371a

Browse files
committed
tapdb: upsert multiverse tree
1 parent 1afc90b commit 94a371a

File tree

4 files changed

+360
-175
lines changed

4 files changed

+360
-175
lines changed

internal/test/helpers.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ func SchnorrKey(t testing.TB, pubKey *btcec.PublicKey) *btcec.PublicKey {
9999
return key
100100
}
101101

102+
func SchnorrKeysEqual(t testing.TB, a, b *btcec.PublicKey) bool {
103+
if a == nil || b == nil {
104+
return a == b
105+
}
106+
107+
return SchnorrKey(t, a).IsEqual(SchnorrKey(t, b))
108+
}
109+
102110
func RandPubKey(t testing.TB) *btcec.PublicKey {
103111
return SchnorrPubKey(t, RandPrivKey(t))
104112
}

tapdb/multiverse.go

Lines changed: 61 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"sync/atomic"
1111
"time"
1212

13+
"github.com/btcsuite/btcd/btcec/v2"
1314
"github.com/btcsuite/btcd/btcec/v2/schnorr"
1415
"github.com/lightninglabs/neutrino/cache/lru"
1516
"github.com/lightninglabs/taproot-assets/asset"
@@ -862,75 +863,18 @@ func (b *MultiverseStore) UpsertProofLeaf(ctx context.Context,
862863
issuanceProof *universe.Proof
863864
)
864865

865-
multiverseNS, err := namespaceForProof(id.ProofType)
866-
if err != nil {
867-
return nil, err
868-
}
869-
870866
execTxFunc := func(dbTx BaseMultiverseStore) error {
871867
// Register issuance in the asset (group) specific universe
872868
// tree.
873-
var (
874-
universeRoot mssmt.Node
875-
err error
876-
)
877-
issuanceProof, universeRoot, err = universeUpsertProofLeaf(
869+
var err error
870+
issuanceProof, err = universeUpsertProofLeaf(
878871
ctx, dbTx, id, key, leaf, metaReveal,
879872
)
880873
if err != nil {
881874
return err
882875
}
883876

884-
// Retrieve a handle to the multiverse tree so that we can
885-
// update the tree by inserting a new issuance.
886-
multiverseTree := mssmt.NewCompactedTree(
887-
newTreeStoreWrapperTx(dbTx, multiverseNS),
888-
)
889-
890-
// Construct a leaf node for insertion into the multiverse tree.
891-
// The leaf node includes a reference to the lower tree via the
892-
// lower tree root hash.
893-
universeRootHash := universeRoot.NodeHash()
894-
assetGroupSum := universeRoot.NodeSum()
895-
896-
if id.ProofType == universe.ProofTypeIssuance {
897-
assetGroupSum = 1
898-
}
899-
900-
leafNode := mssmt.NewLeafNode(
901-
universeRootHash[:], assetGroupSum,
902-
)
903-
904-
// Use asset ID (or asset group hash) as the upper tree leaf
905-
// node key. This is the same as the asset specific universe ID.
906-
leafNodeKey := id.Bytes()
907-
908-
_, err = multiverseTree.Insert(
909-
ctx, leafNodeKey, leafNode,
910-
)
911-
if err != nil {
912-
return err
913-
}
914-
915-
// Retrieve the multiverse root and asset specific inclusion
916-
// proof for the leaf node.
917-
multiverseRoot, err := multiverseTree.Root(ctx)
918-
if err != nil {
919-
return err
920-
}
921-
922-
multiverseInclusionProof, err := multiverseTree.MerkleProof(
923-
ctx, leafNodeKey,
924-
)
925-
if err != nil {
926-
return err
927-
}
928-
929-
// Add multiverse specific fields to the issuance proof.
930-
issuanceProof.MultiverseRoot = multiverseRoot
931-
issuanceProof.MultiverseInclusionProof = multiverseInclusionProof
932-
933-
return err
877+
return nil
934878
}
935879
dbErr := b.db.ExecTx(ctx, &writeTx, execTxFunc)
936880
if dbErr != nil {
@@ -957,48 +901,14 @@ func (b *MultiverseStore) UpsertProofLeafBatch(ctx context.Context,
957901

958902
// Upsert proof leaf into the asset (group) specific universe
959903
// tree.
960-
_, universeRoot, err := universeUpsertProofLeaf(
904+
_, err := universeUpsertProofLeaf(
961905
ctx, dbTx, item.ID, item.Key, item.Leaf,
962906
item.MetaReveal,
963907
)
964908
if err != nil {
965909
return err
966910
}
967911

968-
multiverseNS, err := namespaceForProof(item.ID.ProofType)
969-
if err != nil {
970-
return err
971-
}
972-
973-
// Retrieve a handle to the multiverse tree so that we can
974-
// update the tree by inserting/updating a proof leaf.
975-
multiverseTree := mssmt.NewCompactedTree(
976-
newTreeStoreWrapperTx(dbTx, multiverseNS),
977-
)
978-
979-
// Construct a leaf node for insertion into the multiverse tree.
980-
// The leaf node includes a reference to the lower tree via the
981-
// lower tree root hash.
982-
universeRootHash := universeRoot.NodeHash()
983-
assetGroupSum := universeRoot.NodeSum()
984-
985-
if item.ID.ProofType == universe.ProofTypeIssuance {
986-
assetGroupSum = 1
987-
}
988-
989-
leafNode := mssmt.NewLeafNode(
990-
universeRootHash[:], assetGroupSum,
991-
)
992-
993-
// Use asset ID (or asset group hash) as the upper tree leaf
994-
// node key. This is the same as the asset specific universe ID.
995-
leafNodeKey := item.ID.Bytes()
996-
997-
_, err = multiverseTree.Insert(ctx, leafNodeKey, leafNode)
998-
if err != nil {
999-
return err
1000-
}
1001-
1002912
return nil
1003913
}
1004914

@@ -1074,3 +984,59 @@ func (b *MultiverseStore) DeleteUniverse(ctx context.Context,
1074984

1075985
return id.String(), dbErr
1076986
}
987+
988+
// FetchLeaves returns the set of multiverse leaves for the given proof type,
989+
// asset ID, and group key. If both asset ID and group key is nil, all leaves
990+
// for the given proof type will be returned.
991+
func (b *MultiverseStore) FetchLeaves(ctx context.Context,
992+
assetID *asset.ID, groupKey *btcec.PublicKey,
993+
proofType universe.ProofType) ([]universe.Identifier, error) {
994+
995+
var assetIDBytes, groupKeyBytes []byte
996+
if assetID != nil {
997+
assetIDBytes = assetID[:]
998+
}
999+
if groupKey != nil {
1000+
groupKeyBytes = schnorr.SerializePubKey(groupKey)
1001+
}
1002+
1003+
var (
1004+
readTx = NewBaseUniverseReadTx()
1005+
ids []universe.Identifier
1006+
)
1007+
dbErr := b.db.ExecTx(ctx, &readTx, func(q BaseMultiverseStore) error {
1008+
leaves, err := q.QueryMultiverseLeaves(
1009+
ctx, QueryMultiverseLeaves{
1010+
ProofType: proofType.String(),
1011+
AssetID: assetIDBytes,
1012+
GroupKey: groupKeyBytes,
1013+
},
1014+
)
1015+
if err != nil {
1016+
return err
1017+
}
1018+
1019+
ids = make([]universe.Identifier, len(leaves))
1020+
for i, leaf := range leaves {
1021+
ids[i].ProofType = proofType
1022+
if len(leaf.AssetID) > 0 {
1023+
copy(ids[i].AssetID[:], leaf.AssetID)
1024+
}
1025+
if len(leaf.GroupKey) > 0 {
1026+
ids[i].GroupKey, err = schnorr.ParsePubKey(
1027+
leaf.GroupKey,
1028+
)
1029+
if err != nil {
1030+
return err
1031+
}
1032+
}
1033+
}
1034+
1035+
return nil
1036+
})
1037+
if dbErr != nil {
1038+
return nil, dbErr
1039+
}
1040+
1041+
return ids, nil
1042+
}

0 commit comments

Comments
 (0)