Skip to content

fix: incorporate EC finality calculator into tipset lookup-by-height cache - #7112

Merged
hanabi1224 merged 9 commits into
mainfrom
hm/warmup-tipset-height-lookup
May 27, 2026
Merged

fix: incorporate EC finality calculator into tipset lookup-by-height cache#7112
hanabi1224 merged 9 commits into
mainfrom
hm/warmup-tipset-height-lookup

Conversation

@hanabi1224

@hanabi1224hanabi1224 commented May 27, 2026

Copy link
Copy Markdown
Contributor

Summary of changes

Previously, we don't cache the lookup for epoch (head-900, head] (Only when F3 is down), with EC finality calculator, the finaltiy is ~100 (actually 20 @6052192) instead of 900 on mainnet

Changes introduced in this pull request:

Benchmark of querying tipset @ (head epoch - 500).

# command
oha -n 1000 -c 1 -m POST http://localhost:2345/rpc/v1 -H 'Content-Type: application/json' -D eth_getBlockByNumber_call.json
# payload
{
"method": "eth_getBlockByNumber",
"params": ["0x5c571f", false],
"id": 1,
"jsonrpc": "2.0"
}
# main
Success rate: 100.00%30s 40s 50s 60s 70s ││0.0124 0.0166 0.0207 0.0248 0.0290 0.0331 0.0372 │
Total:────────19659.0131 ms──────────────────────────────┘└──────────────────────────────────────────────────────────┘
Slowest: 150.5417 ms
Fastest: 12.4223 ms
Average: 19.6465 ms
Requests/sec: 50.8673
Total data: 2.82 MiB
Size/request: 2.88 KiB
Size/sec: 146.74 KiB
Response time histogram:
12.422 ms [1] |
26.234 ms [812] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
40.046 ms [184] |■■■■■■■
53.858 ms [1] |
67.670 ms [0] |
81.482 ms [1] |
95.294 ms [0] |
109.106 ms [0] |
122.918 ms [0] |
136.730 ms [0] |
150.542 ms [1] |
Response time distribution:
10.00% in 16.0410 ms
25.00% in 16.3323 ms
50.00% in 16.6541 ms
75.00% in 20.0071 ms
90.00% in 28.3209 ms
95.00% in 34.7470 ms
99.00% in 36.3333 ms
99.90% in 150.5417 ms
99.99% in 150.5417 ms
# PR Success rate: 100.00%
Total: 658.4161 ms
Slowest: 20.1629 ms
Fastest: 0.2080 ms
Average: 0.6541 ms
Requests/sec: 1518.7965
Total data: 2.82 MiB
Size/request: 2.88 KiB
Size/sec: 4.28 MiB
Response time histogram:
0.208 ms [1] |
2.204 ms [966] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
4.199 ms [28] |
6.194 ms [4] |
8.190 ms [0] |
10.185 ms [0] |
12.181 ms [0] |
14.176 ms [0] |
16.172 ms [0] |
18.167 ms [0] |
20.163 ms [1] |
Response time distribution:
10.00% in 0.2769 ms
25.00% in 0.3087 ms
50.00% in 0.4054 ms
75.00% in 0.6308 ms
90.00% in 1.3820 ms
95.00% in 1.9961 ms
99.00% in 3.0389 ms
99.90% in 20.1629 ms
99.99% in 20.1629 ms

Reference issue to close (if applicable)

Closes

Other information and links

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

  • Refactor

    • Finality logic now derives a dynamic EC-based finalized epoch and uses a unified predicate that stays consistent as the chain head advances.
    • The EC-derived finalized epoch is exposed so other components can reference the computed finality point.
  • Performance

    • Added async tipset lookups and an extra cache warmup step to prefetch finalized tipsets, improving RPC responsiveness and cache hit rates; lookup failures are logged.

Review Change Stack

@hanabi1224hanabi1224 added the RPC requires calibnet RPC checks to run on CI label May 27, 2026
@coderabbitai

coderabbitaiBot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

