Ethereum Client Cache Correctness Beats Unproven Speed
A small Ethereum client patch exposes a large engineering rule: cache correctness can be measured, while performance claims need benchmarks. On July 25, a six line peer cache change appeared as a broader state trie optimization closed without merging.
The peer cache was dropping useful entries
Geth tracks transaction hashes that each network peer is already known to have. This known transaction cache helps the client avoid sending the same data to the same peer again. Its configured capacity is 32,768 hashes.
The existing logic trims the cache before adding a batch. It calculates how much room the full input batch would need, then removes entries until that room exists. That arithmetic assumes every hash in the input is new.
A set does not work that way. Adding a hash that is already present does not increase its size. If a cache holds 32,760 entries and receives 16 hashes, with 12 already present, the old logic first removes eight entries. Yet the batch contains only four new hashes, and the cache already has eight free places. No removal was required.
This is not a consensus failure. It does not alter Ethereum balances, blocks, or transaction validity. It is a local efficiency defect in how Geth remembers peer knowledge. Still, weaker memory of what a peer knows can create more redundant transaction propagation later. Small bookkeeping errors have a habit of returning as bandwidth and CPU work.
Six changed lines fix the sequence
The draft change reverses the order. Geth would first add every supplied hash to the set. It would then remove entries only while the actual set size exceeds 32,768.
That sequence makes the eviction decision from observed cardinality, not from an estimate based on batch length. Duplicate hashes become free, as set mathematics says they should. The capacity limit remains unchanged.
The patch is narrow. It changes one Go file, with three additions and three deletions in one commit. That compact scope makes the claim easy to inspect: after each call, the cache should be no larger than its limit, and existing entries should not be removed merely because the input repeats hashes.
The status matters. As of July 25, the change remained a draft and had not merged. It is a proposed correction, not behavior that operators can assume is present in a released Geth build.
State trie batching made a wider bet
A separate proposal, opened on July 2, targeted state trie work during block execution. It collected storage keys and values, then called a batch update method instead of updating each storage item separately. At the account level, it also collected addresses, account records, and code lengths before applying a batch.
The stated goal was concurrent resolution of trie nodes during the IntermediateRoot stage. The expected benefit concerned a BAL driven parallel execution path where trie prefetching is disabled. For sequential execution, the proposal expected no performance effect.
This was a larger change than the cache fix. It touched two state files, with 39 additions and 23 deletions. It also changed the order in which account updates, contract code writes, and deletions were organized. That does not make it unsafe, but it raises the burden of proof. State processing sits much closer to Ethereum’s execution core than peer cache housekeeping.
The missing number is the main result
The state trie proposal closed on July 25 without merging. Its own task list still called for an evaluation of performance in BAL mode. No measured gain was included in the staged public record.
Closure does not prove the design was wrong. It also does not reveal why the work stopped. It does establish a useful boundary: the claimed speed benefit remained unquantified, and the proposed code did not become part of the main branch through that change.
For a performance patch, an average speed number would be only a start. Useful evidence would separate sequential and parallel execution, then show results across different block shapes, storage access patterns, and database conditions. Median results matter, but tail latency and variance often decide whether parallel work is operationally useful.
The contrast is clean. The cache patch has a small, testable invariant and a direct counterexample to the old logic. The trie patch had a plausible mechanism, but its central benefit still needed measurement. Code size is not the deciding variable. Evidence is.
What to watch
The peer cache change needs boundary tests before merge. Fully repeated batches, mixed batches, empty batches, and batches larger than the cache limit should all preserve the capacity rule without avoidable eviction.
Any return of state trie batching should bring benchmark distributions, not one favorable point estimate. Results should cover both the intended parallel path and the sequential path that is supposed to remain neutral.
Finally, patch status should stay separate from production reality. Draft code is not shipped code, and a closed experiment is not a failed protocol. Ethereum client progress often comes through such small distinctions. They are less dramatic than price charts, but they are where software quality is actually decided.