Skip to content

Quick cache#7073

Merged
hanabi1224 merged 8 commits into
mainfrom
quick-cache
May 18, 2026
Merged

Quick cache#7073
hanabi1224 merged 8 commits into
mainfrom
quick-cache

Conversation

@LesnyRumcajs
Copy link
Copy Markdown
Member

@LesnyRumcajs LesnyRumcajs commented May 18, 2026

Summary of changes

Changes introduced in this pull request:

  • switches Forest's homebaked caching with quick_cache. Under the hood it uses Clock-PRO instead of LRU, which should have better performance characteristics.
  • a bunch of renaming, msotly to get rid of Lru prefix. This is a breaking change for Prometheus metrics, but I doubt it's used by anyone. I added it in the CHANGELOG just in case.

Reference issue to close (if applicable)

Closes

Other information and links

image

Change checklist

  • I have performed a self-review of my own code,
  • I have made corresponding changes to the documentation. All new code adheres to the team's documentation standards,
  • I have added tests that prove my fix is effective or that my feature works (if possible),
  • I have made sure the CHANGELOG is up-to-date. All user-facing changes should be reflected in this document.

Outside contributions

  • I have read and agree to the CONTRIBUTING document.
  • I have read and agree to the AI Policy document. I understand that failure to comply with the guidelines will lead to rejection of the pull request.

Summary by CodeRabbit

  • Breaking Changes

    • Core cache engine replaced with a new implementation (CLOCK‑PRO eviction). Prometheus metrics renamed from lru_cache_hit_total/lru_cache_miss_total to cache_hit_total/cache_miss_total — update dashboards, alerts, and recording rules.
  • Chores

    • Configuration updated to exclude crates.io (bot protection).

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: efbde0eb-6f47-4816-853a-7c87d105f227

📥 Commits

Reviewing files that changed from the base of the PR and between 179baa3 and 12627d5.

📒 Files selected for processing (1)
  • src/db/car/mod.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/db/car/mod.rs

Walkthrough

Replaces LRU-backed caches with a quick_cache-backed SizeTrackingCache (CLOCK-PRO), updates cache APIs and wrappers across the codebase, renames cache metrics, and migrates specialized caches (ZstdFrameCache, ForestCache, blockstore read cache) to the new engine.

Changes

Cache Engine Migration

