triedb/pathdb: use scheme-appropriate hasher in diskLayer.node

Addresses review finding I1.

diskLayer.node() returned crypto.Keccak256Hash(blob) as the hash for
ALL trie nodes regardless of the database's scheme. For the binary trie
the correct hash is sha256 via binaryNodeHasher. The wrong hash was
masked by noHashCheck=true in pathdb.NodeReader for the bintrie path,
but HistoricalNodeReader.Node (which does NOT set noHashCheck) would
never match the returned hash, silently falling through to the slow
freezer-backed read on every call.

Fix: replace crypto.Keccak256Hash(blob) with dl.db.hasher(blob) at
both the clean-cache-hit and disk-read return paths. The hasher is
already set to the correct function (merkleNodeHasher or
binaryNodeHasher) at Database construction time.
This commit is contained in:
CPerezz 2026-04-09 11:29:31 +02:00
parent 21f243ff8a
commit 149277be3c
No known key found for this signature in database
GPG key ID: 62045F34B97177DD

View file

@ -25,7 +25,6 @@ import (
"github.com/VictoriaMetrics/fastcache"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
)
@ -141,7 +140,14 @@ func (dl *diskLayer) node(owner common.Hash, path []byte, depth int) ([]byte, co
if blob := dl.nodes.Get(nil, key); len(blob) > 0 {
cleanNodeHitMeter.Mark(1)
cleanNodeReadMeter.Mark(int64(len(blob)))
return blob, crypto.Keccak256Hash(blob), nodeLoc{loc: locCleanCache, depth: depth}, nil
// Use the scheme-appropriate hasher (keccak256 for merkle,
// sha256-via-bintrie for binary trie). Prior to A5 this was
// hard-coded to crypto.Keccak256Hash, which returned the wrong
// hash for bintrie nodes — masked by noHashCheck=true in the
// verkle NodeReader, but silently wrong for any caller without
// that flag (e.g. HistoricalNodeReader.Node).
h, _ := dl.db.hasher(blob)
return blob, h, nodeLoc{loc: locCleanCache, depth: depth}, nil
}
cleanNodeMissMeter.Mark(1)
}
@ -161,7 +167,8 @@ func (dl *diskLayer) node(owner common.Hash, path []byte, depth int) ([]byte, co
dl.nodes.Set(key, blob)
cleanNodeWriteMeter.Mark(int64(len(blob)))
}
return blob, crypto.Keccak256Hash(blob), nodeLoc{loc: locDiskLayer, depth: depth}, nil
h, _ := dl.db.hasher(blob)
return blob, h, nodeLoc{loc: locDiskLayer, depth: depth}, nil
}
// account directly retrieves the account RLP associated with a particular