Add EVM storage read-ahead for sequential SLOAD#36
Conversation
Batch sequential SLOAD lookups via CMerkleTree.get_range/3 and return multiple key/value pairs per gs response so array scans like Members() avoid one IPC per slot. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a storage read-ahead mechanism for the EVM by implementing a new get_range function in the Merkle tree NIF and Elixir wrapper. This allows fetching multiple sequential storage keys in a single roundtrip, which are then cached on the C++ host side. Feedback on these changes highlights several critical improvements: a potential protocol desynchronization bug where a read-ahead count of 256 overflows an 8-bit integer to 0 (suggesting a cap of 254 instead of 255); unnecessary overhead in merkletree_get_item from using the new range lookup instead of direct lookup; a missing guard clause in Elixir's get_range/3 to enforce the maximum count of 256; and an optimization opportunity in get_range_entries to avoid an expensive vector copy by using std::move.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Cap read-ahead at 254 so the uint8 pair count cannot wrap, restore direct get_item for single lookups, move keys in get_range_entries, and guard get_range/3 count <= 256. Co-authored-by: Cursor <cursoragent@cursor.com>
Use get_item for single lookups, iolist gs responses, zero-init host ret, simplify NIF range entries, and add boundary tests for read-ahead 0 and 254. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
CMerkleTree.get_range/3NIF that fetches sequential storage slots in one call (get_item/2delegates ton=1)gsport response to return the requested key plus read-ahead followers (default 10, configurable viaEVM_STORAGE_READ_AHEAD)gsresponseTest plan
mix test test/cmerkletree_test.exs test/evm_storage_readahead_test.exseth_call(Members()) and confirm reduced RPC latencyEVM_STORAGE_READ_AHEAD=0(single-slot) vs16if neededMade with Cursor