Layer / File(s) Summary
Core cache implementation and constraint traits
src/utils/cache/size_tracking.rs
SizeTrackingCache<K, V> replaces SizeTrackingLruCache backed by quick_cache::sync::Cache. New CacheKeyConstraints and CacheValueConstraints replace LRU variants. All operations use Equivalent<K> for key matching. New async get_or_compute method coalesces concurrent cache misses and returns (value, hit: bool) tuple. Prometheus help text updated from "LruCache" to "cache".
Metrics and dependency infrastructure
Cargo.toml, src/metrics/mod.rs, src/utils/cache/mod.rs
Add quick_cache = "0.6" dependency. Replace LRU_CACHE_HIT/LRU_CACHE_MISS Prometheus metrics with CACHE_HIT/CACHE_MISS counters. Module exports switch from lru to size_tracking, exposing SizeTrackingCache instead of SizeTrackingLruCache.
ForestCache wrapper and state manager integration
src/state_manager/cache.rs, src/state_manager/mod.rs
ForestCache replaces ForestLruCache, wrapping SizeTrackingCache and adding TIPSET_HIT/TIPSET_MISS metrics. Removes manual pending map orchestration; delegates to get_or_compute for single-computation-per-key guarantee. get_map now accepts FnOnce closure. StateManager constructs ForestCache for tipset state and SizeTrackingCache for IdToAddressCache. Tests updated to verify concurrency and metric behavior.
Blockstore read cache and RPC integration
src/db/blockstore_with_read_cache.rs, src/rpc/methods/eth.rs, src/rpc/methods/f3.rs
DefaultBlockstoreReadCache (alias for SizeTrackingCache<CidWrapper, Vec<u8>>) replaces LruBlockstoreReadCache. BlockstoreReadCache impl updated to use get_cloned/push with CidWrapper key conversion. Ethereum RPC block transaction caches (ETH_BLOCK_HASH_TX_CACHE, ETH_BLOCK_FULL_TX_CACHE) now use ForestCache. F3 power-table computation updates BLOCKSTORE_CACHE static.
Beacon and chain store caches
src/beacon/drand.rs, src/chain/store/chain_store.rs, src/chain/store/index.rs
DrandBeacon::verified_beacons stores Arc<BeaconEntry> in SizeTrackingCache; cache lookups unwrap/clone via Arc::unwrap_or_clone. MessagesInTipsetCache and ChainIndex tipset cache use SizeTrackingCache. Cache hit/miss metrics updated to use CACHE_HIT/CACHE_MISS instead of LRU variants.
Bad block cache and state migration cache
src/chain_sync/bad_block_cache.rs, src/state_migration/common/mod.rs
BadBlockCache and SeenBlockCache migrate to SizeTrackingCache; BadBlockCache::peek uses peek_cloned with CidWrapper conversion. MigrationCache internal cache field changes from Arc<SizeTrackingLruCache<...>> to Arc<SizeTrackingCache<...>>; same initialization pattern via new_with_metrics.
Message pool signature and nonce caches
src/message_pool/msgpool/msg_pool.rs, src/message_pool/msgpool/selection.rs, src/message_pool/msgpool/utils.rs
Caches struct fields bls_sig, sig_val, and state_nonce migrate to SizeTrackingCache. recover_sig and run_head_change function signatures updated to accept &SizeTrackingCache<CidWrapper, Signature>. Cache key construction explicitly uses CidWrapper::from(cid).
ZstdFrameCache refactor to quick_cache backend
src/db/car/mod.rs, src/db/car/forest.rs
ZstdFrameCache refactored from SizeTrackingLruCache + manual AtomicUsize to direct quick_cache::sync::Cache with Weighter for byte-weight eviction. New FrameIndex stores Arc<HashMap<CidWrapper, Bytes>> per (offset, key). get() clones requested CID entry from cached index. put() computes weight, skips oversized entries, inserts to quick_cache without manual LRU maintenance. Test updated to assert cache weight and eviction behavior. Documentation comment updated from "lru-cache" to generic "cache".
Documentation and configuration
CHANGELOG.md, .config/lychee.toml
CHANGELOG.md documents breaking changes: cache engine replacement to CLOCK-PRO via quick_cache, Prometheus metric rename from lru_cache_* to cache_*, operator action reminder. .config/lychee.toml adds crates.io exclusion with bot protection comment.

Sequence Diagram

sequenceDiagram
  participant Caller
  participant ForestCache
  participant SizeTrackingCache
  participant quick_cache
  Caller->>ForestCache: get_or_else(key, compute_fn)
  ForestCache->>SizeTrackingCache: get_or_compute(key, compute_fn)
  alt Cache hit
    SizeTrackingCache->>quick_cache: get(key)
    quick_cache-->>SizeTrackingCache: Some(value)
    SizeTrackingCache-->>ForestCache: (value, hit=true)
    ForestCache->>ForestCache: increment TIPSET_HIT
  else Cache miss
    SizeTrackingCache->>SizeTrackingCache: call compute_fn()
    SizeTrackingCache->>quick_cache: insert(key, value)
    SizeTrackingCache-->>ForestCache: (value, hit=false)
    ForestCache->>ForestCache: increment TIPSET_MISS
  end
  ForestCache-->>Caller: value
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • ChainSafe/forest#6880: Touches tipset caching logic and capacity/skip-length adjustments overlapping ChainIndex cache changes.
  • ChainSafe/forest#5841: Introduced SizeTrackingLruCache/get-size utilities that this PR replaces with SizeTrackingCache.
  • ChainSafe/forest#5912: Related tipset-state caching refactor and metrics changes touching state_manager cache behavior.

Suggested labels

RPC

Suggested reviewers

  • akaladarshi
  • hanabi1224
  • sudo-shashank
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title "Quick cache" is vague and overly generic, failing to clearly describe the specific nature or scope of the changes. Consider a more descriptive title such as 'Replace LRU cache implementation with quick_cache' or 'Migrate caching from custom LRU to CLOCK-Pro algorithm' to better convey the primary change.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch quick-cache
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch quick-cache

Comment @coderabbitai help to get the list of available commands and usage tips.

@LesnyRumcajs LesnyRumcajs force-pushed the quick-cache branch 2 times, most recently from 67eee27 to 6320b26 Compare May 18, 2026 13:54
@LesnyRumcajs LesnyRumcajs marked this pull request as ready for review May 18, 2026 14:20
@LesnyRumcajs LesnyRumcajs requested a review from a team as a code owner May 18, 2026 14:20
@LesnyRumcajs LesnyRumcajs requested review from akaladarshi and hanabi1224 and removed request for a team May 18, 2026 14:20
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/utils/cache/size_tracking.rs (1)

