go-ethereum/eth/protocols
ozpool 3c5cca0906 eth/protocols/snap: validate trie node path length
A peer-supplied path in a GetTrieNodes request is fed straight to
accTrie.GetNode (or stTrie.GetNode), which calls compactToHex on
the path before traversing the trie. compactToHex allocates
2*len(path)+1 nibbles regardless of whether the path can possibly
match a node.

Trie keys in any Ethereum state trie are Keccak256 hashes (32 bytes
= 64 nibbles), so the longest valid compact-encoded path is 33 bytes
(64 nibbles + 1 prefix byte). Anything longer is structurally
invalid and cannot address a node.

Currently the handler accepts arbitrary-length paths up to the 10MB
message cap, performing a doomed trie traversal for each one. This
gives a peer a cheap way to amplify CPU/memory usage on the server
and silently makes geth a non-conforming reference for the devp2p
snap test suite (clients that reject long paths at the protocol
layer fail tests that pin geth's accept-and-empty-respond behavior).

Add a guard at both the account-path and storage-path branches of
ServiceGetTrieNodesQuery: if the path exceeds maxTrieNodePathLength
(33 bytes), append a nil placeholder and skip the trie walk. The
nil placeholder preserves positional alignment with the request and
matches the existing wire behavior for paths that resolve to a
non-existent node, so this is a pure CPU/allocation fix and not a
protocol change.

Adds unit tests in handler_test.go covering account paths just over
the limit and far over the limit. The storage-path branch shares the
same guard but exercising it requires a chain with existing accounts;
that coverage is left as a follow-up.

Refs #34853.
2026-04-30 15:44:48 +05:30
..
eth core, eth/protocols/snap: Snap/2 Protocol + BAL Serving (#34083) 2026-04-03 14:10:32 +08:00
snap eth/protocols/snap: validate trie node path length 2026-04-30 15:44:48 +05:30