From 9e073fb367372be24a99f259655b8f096b3fcecf Mon Sep 17 00:00:00 2001 From: Darren Kellenschwiler Date: Fri, 1 Dec 2023 14:24:39 -0600 Subject: [PATCH] fix: only include the hashes for the txid we're interested in Previously this function returned a BUMP of the whole tree which quickly exhausts ARC resources when there are thousands in memory. It should be one txid per BUMP, which is significantly less data. Signed-off-by: Darren Kellenschwiler --- bump.go | 11 +++++++++++ bump_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/bump.go b/bump.go index 6eabc61..bf1b4ab 100644 --- a/bump.go +++ b/bump.go @@ -233,6 +233,7 @@ func NewBUMPFromMerkleTreeAndIndex(blockHeight uint64, merkleTree []*chainhash.H return nil, errors.New("merkle tree is empty") } + // these are the offsets for the txid we're interested in. offsets := make([]uint64, treeHeight) for i := 0; i < treeHeight; i++ { if txIndex>>uint64(i)&1 == 0 { @@ -251,6 +252,16 @@ func NewBUMPFromMerkleTreeAndIndex(blockHeight uint64, merkleTree []*chainhash.H bump.Path = append(bump.Path, leaves) for offset := 0; offset < numOfHashes; offset++ { o := uint64(offset) + // only include the hashes for the txid we're interested in. + if height == 0 { + if o != txIndex && o != offsets[height] { + continue + } + } else { + if o != offsets[height] { + continue + } + } thisLeaf := leaf{Offset: &o} hash := merkleTree[levelOffset+offset] if hash.IsEqual(nil) { diff --git a/bump_test.go b/bump_test.go index 2d908a8..4cdc46a 100644 --- a/bump_test.go +++ b/bump_test.go @@ -1,6 +1,7 @@ package bc import ( + "math" "testing" "github.com/libsv/go-p2p/chaincfg/chainhash" @@ -168,3 +169,27 @@ func TestTxids(t *testing.T) { txids := bump.Txids() require.Equal(t, []string{testnetBlockExample[0]}, txids) } + +func TestOnlySpecifiedPathsStored(t *testing.T) { + chainHashBlock := make([]*chainhash.Hash, 0) + for _, txid := range blockTxExample { + hash, err := chainhash.NewHashFromStr(txid) + require.NoError(t, err) + chainHashBlock = append(chainHashBlock, hash) + } + merkles, err := BuildMerkleTreeStoreChainHash(chainHashBlock) + require.NoError(t, err) + + for idx := range blockTxExample { + bump, err := NewBUMPFromMerkleTreeAndIndex(1575794, merkles, uint64(idx)) + require.NoError(t, err) + totalHashes := 0 + for _, level := range bump.Path { + totalHashes += len(level) + } + // number of levels plus the txid itself. + l := int(math.Log2(float64(len(blockTxExample)))) + 1 + require.Equal(t, l, totalHashes) + } + +}