Skip to content

Commit 55f07b1

Browse files
Roasbeefguggero
authored andcommitted
universe: update MultiverseRoot to use a single db query
In this commit, we modify the `MultiverseRoot` method to use a single DB query. If we don't have anything to filter, then we'll fetch the global root for that proof type. Otherwise, we'll query the DB for the leaves that match the set of IDs, then insert those into our in-memory tree. This saves us N DB queries where N is the size of the set of Identifier.
1 parent d9b57fe commit 55f07b1

File tree

3 files changed

+61
-47
lines changed

3 files changed

+61
-47
lines changed

rpcserver.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,9 +3005,12 @@ func (r *rpcServer) MultiverseRoot(ctx context.Context,
30053005
err)
30063006
}
30073007

3008-
return &unirpc.MultiverseRootResponse{
3009-
MultiverseRoot: marshalMssmtNode(rootNode),
3010-
}, nil
3008+
var resp unirpc.MultiverseRootResponse
3009+
rootNode.WhenSome(func(node universe.MultiverseRoot) {
3010+
resp.MultiverseRoot = marshalMssmtNode(node)
3011+
})
3012+
3013+
return &resp, nil
30113014
}
30123015

30133016
// AssetRoots queries for the known Universe roots associated with each known

universe/base.go

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -139,63 +139,70 @@ func (a *Archive) RootNodes(ctx context.Context,
139139
// proof type. If the given list of universe IDs is non-empty, then the root
140140
// will be calculated just for those universes.
141141
func (a *Archive) MultiverseRoot(ctx context.Context, proofType ProofType,
142-
filterByIDs []Identifier) (mssmt.Node, error) {
142+
filterByIDs []Identifier) (fn.Option[MultiverseRoot], error) {
143143

144144
log.Debugf("Fetching multiverse root for proof type: %v", proofType)
145145

146-
leaveIDs, err := a.cfg.Multiverse.FetchLeaves(ctx, nil, nil, proofType)
147-
if err != nil {
148-
return nil, fmt.Errorf("unable to fetch multiverse leaves: %w",
149-
err)
150-
}
146+
none := fn.None[MultiverseRoot]()
151147

152-
// If a filter list is provided, then we'll only include the leaves
153-
// that are in the filter list.
154-
includeUniverse := func(id Identifier) bool {
155-
if len(filterByIDs) == 0 {
156-
return true
148+
// If we don't have any IDs, then we'll return the multiverse root for
149+
// the given proof type.
150+
if len(filterByIDs) == 0 {
151+
rootNode, err := a.cfg.Multiverse.MultiverseRootNode(
152+
ctx, proofType,
153+
)
154+
if err != nil {
155+
return none, err
157156
}
158157

159-
for _, filterID := range filterByIDs {
160-
if id.IsEqual(filterID) {
161-
return true
162-
}
158+
return rootNode, nil
159+
}
160+
161+
// Otherwise, we'll run the query to fetch the multiverse leaf for each
162+
// of the specified assets.
163+
uniTargets := make([]MultiverseLeafDesc, len(filterByIDs))
164+
for idx, id := range filterByIDs {
165+
if id.GroupKey != nil {
166+
uniTargets[idx] = fn.NewRight[asset.ID](*id.GroupKey)
167+
} else {
168+
uniTargets[idx] = fn.NewLeft[asset.ID, btcec.PublicKey](
169+
id.AssetID,
170+
)
163171
}
172+
}
164173

165-
return false
174+
multiverseLeaves, err := a.cfg.Multiverse.FetchLeaves(
175+
ctx, uniTargets, proofType,
176+
)
177+
if err != nil {
178+
return none, fmt.Errorf("unable to fetch multiverse "+
179+
"leaves: %w", err)
166180
}
167181

182+
// Now that we have the leaves, we'll insert them into an in-memory
183+
// tree, so we can obtain the root for this unique combination.
168184
memStore := mssmt.NewDefaultStore()
169185
tree := mssmt.NewCompactedTree(memStore)
170186

171-
for _, id := range leaveIDs {
172-
// Only include the universe if it's in the filter list (given
173-
// the filter list is non-empty).
174-
if !includeUniverse(id) {
175-
continue
176-
}
177-
178-
uniRoot, err := a.cfg.Multiverse.UniverseRootNode(ctx, id)
187+
for _, leaf := range multiverseLeaves {
188+
_, err = tree.Insert(ctx, leaf.ID.Bytes(), leaf.LeafNode)
179189
if err != nil {
180-
return nil, fmt.Errorf("unable to fetch universe "+
181-
"root: %w", err)
190+
return none, fmt.Errorf("unable to insert "+
191+
"leaf: %w", err)
182192
}
193+
}
183194

184-
rootHash := uniRoot.NodeHash()
185-
rootSum := uniRoot.NodeSum()
186-
187-
if id.ProofType == ProofTypeIssuance {
188-
rootSum = 1
189-
}
195+
customRoot, err := tree.Root(ctx)
196+
if err != nil {
197+
return none, fmt.Errorf("unable to obtain root: %w", err)
198+
}
190199

191-
uniLeaf := mssmt.NewLeafNode(rootHash[:], rootSum)
192-
_, err = tree.Insert(ctx, id.Bytes(), uniLeaf)
193-
if err != nil {
194-
return nil, fmt.Errorf("unable to insert leaf: %w", err)
195-
}
200+
multiverseRoot := MultiverseRoot{
201+
ProofType: proofType,
202+
Node: customRoot,
196203
}
197204

198-
return tree.Root(ctx)
205+
return fn.Some(multiverseRoot), nil
199206
}
200207

201208
// UpsertProofLeaf attempts to upsert a proof for an asset issuance or transfer

universe/interface.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,16 @@ type MultiverseArchive interface {
428428
UniverseLeafKeys(ctx context.Context,
429429
q UniverseLeafKeysQuery) ([]LeafKey, error)
430430

431-
// FetchLeaves returns the set of multiverse leaves for the given proof
432-
// type, asset ID, and group key. If both asset ID and group key is nil,
433-
// all leaves for the given proof type will be returned.
434-
FetchLeaves(ctx context.Context, assetID *asset.ID,
435-
groupKey *btcec.PublicKey,
436-
proofType ProofType) ([]Identifier, error)
431+
// FetchLeaves returns the set of multiverse leaves that satisfy the set
432+
// of universe targets. If the set of targets is empty, all leaves for
433+
// the given proof type will be returned.
434+
FetchLeaves(ctx context.Context, universeTargets []MultiverseLeafDesc,
435+
proofType ProofType) ([]MultiverseLeaf, error)
436+
437+
// MultiverseRootNode returns the Multiverse root node for the given
438+
// proof type.
439+
MultiverseRootNode(ctx context.Context,
440+
proofType ProofType) (fn.Option[MultiverseRoot], error)
437441
}
438442

439443
// Registrar is an interface that allows a caller to upsert a proof leaf in a

0 commit comments

Comments
 (0)