Per review on #34854:
- Refactor the path-length guard to if-else style (no append-nil-and-break);
the trie traversal lives in the else branch.
- Tighten maxTrieNodePathLength from 33 to 32 bytes. The theoretical
compact-encoded upper bound is 33 bytes (64 nibbles + 1 prefix byte), but
in an MPT the value node is always embedded in its parent and is never
addressed as a standalone node, so the hexary path length is at most 63
nibbles and the compact encoding never exceeds 32 bytes.
- Update test comment to reflect the 32-byte real-world cap.
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.
This PR updates the BAL structure definition to the latest the spec,
- Balance has been changed from [16]byte to uint256
- Storage key and value has been changed from [32]byte to uint256
- BlockAccessList has been changed from a struct to a slice of
AccountChanges
- TxIndex has been changed from uint16 to uint32
This PR refactors the encoding rules for `AccessListsPacket` in the wire
protocol. Specifically:
- The response is now encoded as a list of `rlp.RawValue`
- `rlp.EmptyString` is used as a placeholder for unavailable BAL objects