trie/bintrie: revert sha256 helper + parallelHashDepth constant

Gballet asked (comment 3099953085) to leave the sha256Sum256 / constant
parallelHashDepth optimisation out of this PR: it's an orthogonal
microbenchmark concern that should be revisited post-group-depth under
Go 1.26.

- Delete the sha256Sum256 helper from hasher.go.
- Delete the const parallelHashDepth = 4 from hasher.go.
- Restore master's dynamic parallelDepth() helper in store_commit.go
  (copy verbatim — min(bits.Len(NumCPU), 8)).
- In hashInternal's shallow-parallel branch, call sha256.Sum256 directly
  (std-lib, stack-allocated [32]byte; common.Hash is a type alias for
  [32]byte so no conversion needed).
- In hashInternal's deep-sequential branch, use the pooled newSha256 /
  returnSha256 hasher (matches master's internal_node.go:170-185).

Intentional trade-off: the deep branch now re-introduces per-hash
sync.Pool Get/Put plus a 32-byte h.Sum(nil) allocation. Zero regression
vs master; foregoes the arena's proposed stack-based hashing until
Go 1.26 + post-group-depth benchmarks.
This commit is contained in:
CPerezz 2026-04-18 18:50:20 +02:00
parent 2d44d8a4b6
commit 3885e539b7
No known key found for this signature in database
GPG key ID: 62045F34B97177DD
2 changed files with 22 additions and 16 deletions

View file

@ -37,11 +37,3 @@ func newSha256() hash.Hash {
func returnSha256(h hash.Hash) { func returnSha256(h hash.Hash) {
sha256Pool.Put(h) sha256Pool.Put(h)
} }
// sha256Sum256 computes a sha256 digest and returns it as a common.Hash.
func sha256Sum256(data []byte) [32]byte {
return sha256.Sum256(data)
}
// parallelHashDepth controls the tree hashing parallelization depth threshold
const parallelHashDepth = 4

View file

@ -17,9 +17,11 @@
package bintrie package bintrie
import ( import (
"crypto/sha256"
"errors" "errors"
"fmt" "fmt"
"math/bits" "math/bits"
"runtime"
"sync" "sync"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -46,19 +48,26 @@ func (s *NodeStore) computeHash(ref nodeRef) common.Hash {
} }
} }
// parallelDepth returns the tree depth below which hashInternal spawns
// goroutines for shallow-depth parallelism.
func parallelDepth() int {
return min(bits.Len(uint(runtime.NumCPU())), 8)
}
// hashInternal hashes an InternalNode and caches the result. // hashInternal hashes an InternalNode and caches the result.
// //
// At shallow depths (< parallelHashDepth) the left subtree is hashed in a // At shallow depths (< parallelDepth()) the left subtree is hashed in a
// goroutine while the right subtree is hashed inline, then the two digests // goroutine while the right subtree is hashed inline, then the two digests
// are combined. Below that threshold the goroutine spawn cost outweighs the // are combined. Below that threshold the goroutine spawn cost outweighs the
// hashing work, so deeper nodes hash both children sequentially. // hashing work, so deeper nodes hash both children sequentially via the
// pooled hasher.
func (s *NodeStore) hashInternal(idx uint32) common.Hash { func (s *NodeStore) hashInternal(idx uint32) common.Hash {
node := s.getInternal(idx) node := s.getInternal(idx)
if !node.mustRecompute { if !node.mustRecompute {
return node.hash return node.hash
} }
if node.depth < parallelHashDepth { if int(node.depth) < parallelDepth() {
var input [64]byte var input [64]byte
var lh common.Hash var lh common.Hash
var wg sync.WaitGroup var wg sync.WaitGroup
@ -75,21 +84,26 @@ func (s *NodeStore) hashInternal(idx uint32) common.Hash {
} }
wg.Wait() wg.Wait()
copy(input[:32], lh[:]) copy(input[:32], lh[:])
node.hash = sha256Sum256(input[:]) node.hash = sha256.Sum256(input[:])
node.mustRecompute = false node.mustRecompute = false
return node.hash return node.hash
} }
var input [64]byte h := newSha256()
defer returnSha256(h)
if !node.left.IsEmpty() { if !node.left.IsEmpty() {
lh := s.computeHash(node.left) lh := s.computeHash(node.left)
copy(input[:32], lh[:]) h.Write(lh[:])
} else {
h.Write(make([]byte, HashSize))
} }
if !node.right.IsEmpty() { if !node.right.IsEmpty() {
rh := s.computeHash(node.right) rh := s.computeHash(node.right)
copy(input[32:], rh[:]) h.Write(rh[:])
} else {
h.Write(make([]byte, HashSize))
} }
node.hash = sha256Sum256(input[:]) node.hash = common.BytesToHash(h.Sum(nil))
node.mustRecompute = false node.mustRecompute = false
return node.hash return node.hash
} }