This PR was authored by the user configured for CodeRabbit reviews. CodeRabbit does not review PRs authored by this user. It's recommended to use a dedicated user account to post CodeRabbit review feedback.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 37de5d2a-b55d-4f92-8657-313e88b57b90

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Refactors EC finality epoch computation into a public RPC helper; caches the EC-derived finalized epoch in ChainStore and uses it (maxed with F3 epoch) for finality checks; adds async tipset lookup and warms daemon RPC caches using the cached EC epoch.

Changes

EC finality epoch caching and integration

Layer / File(s)Summary
RPC EC finality calculation refactoring
src/rpc/methods/chain.rs
ChainGetTipSetFinalityStatus gains get_ec_finality_epoch and internal helpers (depth→epoch mapping, cached threshold-depth); chain-sampling and finalized-tipset resolution are refactored to compute an EC finality epoch and resolve the tipset via ChainIndex.
ChainStore EC finalized-epoch cache and integration
src/chain/store/chain_store.rs
Adds ec_calculator_finalized_epoch: Arc<AtomicI64>, initializes it with get_ec_finality_epoch in ChainStore::new, integrates it into with_is_tipset_finalized using max(F3_finalized_epoch, ec_calculator_finalized_epoch), propagates it via ShallowClone, recomputes it in set_heaviest_tipset, and exposes pub fn ec_calculator_finalized_epoch(&self) -> ChainEpoch.
ChainIndex async lookup & daemon warmup
src/chain/store/index.rs, src/daemon/mod.rs
Adds ChainIndex::tipset_by_height_async (spawn_blocking wrapper) and updates tipset_by_height fast-paths; daemon cache prefill now loads the tipset at the cached EC finalized epoch via the async lookup and logs a warning if lookup fails.

Sequence Diagram(s)

sequenceDiagram
participant Daemon
participant ChainStore
participant ChainGetTipSetFinalityStatus
participant ChainIndex
Daemon->>ChainStore: on new validated tipset -> read ec_calculator_finalized_epoch
ChainStore->>ChainGetTipSetFinalityStatus: (during init/set_heaviest) get_ec_finality_epoch(chain_index, chain_config, head)
ChainGetTipSetFinalityStatus->>ChainIndex: tipset_by_height(ec_finality_epoch, head, ResolveNullTipset::TakeOlder)
ChainIndex-->>ChainGetTipSetFinalityStatus: finalized tipset
ChainGetTipSetFinalityStatus-->>ChainStore: ec_finality_epoch
Daemon->>ChainIndex: tipset_by_height_async(ec_finality_epoch, head, ResolveNullTipset::TakeOlder)
ChainIndex-->>Daemon: finalized tipset or error
Loading

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

  • ChainSafe/forest#6880: Modifies ChainIndex::tipset_by_height behavior; related to the index fast-path changes and async wrapper added here.
  • ChainSafe/forest#6811: Refactors ChainGetTipSetFinalityStatus and its helpers; closely related to the new helper extraction.
  • ChainSafe/forest#6897: Also refactors EC-based finality resolution and overlaps with ChainGetTipSetFinalityStatus changes.

Suggested reviewers

  • sudo-shashank
  • LesnyRumcajs
  • akaladarshi
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: incorporating EC finality calculator into tipset lookup-by-height caching, which is the core objective of the PR.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

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


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

@hanabi1224
hanabi1224 marked this pull request as ready for review May 27, 2026 08:58
@hanabi1224
hanabi1224 requested a review from a team as a code ownerMay 27, 2026 08:58
@hanabi1224
hanabi1224 requested review from LesnyRumcajs and sudo-shashank and removed request for a teamMay 27, 2026 08:58

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/rpc/methods/chain.rs (1)

1171-1191: 💤 Low value

Consider using ChainEpoch as the return type for consistency.

The method returns i64, but conceptually represents a ChainEpoch. While they're the same underlying type, using ChainEpoch would be more self-documenting and consistent with how the result is used in ChainStore (stored in Arc<RwLock<ChainEpoch>>).

