@@ -12,6 +12,7 @@ import (
1212 "github.com/davecgh/go-spew/spew"
1313 "github.com/lightninglabs/taproot-assets/asset"
1414 "github.com/lightninglabs/taproot-assets/fn"
15+ "github.com/lightninglabs/taproot-assets/mssmt"
1516 "github.com/lightninglabs/taproot-assets/proof"
1617)
1718
@@ -134,6 +135,69 @@ func (a *Archive) RootNodes(ctx context.Context,
134135 return a .cfg .Multiverse .RootNodes (ctx , q )
135136}
136137
138+ // MultiverseRoot returns the root node of the multiverse for the specified
139+ // proof type. If the given list of universe IDs is non-empty, then the root
140+ // will be calculated just for those universes.
141+ func (a * Archive ) MultiverseRoot (ctx context.Context , proofType ProofType ,
142+ filterByIDs []Identifier ) (mssmt.Node , error ) {
143+
144+ log .Debugf ("Fetching multiverse root for proof type: %v" , proofType )
145+
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+ }
151+
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
157+ }
158+
159+ for _ , filterID := range filterByIDs {
160+ if id .IsEqual (filterID ) {
161+ return true
162+ }
163+ }
164+
165+ return false
166+ }
167+
168+ memStore := mssmt .NewDefaultStore ()
169+ tree := mssmt .NewCompactedTree (memStore )
170+
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 )
179+ if err != nil {
180+ return nil , fmt .Errorf ("unable to fetch universe " +
181+ "root: %w" , err )
182+ }
183+
184+ rootHash := uniRoot .NodeHash ()
185+ rootSum := uniRoot .NodeSum ()
186+
187+ if id .ProofType == ProofTypeIssuance {
188+ rootSum = 1
189+ }
190+
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+ }
196+ }
197+
198+ return tree .Root (ctx )
199+ }
200+
137201// UpsertProofLeaf attempts to upsert a proof for an asset issuance or transfer
138202// event. This method will return an error if the passed proof is invalid. If
139203// the leaf is already known, then no action is taken and the existing
0 commit comments