mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
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. |
||
|---|---|---|
| .. | ||
| catalyst | ||
| downloader | ||
| ethconfig | ||
| fetcher | ||
| filters | ||
| gasestimator | ||
| gasprice | ||
| protocols | ||
| syncer | ||
| tracers | ||
| api_admin.go | ||
| api_backend.go | ||
| api_backend_test.go | ||
| api_debug.go | ||
| api_debug_test.go | ||
| api_miner.go | ||
| backend.go | ||
| dropper.go | ||
| handler.go | ||
| handler_eth.go | ||
| handler_eth_test.go | ||
| handler_snap.go | ||
| handler_test.go | ||
| peer.go | ||
| peerset.go | ||
| state_accessor.go | ||
| sync.go | ||
| sync_test.go | ||