mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-03 09:37:38 +00:00
7c43cb532c
Most notably use of more than a single thread. there is still potential for me but there are more important things for now to work on.
59 lines
1.5 KiB
Go
59 lines
1.5 KiB
Go
package merkle_tree
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/ledgerwatch/erigon/cl/utils"
|
|
"github.com/prysmaticlabs/gohashtree"
|
|
)
|
|
|
|
// merkleizeTrieLeaves returns intermediate roots of given leaves.
|
|
func merkleizeTrieLeaves(leaves [][32]byte) ([32]byte, error) {
|
|
layer := make([][32]byte, len(leaves)/2)
|
|
for len(leaves) > 1 {
|
|
if !utils.IsPowerOf2(uint64(len(leaves))) {
|
|
return [32]byte{}, fmt.Errorf("hash layer is a non power of 2: %d", len(leaves))
|
|
}
|
|
if err := gohashtree.Hash(layer, leaves); err != nil {
|
|
return [32]byte{}, err
|
|
}
|
|
leaves = layer[:len(leaves)/2]
|
|
}
|
|
return leaves[0], nil
|
|
}
|
|
|
|
func MerkleRootFromLeaves(leaves [][32]byte) ([32]byte, error) {
|
|
if len(leaves) == 0 {
|
|
return [32]byte{}, errors.New("zero leaves provided")
|
|
}
|
|
if len(leaves) == 1 {
|
|
return leaves[0], nil
|
|
}
|
|
hashLayer := leaves
|
|
return merkleizeTrieLeaves(hashLayer)
|
|
}
|
|
|
|
// getDepth returns the depth of a merkle tree with a given number of nodes.
|
|
// The depth is defined as the number of levels in the tree, with the root
|
|
// node at level 0 and each child node at a level one greater than its parent.
|
|
// If the number of nodes is less than or equal to 1, the depth is 0.
|
|
func getDepth(v uint64) uint8 {
|
|
// If there are 0 or 1 nodes, the depth is 0.
|
|
if v <= 1 {
|
|
return 0
|
|
}
|
|
|
|
// Initialize the depth to 0.
|
|
depth := uint8(0)
|
|
|
|
// Divide the number of nodes by 2 until it is less than or equal to 1.
|
|
// The number of iterations is the depth of the tree.
|
|
for v > 1 {
|
|
v >>= 1
|
|
depth++
|
|
}
|
|
|
|
return depth
|
|
}
|