Suggested change
 pub fn get_ec_finality_epoch(
chain_index: &ChainIndex,
chain_config: &ChainConfig,
head: &Tipset,
- ) -> i64 {+ ) -> ChainEpoch {
let depth =
Self::get_ec_finality_threshold_depth_with_cache(chain_index, chain_config, head);
Self::get_ec_finality_epoch_by_depth(chain_config, head, depth)
}
fn get_ec_finality_epoch_by_depth(
chain_config: &ChainConfig,
head: &Tipset,
depth: i64,
- ) -> i64 {+ ) -> ChainEpoch {
🤖 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/rpc/methods/chain.rs` around lines 1171 - 1191, Change the return type of
get_ec_finality_epoch and get_ec_finality_epoch_by_depth from i64 to ChainEpoch
to reflect the semantic type; update their signatures (pub fn
get_ec_finality_epoch(... ) -> ChainEpoch and fn
get_ec_finality_epoch_by_depth(... ) -> ChainEpoch) and convert the
arithmetic/clamping logic to produce a ChainEpoch (e.g., perform epoch
subtraction and clamp to zero using ChainEpoch-compatible operations or
conversions), and update any callers or stored places (e.g., where the result is
placed into Arc<RwLock<ChainEpoch>>) to accept ChainEpoch instead of i64; touch
the symbols get_ec_finality_epoch, get_ec_finality_epoch_by_depth, ChainIndex,
ChainConfig, Tipset and chain_config.policy.chain_finality as needed to keep
types consistent.
🤖 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/rpc/methods/chain.rs`:
- Around line 1171-1191: Change the return type of get_ec_finality_epoch and
get_ec_finality_epoch_by_depth from i64 to ChainEpoch to reflect the semantic
type; update their signatures (pub fn get_ec_finality_epoch(... ) -> ChainEpoch
and fn get_ec_finality_epoch_by_depth(... ) -> ChainEpoch) and convert the
arithmetic/clamping logic to produce a ChainEpoch (e.g., perform epoch
subtraction and clamp to zero using ChainEpoch-compatible operations or
conversions), and update any callers or stored places (e.g., where the result is
placed into Arc<RwLock<ChainEpoch>>) to accept ChainEpoch instead of i64; touch
the symbols get_ec_finality_epoch, get_ec_finality_epoch_by_depth, ChainIndex,
ChainConfig, Tipset and chain_config.policy.chain_finality as needed to keep
types consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 73c9f109-5c91-49a7-a50f-ed4e300a65a7

📥 Commits

Reviewing files that changed from the base of the PR and between ee2a7e6 and 2da49d6.

📒 Files selected for processing (2)
  • src/chain/store/chain_store.rs
  • src/rpc/methods/chain.rs

@codecov

codecovBot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.07438% with 35 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.40%. Comparing base (ee2a7e6) to head (7bd0392).
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/daemon/mod.rs0.00%18 Missing ⚠️
src/chain/store/index.rs25.00%11 Missing and 1 partial ⚠️
src/chain/store/chain_store.rs84.00%4 Missing ⚠️
src/rpc/methods/chain.rs98.38%1 Missing ⚠️
Additional details and impacted files
Files with missing linesCoverage Δ
src/rpc/methods/chain.rs57.22% <98.38%> (+1.56%)⬆️
src/chain/store/chain_store.rs69.01% <84.00%> (+0.14%)⬆️
src/chain/store/index.rs85.38% <25.00%> (-3.45%)⬇️
src/daemon/mod.rs25.00% <0.00%> (-0.69%)⬇️

... and 8 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 ee2a7e6...7bd0392. 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.

@hanabi1224
hanabi1224force-pushed the hm/warmup-tipset-height-lookup branch from 4060d7c to 8eef8d9CompareMay 27, 2026 09:55
Comment threadsrc/chain/store/chain_store.rs Outdated
Comment threadsrc/rpc/methods/chain.rs Outdated
@hanabi1224
hanabi1224 enabled auto-merge May 27, 2026 11:46
@hanabi1224
hanabi1224 added this pull request to the merge queueMay 27, 2026
Merged via the queue into main with commit 8086404May 27, 2026
33 checks passed
@hanabi1224
hanabi1224 deleted the hm/warmup-tipset-height-lookup branch May 27, 2026 12:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RPCrequires calibnet RPC checks to run on CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@hanabi1224@LesnyRumcajs