Skip to content

feat(engine): expose engine caches to SDK consumers#23049

Closed
yongkangc wants to merge 10 commits into
mainfrom
yk/reth-505-engine-caches-facade-20260316-055813
Closed

feat(engine): expose engine caches to SDK consumers#23049
yongkangc wants to merge 10 commits into
mainfrom
yk/reth-505-engine-caches-facade-20260316-055813

Conversation

@yongkangc
Copy link
Copy Markdown
Contributor

@yongkangc yongkangc commented Mar 16, 2026

Closes RETH-505

Problem
Engine-tree caches (execution cache, sparse trie, precompile cache) are created inside BasicEngineValidator and PayloadProcessor. The launcher has no handle to them, so payload builders can't reuse engine caches like the precompile cache.

Solution
New EngineSharedCaches<Evm> struct with pub fields. The launcher creates it and passes it through build_tree_validator.

Before

Payload builders have no access to engine caches. To share them, an SDK consumer would have to:

  1. Skip BasicEngineValidator entirely and reimplement the validator from scratch
  2. Create the caches externally and wire them through a custom EngineValidatorBuilder impl
  3. Manually thread those caches to their payload builder
graph TD
    L[EngineNodeLauncher] -->|build_tree_validator| BEV[BasicEngineValidator]
    BEV -->|"new(precompile_cache_map)"| PP[PayloadProcessor]
    L -->|no cache handle| PB[PayloadBuilder]

    BEV -.->|creates internally| PCM1["PrecompileCacheMap::default()"]
    PP -.->|creates internally| EC["PayloadExecutionCache::default()"]
    PP -.->|creates internally| SST["SharedPreservedSparseTrie::default()"]

    style PCM1 fill:#f96,stroke:#333
    style EC fill:#f96,stroke:#333
    style SST fill:#f96,stroke:#333
    style PB fill:#eee,stroke:#999,stroke-dasharray: 5 5
Loading

After

build_tree_validator now takes EngineSharedCaches as a parameter. SDK consumers can clone whichever cache handle they need before forwarding the bundle:

  1. Clone whichever cache handle they need (e.g., shared_caches.precompile_cache_map.clone())
  2. Pass it to their payload builder
  3. Forward the bundle to BasicEngineValidator as normal
graph TD
    L[EngineNodeLauncher] -->|creates| ESC["EngineSharedCaches::default()"]
    L -->|"build_tree_validator(shared_caches)"| BEV[BasicEngineValidator]
    BEV -->|"new(shared_caches)"| PP[PayloadProcessor]
    ESC -.->|".precompile_cache_map.clone()"| PB[PayloadBuilder]

    style ESC fill:#6f9,stroke:#333
    style PB fill:#69f,stroke:#333
Loading

Expected Impact

  • Zero runtime change
  • Enables cache sharing with payload builders
  • Breaking: build_tree_validator signature now includes EngineSharedCaches
  • #[non_exhaustive] on EngineSharedCaches protects against future field additions

…d cache lifecycle

Adds a Reth-owned `EngineSharedCaches<Evm>` type that groups execution
cache, sparse trie cache, and precompile cache under a single facade
created by the node launcher and threaded through the engine validator
path — following the same ownership pattern as `ChangesetCache`.

This gives a stable public ownership boundary for later downstream
consumption without changing internal hot-path behavior.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 16, 2026

✅ Changelog found on PR.

Edit changelog

@yongkangc yongkangc self-assigned this Mar 16, 2026
- Remove SharedPreservedSparseTrie wrapper; use PayloadSparseTrieCache
  directly in PayloadProcessor (zero-value delegation layer)
- Make EngineSharedCaches fields pub, remove getter methods
- Remove Clone derive from EngineSharedCaches (facade is created and
  moved, not cloned)
- Fix trait inversion: make build_tree_validator_with_caches the
  required method, provide default for build_tree_validator that
  forwards with EngineSharedCaches::default() (eliminates silent
  cache-drop footgun and infinite-recursion trap)
- Remove redundant build_tree_validator override from
  BasicEngineValidatorBuilder (trait default handles it)
