merkle tree: fix the implementation and add a test case
Merkle tree requires a full binary tree, which means the number of node is power of 2 and the level of the tree is log(N) instead of N/2. This patch duplicate the node to a power of 2 number and correct the level calculation. Besides it adds a test case with 6 nodes. Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
This commit is contained in:
parent
c0accf31e0
commit
5e43c770ee
|
@ -20,7 +20,8 @@ type MerkleNode struct {
|
|||
func NewMerkleTree(data [][]byte) *MerkleTree {
|
||||
var nodes []MerkleNode
|
||||
|
||||
if len(data)%2 != 0 {
|
||||
// append node until number is power of 2
|
||||
for (len(data) & (len(data) - 1)) != 0 {
|
||||
data = append(data, data[len(data)-1])
|
||||
}
|
||||
|
||||
|
@ -29,7 +30,8 @@ func NewMerkleTree(data [][]byte) *MerkleTree {
|
|||
nodes = append(nodes, *node)
|
||||
}
|
||||
|
||||
for i := 0; i < len(data)/2; i++ {
|
||||
// up level until there is only 1 node
|
||||
for len(nodes) > 1 {
|
||||
var newLevel []MerkleNode
|
||||
|
||||
for j := 0; j < len(nodes); j += 2 {
|
||||
|
|
|
@ -73,3 +73,41 @@ func TestNewMerkleTree(t *testing.T) {
|
|||
|
||||
assert.Equal(t, rootHash, fmt.Sprintf("%x", mTree.RootNode.Data), "Merkle tree root hash is correct")
|
||||
}
|
||||
|
||||
func TestNewMerkleTree8(t *testing.T) {
|
||||
data := [][]byte{
|
||||
[]byte("node1"),
|
||||
[]byte("node2"),
|
||||
[]byte("node3"),
|
||||
[]byte("node4"),
|
||||
[]byte("node5"),
|
||||
[]byte("node6"),
|
||||
}
|
||||
// Level 0
|
||||
n01 := NewMerkleNode(nil, nil, data[0])
|
||||
n02 := NewMerkleNode(nil, nil, data[1])
|
||||
n03 := NewMerkleNode(nil, nil, data[2])
|
||||
n04 := NewMerkleNode(nil, nil, data[3])
|
||||
n05 := NewMerkleNode(nil, nil, data[4])
|
||||
n06 := NewMerkleNode(nil, nil, data[5])
|
||||
n07 := NewMerkleNode(nil, nil, data[5])
|
||||
n08 := NewMerkleNode(nil, nil, data[5])
|
||||
|
||||
// Level 1
|
||||
n11 := NewMerkleNode(n01, n02, nil)
|
||||
n12 := NewMerkleNode(n03, n04, nil)
|
||||
n13 := NewMerkleNode(n05, n06, nil)
|
||||
n14 := NewMerkleNode(n07, n08, nil)
|
||||
|
||||
// Level 2
|
||||
n21 := NewMerkleNode(n11, n12, nil)
|
||||
n22 := NewMerkleNode(n13, n14, nil)
|
||||
|
||||
// Level 3
|
||||
n31 := NewMerkleNode(n21, n22, nil)
|
||||
|
||||
rootHash := fmt.Sprintf("%x", n31.Data)
|
||||
mTree := NewMerkleTree(data)
|
||||
|
||||
assert.Equal(t, rootHash, fmt.Sprintf("%x", mTree.RootNode.Data), "Merkle tree root hash is correct")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue