Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cl/cltypes/solid/byte_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/erigontech/erigon/common/clonable"
"github.com/erigontech/erigon/common/hexutil"
"github.com/erigontech/erigon/common/length"
"github.com/erigontech/erigon/common/math"
)

// ByteListSSZ is a variable-length SSZ byte list (ByteList[N]) with a
Expand Down Expand Up @@ -103,7 +104,7 @@ func (b *ByteListSSZ) HashSSZ() ([32]byte, error) {
chunkLimit := (b.limit + 31) / 32

// Pack the data into 32-byte chunks and merkleize with the chunk limit.
leafCount := merkle_tree.NextPowerOfTwo(uint64((len(b.data) + 31) / length.Hash))
leafCount := math.NextPowerOfTwo(uint64((len(b.data) + 31) / length.Hash))
if leafCount == 0 {
leafCount = 1
}
Expand Down
4 changes: 2 additions & 2 deletions cl/cltypes/solid/hash_vector.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ package solid
import (
"encoding/json"

"github.com/erigontech/erigon/cl/merkle_tree"
"github.com/erigontech/erigon/common"
"github.com/erigontech/erigon/common/clonable"
"github.com/erigontech/erigon/common/length"
"github.com/erigontech/erigon/common/math"
"github.com/erigontech/erigon/common/ssz"
)

Expand All @@ -34,7 +34,7 @@ func NewHashVector(s int) HashVectorSSZ {
return &hashVector{
u: &hashList{
u: make([]byte, s*length.Hash),
c: int(merkle_tree.NextPowerOfTwo(uint64(s))),
c: int(math.NextPowerOfTwo(uint64(s))),
l: s,
},
}
Expand Down
3 changes: 2 additions & 1 deletion cl/cltypes/solid/vector.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/erigontech/erigon/cl/merkle_tree"
ssz2 "github.com/erigontech/erigon/cl/ssz"
"github.com/erigontech/erigon/common/clonable"
"github.com/erigontech/erigon/common/math"
"github.com/erigontech/erigon/common/ssz"
)

Expand Down Expand Up @@ -248,7 +249,7 @@ func (v *VectorSSZ[T]) HashSSZ() ([32]byte, error) {
// Initialize MerkleTree if not already done
if v.merkleTree == nil {
// For vectors, the limit should be the next power of 2 for proper merkleization
limit := merkle_tree.NextPowerOfTwo(uint64(len(v.items)))
limit := math.NextPowerOfTwo(uint64(len(v.items)))
v.merkleTree = &merkle_tree.MerkleTree{}
v.merkleTree.Initialize(len(v.items), merkle_tree.OptimalMaxTreeCacheDepth, func(idx int, out []byte) {
hash, err := v.items[idx].HashSSZ()
Expand Down
3 changes: 2 additions & 1 deletion cl/cltypes/solid/vector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/erigontech/erigon/cl/merkle_tree"
"github.com/erigontech/erigon/common"
"github.com/erigontech/erigon/common/math"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -497,7 +498,7 @@ func TestMerkleizeVector_Direct(t *testing.T) {
t.Logf("hZero: %x", hZero)

// For proper merkleization, length should be next power of 2
vectorLength := merkle_tree.NextPowerOfTwo(3) // 3 -> 4
vectorLength := math.NextPowerOfTwo(3) // 3 -> 4

// Test 1: [h1, h1, hZero]
leaves1 := [][32]byte{h1, h1, hZero}
Expand Down
7 changes: 4 additions & 3 deletions cl/merkle_tree/merkle_root.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/erigontech/erigon/cl/utils"
"github.com/erigontech/erigon/common"
"github.com/erigontech/erigon/common/length"
"github.com/erigontech/erigon/common/math"
"github.com/erigontech/erigon/common/ssz"
)

Expand All @@ -44,7 +45,7 @@ func HashTreeRoot(schema ...any) ([32]byte, error) {
return [32]byte{}, errors.New("empty schema")
}
var stack [maxStackLeaves * length.Hash]byte // stack-allocation for most of cases
size := NextPowerOfTwo(uint64(len(schema) * length.Hash))
size := math.NextPowerOfTwo(uint64(len(schema) * length.Hash))
var leaves []byte
if size <= uint64(len(stack)) {
leaves = stack[:size]
Expand Down Expand Up @@ -142,15 +143,15 @@ func MerkleRootFromFlatLeaves(leaves []byte, out []byte) (err error) {
copy(out, leaves)
return
}
return globalHasher.merkleizeTrieLeavesFlat(leaves, out, NextPowerOfTwo(uint64((len(leaves)+31)/32)))
return globalHasher.merkleizeTrieLeavesFlat(leaves, out, math.NextPowerOfTwo(uint64((len(leaves)+31)/32)))
}

func MerkleRootFromFlatFromIntermediateLevel(nodes []byte, out []byte, leavesLen, intermediateLevel int) (err error) {
if len(nodes) <= 32 {
copy(out, nodes)
return
}
return globalHasher.merkleizeTrieLeavesFlatWithStart(nodes, out, NextPowerOfTwo(uint64((leavesLen+31)/32)), uint64(intermediateLevel))
return globalHasher.merkleizeTrieLeavesFlatWithStart(nodes, out, math.NextPowerOfTwo(uint64((leavesLen+31)/32)), uint64(intermediateLevel))
}

func MerkleRootFromFlatFromIntermediateLevelWithLimit(nodes []byte, out []byte, limit, intermediateLevel int) (err error) {
Expand Down
3 changes: 2 additions & 1 deletion cl/merkle_tree/primitives.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/erigontech/erigon/common"
"github.com/erigontech/erigon/common/length"
"github.com/erigontech/erigon/common/math"
)

// Uint64Root retrieves the root hash of a uint64 value by converting it to a byte array and returning it as a hash.
Expand All @@ -31,7 +32,7 @@ func Uint64Root(val uint64) common.Hash {
}

func BytesRoot(b []byte) (out [32]byte, err error) {
leafCount := NextPowerOfTwo(uint64((len(b) + 31) / length.Hash))
leafCount := math.NextPowerOfTwo(uint64((len(b) + 31) / length.Hash))
leaves := make([]byte, leafCount*length.Hash)
copy(leaves, b)
if err = MerkleRootFromFlatLeaves(leaves, leaves); err != nil {
Expand Down
17 changes: 0 additions & 17 deletions cl/merkle_tree/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,6 @@

package merkle_tree

func NextPowerOfTwo(n uint64) uint64 {
if n == 0 {
return 1
}
// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
n--
n |= n >> 1
n |= n >> 2
n |= n >> 4
n |= n >> 8
n |= n >> 16
n |= n >> 32
n++

return n
}

// 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.
Expand Down
9 changes: 9 additions & 0 deletions common/math/integer.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,12 @@ func SafeAdd(x, y uint64) (uint64, bool) {
sum, carryOut := bits.Add64(x, y, 0)
return sum, carryOut != 0
}

// NextPowerOfTwo returns the least power of two at or above n, and 1 for
// n == 0; n above 1<<63 wraps to 0.
func NextPowerOfTwo(n uint64) uint64 {
if n <= 1 {
return 1
}
return uint64(1) << bits.Len64(n-1)
}
10 changes: 10 additions & 0 deletions common/math/integer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,13 @@ func TestAbsoluteDifference(t *testing.T) {
assert.Equal(t, AbsoluteDifference(x1, x2), x1-x2)
assert.Equal(t, AbsoluteDifference(x2, x1), x1-x2)
}

func TestNextPowerOfTwo(t *testing.T) {
for _, tc := range []struct{ in, want uint64 }{
{0, 1}, {1, 1}, {2, 2}, {3, 4}, {4, 4}, {5, 8},
{1<<24 - 1, 1 << 24}, {1 << 24, 1 << 24},
{1 << 63, 1 << 63}, {1<<63 + 1, 0}, {^uint64(0), 0},
} {
assert.Equal(t, tc.want, NextPowerOfTwo(tc.in), "n=%d", tc.in)
}
}
13 changes: 3 additions & 10 deletions execution/cache/generic_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package cache

import (
"bytes"
"math/bits"
"runtime"
"sync"
"sync/atomic"
Expand All @@ -31,6 +30,7 @@ import (
"github.com/erigontech/erigon/common/cachebudget"
"github.com/erigontech/erigon/common/log/v3"
"github.com/erigontech/erigon/common/maphash"
"github.com/erigontech/erigon/common/math"
"github.com/erigontech/erigon/execution/cache/coherence"
)

Expand Down Expand Up @@ -122,17 +122,10 @@ type GenericCache[T any] struct {

func u64identity(k uint64) uint32 { return uint32(k) }

func nextPow2(v uint32) uint32 {
if v <= 1 {
return 1
}
return 1 << bits.Len32(v-1)
}

// initialShardCount starts a lineage at ~64 entries per shard (freelru's own
// small-cache geometry), bounded by ceil.
func initialShardCount(capacity, ceil uint32) uint32 {
return min(nextPow2(capacity/64), ceil)
return min(uint32(math.NextPowerOfTwo(uint64(capacity/64))), ceil)
}

const (
Expand Down Expand Up @@ -189,7 +182,7 @@ func newGenericCacheEntries[T any](capacityBytes datasize.ByteSize, capacityEntr
sizeFunc: sizeFunc,
}
c.curCap.Store(capacityEntries)
c.shardCeil = nextPow2(uint32(runtime.GOMAXPROCS(0) * 16))
c.shardCeil = uint32(math.NextPowerOfTwo(uint64(runtime.GOMAXPROCS(0) * 16)))
c.shardCount = initialShardCount(capacityEntries, c.shardCeil)
// Before any unwind every entry predates the (nonexistent) floor, so all
// reads are valid; the floor only drops once an unwind happens.
Expand Down
3 changes: 2 additions & 1 deletion polygon/bor/bor.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
"github.com/erigontech/erigon/common/empty"
"github.com/erigontech/erigon/common/length"
"github.com/erigontech/erigon/common/log/v3"
math2 "github.com/erigontech/erigon/common/math"
"github.com/erigontech/erigon/db/dbservices"
"github.com/erigontech/erigon/db/kv"
"github.com/erigontech/erigon/db/rawdb"
Expand Down Expand Up @@ -1180,7 +1181,7 @@ func (c *Bor) GetRootHash(ctx context.Context, tx kv.Tx, start, end uint64) (str
}

func ComputeHeadersRootHash(blockHeaders []*types.Header) ([]byte, error) {
headers := make([][32]byte, NextPowerOfTwo(uint64(len(blockHeaders))))
headers := make([][32]byte, math2.NextPowerOfTwo(uint64(len(blockHeaders))))
for i := range blockHeaders {
blockHeader := blockHeaders[i]
headers[i] = crypto.Keccak256Hash(AppendBytes32(
Expand Down
17 changes: 0 additions & 17 deletions polygon/bor/merkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,6 @@ func AppendBytes32(data ...[]byte) []byte {
return result
}

func NextPowerOfTwo(n uint64) uint64 {
if n == 0 {
return 1
}
// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
n--
n |= n >> 1
n |= n >> 2
n |= n >> 4
n |= n >> 8
n |= n >> 16
n |= n >> 32
n++

return n
}

func ConvertTo32(input []byte) (output [32]byte, err error) {
l := len(input)
if l > 32 || l == 0 {
Expand Down
Loading