- Clean up doc comments and rustdoc links
@yongkangc yongkangc changed the title feat(engine): introduce EngineSharedCaches facade for launcher-owned cache lifecycle feat(engine): introduce EngineSharedCaches for launcher-owned cache lifecycle Mar 16, 2026
@yongkangc yongkangc changed the title feat(engine): introduce EngineSharedCaches for launcher-owned cache lifecycle feat(engine): add EngineSharedCaches for launcher-owned cache lifecycle Mar 16, 2026
@yongkangc
Copy link
Copy Markdown
Contributor Author

derek bench

@yongkangc yongkangc added S-breaking This PR includes a breaking change A-sdk Related to reth's use as a library A-engine Related to the engine implementation labels Mar 16, 2026
@yongkangc yongkangc marked this pull request as ready for review March 16, 2026 07:35
- Revert trait inversion: build_tree_validator stays required,
  build_tree_validator_with_caches is a default that drops caches
  and forwards (no semver break for external impls)
- Add #[non_exhaustive] to EngineSharedCaches (adding fields later
  won't break external destructuring/construction)
- Add Clone derive (pub fields make no-Clone unenforceable)
@yongkangc yongkangc removed the S-breaking This PR includes a breaking change label Mar 16, 2026
@yongkangc
Copy link
Copy Markdown
Contributor Author

@codex review

@yongkangc
Copy link
Copy Markdown
Contributor Author

derek bench

@decofe
Copy link
Copy Markdown
Member

decofe commented Mar 16, 2026

cc @yongkangc

✅ Benchmark complete! View job

Benchmark Results

Metric main yk/reth-505-engine-caches-facade-20260316-055813 Change
Mean 24.64ms 24.69ms +0.19% ⚪ (±0.29%)
StdDev 15.87ms 15.90ms
P50 21.45ms 21.48ms +0.13% ⚪ (±1.00%)
P90 35.85ms 35.84ms -0.03% ⚪ (±1.92%)
P99 98.70ms 98.10ms -0.60% ⚪ (±1.69%)
Mgas/s 1301.55 1299.95 -0.12% ⚪ (±0.32%)
Wall Clock 25.48s 25.52s +0.18% ⚪ (±0.34%)

500 blocks

Wait Time Breakdown

Persistence Wait

Metric main yk/reth-505-engine-caches-facade-20260316-055813
Mean 357.12ms 356.20ms
P50 340.59ms 341.55ms
P95 551.11ms 537.16ms

Trie Cache Update Wait

Metric main yk/reth-505-engine-caches-facade-20260316-055813
Mean 5.31ms 5.18ms
P50 5.49ms 5.38ms
P95 7.20ms 7.14ms

Execution Cache Update Wait

Metric main yk/reth-505-engine-caches-facade-20260316-055813
Mean 0.00ms 0.00ms
P50 0.00ms 0.00ms
P95 0.00ms 0.00ms

Grafana Dashboard

Charts

Latency, Throughput & Diff

Latency, Throughput & Diff

Wait Time Breakdown

Wait Time Breakdown

Gas vs Latency

Gas vs Latency

Grafana Dashboard

View real-time metrics

@yongkangc yongkangc added the A-block-building Related to block building label Mar 16, 2026
@yongkangc yongkangc changed the title feat(engine): add EngineSharedCaches for launcher-owned cache lifecycle feat(engine): let payload builders share engine caches Mar 16, 2026
@yongkangc yongkangc changed the title feat(engine): let payload builders share engine caches feat(engine): expose engine caches to SDK consumers Mar 16, 2026
@yongkangc yongkangc added the S-breaking This PR includes a breaking change label Mar 16, 2026
@yongkangc yongkangc requested a review from gakonst as a code owner March 16, 2026 09:03
@yongkangc yongkangc marked this pull request as draft March 16, 2026 09:34
@shekhirin
Copy link
Copy Markdown
Member

Superseded by #23242

@shekhirin shekhirin closed this Mar 26, 2026
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Reth Tracker Mar 26, 2026
@emmajam emmajam deleted the yk/reth-505-engine-caches-facade-20260316-055813 branch May 1, 2026 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-block-building Related to block building A-engine Related to the engine implementation A-sdk Related to reth's use as a library S-breaking This PR includes a breaking change

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants