github.com/btcsuite/btcd@v0.24.0/blockchain/merkle_test.go (about)

     1  // Copyright (c) 2013-2017 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package blockchain
     6  
     7  import (
     8  	"fmt"
     9  	"testing"
    10  
    11  	"github.com/btcsuite/btcd/btcutil"
    12  	"github.com/btcsuite/btcd/chaincfg/chainhash"
    13  	"github.com/btcsuite/btcd/wire"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  // TestMerkle tests the BuildMerkleTreeStore API.
    18  func TestMerkle(t *testing.T) {
    19  	block := btcutil.NewBlock(&Block100000)
    20  	calcMerkleRoot := CalcMerkleRoot(block.Transactions(), false)
    21  	merkleStoreTree := BuildMerkleTreeStore(block.Transactions(), false)
    22  	merkleStoreRoot := merkleStoreTree[len(merkleStoreTree)-1]
    23  
    24  	require.Equal(t, *merkleStoreRoot, calcMerkleRoot)
    25  
    26  	wantMerkle := &Block100000.Header.MerkleRoot
    27  	if !wantMerkle.IsEqual(&calcMerkleRoot) {
    28  		t.Errorf("BuildMerkleTreeStore: merkle root mismatch - "+
    29  			"got %v, want %v", calcMerkleRoot, wantMerkle)
    30  	}
    31  }
    32  
    33  func makeHashes(size int) []*chainhash.Hash {
    34  	var hashes = make([]*chainhash.Hash, size)
    35  	for i := range hashes {
    36  		hashes[i] = new(chainhash.Hash)
    37  	}
    38  	return hashes
    39  }
    40  
    41  func makeTxs(size int) []*btcutil.Tx {
    42  	var txs = make([]*btcutil.Tx, size)
    43  	for i := range txs {
    44  		tx := btcutil.NewTx(wire.NewMsgTx(2))
    45  		tx.Hash()
    46  		txs[i] = tx
    47  	}
    48  	return txs
    49  }
    50  
    51  // BenchmarkRollingMerkle benches the RollingMerkleTree while varying the number
    52  // of leaves pushed to the tree.
    53  func BenchmarkRollingMerkle(b *testing.B) {
    54  	sizes := []int{
    55  		1000,
    56  		2000,
    57  		4000,
    58  		8000,
    59  		16000,
    60  		32000,
    61  	}
    62  
    63  	for _, size := range sizes {
    64  		txs := makeTxs(size)
    65  		name := fmt.Sprintf("%d", size)
    66  		b.Run(name, func(b *testing.B) {
    67  			benchmarkRollingMerkle(b, txs)
    68  		})
    69  	}
    70  }
    71  
    72  // BenchmarkMerkle benches the BuildMerkleTreeStore while varying the number
    73  // of leaves pushed to the tree.
    74  func BenchmarkMerkle(b *testing.B) {
    75  	sizes := []int{
    76  		1000,
    77  		2000,
    78  		4000,
    79  		8000,
    80  		16000,
    81  		32000,
    82  	}
    83  
    84  	for _, size := range sizes {
    85  		txs := makeTxs(size)
    86  		name := fmt.Sprintf("%d", size)
    87  		b.Run(name, func(b *testing.B) {
    88  			benchmarkMerkle(b, txs)
    89  		})
    90  	}
    91  }
    92  
    93  func benchmarkRollingMerkle(b *testing.B, txs []*btcutil.Tx) {
    94  	b.ReportAllocs()
    95  	b.ResetTimer()
    96  
    97  	for i := 0; i < b.N; i++ {
    98  		CalcMerkleRoot(txs, false)
    99  	}
   100  }
   101  
   102  func benchmarkMerkle(b *testing.B, txs []*btcutil.Tx) {
   103  	b.ResetTimer()
   104  	b.ReportAllocs()
   105  
   106  	for i := 0; i < b.N; i++ {
   107  		BuildMerkleTreeStore(txs, false)
   108  	}
   109  }