Skip to content

feat(evm): let benchmarks raise the L1 module cache bound - #27

Merged
abmcar merged 1 commit into
feat/evm-persistent-code-cachefrom
bench/evm-module-cache-bound
Aug 29, 2026
Merged

abmcar merged 1 commit into
feat/evm-persistent-code-cachefrom
bench/evm-module-cache-bound

Conversation

@abmcar

@abmcar abmcar commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Benchmark infrastructure, not a correctness fix. Sent separately from the
exceptional-halt gas fix on purpose — different reviewer concern.

The address-keyed L1 module cache is fixed at 4096 modules. A long replay corpus
holds more unique contracts than that — 15,415 over a 1000-block mainnet window
— so every pass evicts and recompiles, and a twelve-pass timing protocol pays
that cost twelve times. Measured on a 269-block corpus, 44% of the cold-compile
pass went to recompiling contracts the cache had already seen.

That traffic is a property of the bound, not of execution, and it drowns the
signal a cross-engine comparison is trying to read. Reading the bound from
DTVM_EVM_MAX_MODULE_CACHE_SIZE lets a benchmark size the cache to its corpus
and measure execution instead of eviction.

Production is unaffected: the variable is opt-in, the default stays 4096, and an
unparseable value is warned about and ignored.

Branches from feat/evm-persistent-code-cache at 35d2f13, so the diff is this
commit alone.

The address-keyed LRU is fixed at 4096 modules. A long replay corpus holds
more unique contracts than that -- 15,415 over a 1000-block window -- so every
pass evicts and recompiles, and a twelve-pass timing protocol pays that cost
twelve times. Measured on a 269-block corpus, 44% of the cold-compile pass went
to recompiling contracts the cache had already seen.

That traffic is a property of the bound, not of execution, and it drowns the
signal a cross-engine comparison is trying to read. Reading the bound from
DTVM_EVM_MAX_MODULE_CACHE_SIZE lets a benchmark size the cache to its corpus
and measure execution instead of eviction.

Production is unaffected: the variable is opt-in and the default stays 4096.
@github-actions

Copy link
Copy Markdown

⚠️ Performance Regression Detected (interpreter)

No benchmark summary available.

@github-actions

Copy link
Copy Markdown

⚠️ Performance Regression Detected (multipass)

No benchmark summary available.

@github-actions

Copy link
Copy Markdown

⚡ Performance Regression Check Results

⚠️ Performance Regression Detected (interpreter)

No benchmark summary available.


⚠️ Performance Regression Detected (multipass)

No benchmark summary available.


@abmcar
abmcar merged commit 37b36b1 into feat/evm-persistent-code-cache Aug 29, 2026
5 of 33 checks passed
@abmcar

abmcar commented Aug 29, 2026

Copy link
Copy Markdown
Owner Author

Recording why this stayed on the fork, since GitHub auto-closed it as merged when feat/evm-persistent-code-cache advanced past it rather than through a review.

This is a benchmark affordance, not an engine fix, which is why it was split from the two correctness fixes and why those went upstream (DTVMStack#605 for the exceptional-halt gas rule, DTVMStack#604 for the null-deref misclassification) while this one did not.

It is not optional for anyone reproducing the 1000-block campaign: the corpus holds 15,415 unique contracts against a default bound of 4096, so without DTVM_EVM_MAX_MODULE_CACHE_SIZE every pass evicts and recompiles — the difference between hours and hundreds of hours. Documented on the reth side in docs/witness-replay.md §5 and §10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant