From 149277be3c9c8eedd22be35d65120cece00ccf86 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Thu, 9 Apr 2026 11:29:31 +0200 Subject: [PATCH] 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. --- triedb/pathdb/disklayer.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index 428c011c8c..687d1a0042 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -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