116-126: 💤 Low value

Consider removing the unused Option<V> return from push for clarity.

All callers of push ignore the return value. Since the method is documented as non-atomic (peek-then-insert pattern), returning Option<V> implies atomicity that doesn't exist. Changing the return type to () would accurately reflect actual usage:

Simplify return type
-    pub fn push(&self, k: K, v: V) -> Option<V> {
-        let prev = self.cache.peek(&k);
-        self.cache.insert(k, v);
-        prev
+    pub fn push(&self, k: K, v: V) {
+        self.cache.insert(k, v);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/cache/size_tracking.rs` around lines 116 - 126, The push method
currently returns Option<V> though all callers ignore it and the method is
non-atomic; change pub fn push(&self, k: K, v: V) -> Option<V> to return () by
removing the Option<V> return, eliminate the prev variable/peek return (just
call self.cache.peek(&k) only if needed or remove the peek entirely if not
needed), update the method body to perform self.cache.insert(k, v) and return
nothing, and update the doc comment on push to remove references to returning a
displaced value; keep references to push, cache.peek, and cache.insert when
making these edits.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.config/lychee.toml:
- Around line 14-15: The exclusion currently uses the broad string "crates.io";
narrow it by removing the generic "crates.io" entry and instead add only the
specific failing URLs or path patterns that trigger bot protection (e.g., the
exact full URLs or host+path patterns supported by lychee) so real broken links
on crates.io are still caught; update the ignore list to reference those
explicit URL(s) or pattern(s) instead of the top-level "crates.io" token.

In `@src/db/car/mod.rs`:
- Around line 132-135: The current check in the cache insertion logic (using
entry_size.saturating_add(cache_key_size) >= self.max_size) rejects entries that
exactly equal the configured capacity; change the condition to use > instead of
>= so exact-fit entries are allowed (i.e. if
entry_size.saturating_add(cache_key_size) > self.max_size { return; }). Update
the comment to reflect that only items larger than the cache are skipped and
keep the saturating_add to avoid overflow; reference the variables entry_size,
cache_key_size and self.max_size in mod.rs.

---

Nitpick comments:
In `@src/utils/cache/size_tracking.rs`:
- Around line 116-126: The push method currently returns Option<V> though all
callers ignore it and the method is non-atomic; change pub fn push(&self, k: K,
v: V) -> Option<V> to return () by removing the Option<V> return, eliminate the
prev variable/peek return (just call self.cache.peek(&k) only if needed or
remove the peek entirely if not needed), update the method body to perform
self.cache.insert(k, v) and return nothing, and update the doc comment on push
to remove references to returning a displaced value; keep references to push,
cache.peek, and cache.insert when making these edits.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b8ce2083-98be-45fe-8d36-409bd7c825d0

📥 Commits

Reviewing files that changed from the base of the PR and between d546106 and 04b9376.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (22)
  • .config/lychee.toml
  • CHANGELOG.md
  • Cargo.toml
  • src/beacon/drand.rs
  • src/chain/store/chain_store.rs
  • src/chain/store/index.rs
  • src/chain_sync/bad_block_cache.rs
  • src/db/blockstore_with_read_cache.rs
  • src/db/car/forest.rs
  • src/db/car/mod.rs
  • src/message_pool/msgpool/mod.rs
  • src/message_pool/msgpool/msg_pool.rs
  • src/message_pool/msgpool/selection.rs
  • src/message_pool/msgpool/utils.rs
  • src/metrics/mod.rs
  • src/rpc/methods/eth.rs
  • src/rpc/methods/f3.rs
  • src/state_manager/cache.rs
  • src/state_manager/mod.rs
  • src/state_migration/common/mod.rs
  • src/utils/cache/mod.rs
  • src/utils/cache/size_tracking.rs

Comment thread .config/lychee.toml
Comment thread src/db/car/mod.rs
# Conflicts:
#	src/message_pool/msgpool/mod.rs
#	src/message_pool/msgpool/msg_pool.rs
#	src/utils/cache/size_tracking.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/utils/cache/size_tracking.rs (1)

208-237: 💤 Low value

Inconsistent metric name prefixes.

The size metric includes a cache_ prefix (cache_{}_{}_size) while len and cap metrics do not ({}_{}_len, {}_{}_cap). This naming inconsistency could make metric discovery and filtering more difficult for operators.

♻️ Suggested fix for consistent naming
         {
-            let len_metric_name = format!("{}_{}_len", self.cache_name, self.cache_id);
+            let len_metric_name = format!("cache_{}_{}_len", self.cache_name, self.cache_id);
             let len_metric_help = format!("Length of cache {}_{}", self.cache_name, self.cache_id);
             ...
         }
         {
-            let cap_metric_name = format!("{}_{}_cap", self.cache_name, self.cache_id);
+            let cap_metric_name = format!("cache_{}_{}_cap", self.cache_name, self.cache_id);
             let cap_metric_help =
                 format!("Capacity of cache {}_{}", self.cache_name, self.cache_id);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/cache/size_tracking.rs` around lines 208 - 237, The len and cap
metric names are missing the "cache_" prefix causing inconsistent metric naming;
update len_metric_name and cap_metric_name to use the same "cache_{}_{}_len" and
"cache_{}_{}_cap" format as size_metric_name, and adjust their help strings
(len_metric_help and cap_metric_help) to reflect the "cache_{}_{}" prefix so all
three metrics (size_metric_name, len_metric_name, cap_metric_name) consistently
use the cache_ prefix and the same cache identifier formatting when encoded.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/utils/cache/size_tracking.rs`:
- Around line 208-237: The len and cap metric names are missing the "cache_"
prefix causing inconsistent metric naming; update len_metric_name and
cap_metric_name to use the same "cache_{}_{}_len" and "cache_{}_{}_cap" format
as size_metric_name, and adjust their help strings (len_metric_help and
cap_metric_help) to reflect the "cache_{}_{}" prefix so all three metrics
(size_metric_name, len_metric_name, cap_metric_name) consistently use the cache_
prefix and the same cache identifier formatting when encoded.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 95e60c01-4d17-4054-965f-ea30d9c4f341

📥 Commits

Reviewing files that changed from the base of the PR and between 04b9376 and fb7eb82.

📒 Files selected for processing (5)
  • src/message_pool/msgpool/msg_pool.rs
  • src/message_pool/msgpool/selection.rs
  • src/message_pool/msgpool/utils.rs
  • src/rpc/methods/eth.rs
  • src/utils/cache/size_tracking.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/message_pool/msgpool/selection.rs
  • src/message_pool/msgpool/utils.rs
  • src/rpc/methods/eth.rs

@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

❌ Patch coverage is 86.66667% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.22%. Comparing base (6a45567) to head (12627d5).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/utils/cache/size_tracking.rs 77.77% 7 Missing and 1 partial ⚠️
src/message_pool/msgpool/utils.rs 0.00% 2 Missing ⚠️
src/rpc/methods/f3.rs 0.00% 2 Missing ⚠️
src/state_manager/cache.rs 92.00% 1 Missing and 1 partial ⚠️
src/beacon/drand.rs 83.33% 1 Missing ⚠️
src/db/car/mod.rs 95.45% 1 Missing ⚠️
Additional details and impacted files
Files with missing lines Coverage Δ
src/chain/store/chain_store.rs 69.93% <100.00%> (ø)
src/chain/store/index.rs 89.62% <100.00%> (ø)
src/chain_sync/bad_block_cache.rs 79.48% <100.00%> (ø)
src/db/blockstore_with_read_cache.rs 93.33% <100.00%> (ø)
src/db/car/forest.rs 83.87% <ø> (ø)
src/message_pool/msgpool/msg_pool.rs 87.75% <100.00%> (-0.22%) ⬇️
src/message_pool/msgpool/selection.rs 86.28% <100.00%> (ø)
src/metrics/mod.rs 39.39% <100.00%> (ø)
src/rpc/methods/eth.rs 65.68% <100.00%> (ø)
src/state_manager/mod.rs 65.43% <100.00%> (ø)
... and 7 more

... and 6 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6a45567...12627d5. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread Cargo.toml
@hanabi1224 hanabi1224 enabled auto-merge May 18, 2026 17:28
@hanabi1224 hanabi1224 added this pull request to the merge queue May 18, 2026
Merged via the queue into main with commit e0bca2a May 18, 2026
43 checks passed
@hanabi1224 hanabi1224 deleted the quick-cache branch May 18, 2026 17:46
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.

2 participants