2017-08-20 02:21:36 +02:00
|
|
|
// Copyright (c) 2013-2017 The btcsuite developers
|
2013-07-18 16:49:28 +02:00
|
|
|
// Use of this source code is governed by an ISC
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
2017-08-20 02:21:36 +02:00
|
|
|
package blockchain
|
2013-07-18 16:49:28 +02:00
|
|
|
|
|
|
|
import (
|
2019-01-17 11:13:54 +01:00
|
|
|
"fmt"
|
2014-07-02 18:04:59 +02:00
|
|
|
"testing"
|
|
|
|
|
2021-12-25 01:43:16 +01:00
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
2019-01-17 11:13:54 +01:00
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
|
|
"github.com/btcsuite/btcd/wire"
|
2019-04-23 03:28:59 +02:00
|
|
|
"github.com/stretchr/testify/require"
|
2013-07-18 16:49:28 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// TestMerkle tests the BuildMerkleTreeStore API.
|
|
|
|
func TestMerkle(t *testing.T) {
|
2013-08-05 22:20:35 +02:00
|
|
|
block := btcutil.NewBlock(&Block100000)
|
2019-04-23 03:28:59 +02:00
|
|
|
calcMerkleRoot := CalcMerkleRoot(block.Transactions(), false)
|
|
|
|
merkleStoreTree := BuildMerkleTreeStore(block.Transactions(), false)
|
|
|
|
merkleStoreRoot := merkleStoreTree[len(merkleStoreTree)-1]
|
|
|
|
|
|
|
|
require.Equal(t, *merkleStoreRoot, calcMerkleRoot)
|
|
|
|
|
2013-07-18 16:49:28 +02:00
|
|
|
wantMerkle := &Block100000.Header.MerkleRoot
|
2019-04-23 03:28:59 +02:00
|
|
|
if !wantMerkle.IsEqual(&calcMerkleRoot) {
|
2013-07-18 16:49:28 +02:00
|
|
|
t.Errorf("BuildMerkleTreeStore: merkle root mismatch - "+
|
2019-04-23 03:28:59 +02:00
|
|
|
"got %v, want %v", calcMerkleRoot, wantMerkle)
|
2013-07-18 16:49:28 +02:00
|
|
|
}
|
|
|
|
}
|
2019-01-17 11:13:54 +01:00
|
|
|
|
|
|
|
func makeHashes(size int) []*chainhash.Hash {
|
|
|
|
var hashes = make([]*chainhash.Hash, size)
|
|
|
|
for i := range hashes {
|
|
|
|
hashes[i] = new(chainhash.Hash)
|
|
|
|
}
|
|
|
|
return hashes
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeTxs(size int) []*btcutil.Tx {
|
|
|
|
var txs = make([]*btcutil.Tx, size)
|
|
|
|
for i := range txs {
|
|
|
|
tx := btcutil.NewTx(wire.NewMsgTx(2))
|
|
|
|
tx.Hash()
|
|
|
|
txs[i] = tx
|
|
|
|
}
|
|
|
|
return txs
|
|
|
|
}
|
|
|
|
|
|
|
|
// BenchmarkRollingMerkle benches the RollingMerkleTree while varying the number
|
|
|
|
// of leaves pushed to the tree.
|
|
|
|
func BenchmarkRollingMerkle(b *testing.B) {
|
|
|
|
sizes := []int{
|
|
|
|
1000,
|
|
|
|
2000,
|
|
|
|
4000,
|
|
|
|
8000,
|
|
|
|
16000,
|
|
|
|
32000,
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, size := range sizes {
|
|
|
|
txs := makeTxs(size)
|
|
|
|
name := fmt.Sprintf("%d", size)
|
|
|
|
b.Run(name, func(b *testing.B) {
|
|
|
|
benchmarkRollingMerkle(b, txs)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// BenchmarkMerkle benches the BuildMerkleTreeStore while varying the number
|
|
|
|
// of leaves pushed to the tree.
|
|
|
|
func BenchmarkMerkle(b *testing.B) {
|
|
|
|
sizes := []int{
|
|
|
|
1000,
|
|
|
|
2000,
|
|
|
|
4000,
|
|
|
|
8000,
|
|
|
|
16000,
|
|
|
|
32000,
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, size := range sizes {
|
|
|
|
txs := makeTxs(size)
|
|
|
|
name := fmt.Sprintf("%d", size)
|
|
|
|
b.Run(name, func(b *testing.B) {
|
|
|
|
benchmarkMerkle(b, txs)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func benchmarkRollingMerkle(b *testing.B, txs []*btcutil.Tx) {
|
|
|
|
b.ReportAllocs()
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
CalcMerkleRoot(txs, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func benchmarkMerkle(b *testing.B, txs []*btcutil.Tx) {
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
BuildMerkleTreeStore(txs, false)
|
|
|
|
}
|
|
|
|
}
|