Skip to content

Commit 2ff3cdf

Browse files
ffranrdarioAnongba
authored andcommitted
supplycommit: add ExtractSupplyLeavesBlockHeaders helper function
Add a helper function, ExtractSupplyLeavesBlockHeaders, to extract block headers from a set of supply leaves. This will be used in subsequent commits to populate block header data in RPC response messages.
1 parent 040ea5e commit 2ff3cdf

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

universe/supplycommit/util.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package supplycommit
22

33
import (
4+
"bytes"
45
"context"
56
"errors"
67
"fmt"
78

9+
"github.com/btcsuite/btcd/wire"
810
"github.com/lightninglabs/taproot-assets/address"
911
"github.com/lightninglabs/taproot-assets/asset"
12+
"github.com/lightninglabs/taproot-assets/proof"
13+
"github.com/lightninglabs/taproot-assets/tapgarden"
1014
"github.com/lightningnetwork/lnd/fn/v2"
1115
)
1216

@@ -163,3 +167,68 @@ func IsSupplySupported(ctx context.Context, assetLookup AssetLookup,
163167

164168
return true, nil
165169
}
170+
171+
// ExtractSupplyLeavesBlockHeaders is a helper method which extracts the block
172+
// headers from the supply leaves. The returned map is keyed by block height.
173+
func ExtractSupplyLeavesBlockHeaders(ctx context.Context,
174+
chain tapgarden.ChainBridge,
175+
supplyLeaves SupplyLeaves) (map[uint32]wire.BlockHeader, error) {
176+
177+
blockHeaders := make(map[uint32]wire.BlockHeader)
178+
179+
// Extract block headers from issuance leaves.
180+
for idx := range supplyLeaves.IssuanceLeafEntries {
181+
leaf := supplyLeaves.IssuanceLeafEntries[idx]
182+
183+
// Sparse decode the block header from the issuance proof.
184+
var blockHeader wire.BlockHeader
185+
err := proof.SparseDecode(
186+
bytes.NewReader(leaf.IssuanceProof.RawProof),
187+
proof.BlockHeaderRecord(&blockHeader),
188+
)
189+
if err != nil {
190+
return nil, fmt.Errorf("unable to sparse decode "+
191+
"block header from proof: %w", err)
192+
}
193+
194+
blockHeaders[leaf.BlockHeight()] = blockHeader
195+
}
196+
197+
// Extract block headers from burn leaves.
198+
for idx := range supplyLeaves.BurnLeafEntries {
199+
leaf := supplyLeaves.BurnLeafEntries[idx]
200+
201+
if leaf.BurnProof == nil {
202+
return nil, fmt.Errorf("burn proof is nil for burn " +
203+
"leaf")
204+
}
205+
206+
blockHeader := leaf.BurnProof.BlockHeader
207+
blockHeaders[leaf.BlockHeight()] = blockHeader
208+
}
209+
210+
// Extract block headers from ignore leaves.
211+
for idx := range supplyLeaves.IgnoreLeafEntries {
212+
leaf := supplyLeaves.IgnoreLeafEntries[idx]
213+
blockHeight := leaf.BlockHeight()
214+
215+
// If we already have the block header for this height, skip
216+
// fetching it again from the chain backend.
217+
if _, ok := blockHeaders[blockHeight]; ok {
218+
continue
219+
}
220+
221+
blockHeader, err := chain.GetBlockHeaderByHeight(
222+
ctx, int64(blockHeight),
223+
)
224+
if err != nil {
225+
return nil, fmt.Errorf("unable to fetch block "+
226+
"header at height %d: %w",
227+
blockHeight, err)
228+
}
229+
230+
blockHeaders[blockHeight] = *blockHeader
231+
}
232+
233+
return blockHeaders, nil
234+
}

0 commit comments

Comments
 (0)