Skip to content

fix: optimize logic of looking up genesis from a tipset#7290

Merged
hanabi1224 merged 8 commits into
mainfrom
hm/optimize-genesis-loading
Jul 3, 2026
Merged

fix: optimize logic of looking up genesis from a tipset#7290
hanabi1224 merged 8 commits into
mainfrom
hm/optimize-genesis-loading

Conversation

@hanabi1224

@hanabi1224 hanabi1224 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary of changes

Changes introduced in this pull request:

Reference issue to close (if applicable)

Closes #7291

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

  • New Features
    • Added direct conversion from raw block headers to tipsets.
    • Introduced async genesis retrieval and consistent genesis propagation across export, snapshot, offline, and RPC flows.
  • Bug Fixes
    • Fixed genesis handling for height/epoch 0 to use the stored genesis tipset.
    • Standardized genesis timestamp derivation from the min-ticket block for message application and validation.
  • Tests
    • Updated chain-store/index and related tooling tests to align with the new genesis APIs and added RPC identity/parity checks for block number 0.

@hanabi1224 hanabi1224 added RPC requires calibnet RPC checks to run on CI Snapshot Run snapshot tests labels Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Genesis handling now uses stored Tipset values across chain storage, state computation, export paths, DB mappings, and RPC snapshot plumbing. Epoch-0 lookups and related tests now derive network and timing data from min_ticket_block().

Changes

Genesis tipset, chain state, and export flow

Layer / File(s) Summary
Tipset genesis lookup API
src/blocks/tipset.rs
Adds From<&RawBlockHeader> for Tipset and replaces synchronous genesis lookup with async and blocking helpers that return Tipset values.
ChainIndex and ChainStore store genesis tipsets
src/chain/store/index.rs, src/chain/store/chain_store.rs
ChainIndex and ChainStore cache genesis as Tipset, update constructors and accessors, and use the cached tipset in height lookup and lookback timestamp derivation.
Daemon and chain follower genesis wiring
src/daemon/mod.rs, src/chain_sync/chain_follower.rs
create_chain_follower now uses genesis_tipset(), and the chain follower test helper passes the genesis header directly into ChainStore::new.
State computation derives genesis timestamp internally
src/state_manager/state_computation.rs, src/state_manager/execution.rs
apply_block_messages_blocking derives genesis time from chain_index.genesis(), and validation/execution callers stop passing a separate genesis timestamp.
Raw epoch tipset-key mappings
src/db/mod.rs, src/db/memory.rs, src/db/parity_db.rs, src/db/parity_db/gc.rs, src/db/car/many.rs
EthMappingsStore exposes a raw epoch/key setter, and the memory, parity, garbage-collection, and ManyCar implementations forward epoch/key writes through the new shape.
RPC snapshot backfill and method matching
src/tool/subcommands/api_cmd.rs, src/tool/subcommands/api_cmd/test_snapshot.rs, src/tool/subcommands/api_cmd/test_snapshots.txt, src/tool/subcommands/api_cmd/generate_test_snapshot.rs
RpcTestSnapshot gains tipset_by_epoch, snapshot loading backfills ts_lookup_db, and RPC method selection accepts aliases while matching covered and uncovered snapshot names.
Archive export and checkpoint flows use genesis tipsets
src/tool/subcommands/archive_cmd.rs, src/tool/subcommands/benchmark_cmd.rs, src/tool/subcommands/snapshot_cmd.rs, src/tool/offline_server/server.rs
do_export accepts an optional genesis tipset, downstream export and checkpoint paths use async or blocking genesis lookup, and network/timestamp derivation switches to min_ticket_block().
RPC export wiring and epoch-0 parity tests
src/rpc/methods/chain.rs, src/tool/subcommands/api_cmd/api_compare_tests.rs
ForestChainExportDiff::handle passes the chain store genesis tipset into export, and parity tests add epoch-0 coverage for tipset-height and ETH block lookups.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: LesnyRumcajs, sudo-shashank, akaladarshi

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Tipset
  participant ChainStore
  participant ChainIndex
  participant StateComputation

  Client->>Tipset: genesis(store)
  Tipset->>ChainStore: store / return genesis tipset
  ChainStore->>ChainIndex: new(store, genesis)
  StateComputation->>ChainIndex: genesis()
  ChainIndex-->>StateComputation: cached genesis tipset
  StateComputation->>StateComputation: derive genesis timestamp
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the main change: optimizing genesis lookup from a tipset for epoch-0 requests.
Linked Issues check ✅ Passed The refactor caches genesis tipsets and removes repeated tipset-to-genesis lookups, which directly targets the slow epoch-0 requests in #7291.
Out of Scope Changes check ✅ Passed The additional API, snapshot, and test updates appear to support the same genesis-lookup refactor rather than introduce unrelated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hm/optimize-genesis-loading
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch hm/optimize-genesis-loading

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

@hanabi1224 hanabi1224 marked this pull request as ready for review July 3, 2026 05:48
@hanabi1224 hanabi1224 requested a review from a team as a code owner July 3, 2026 05:48
@hanabi1224 hanabi1224 requested review from LesnyRumcajs and akaladarshi and removed request for a team July 3, 2026 05:48

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/chain/store/chain_store.rs (1)

115-131: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Validate that cached genesis is actually epoch 0.

ChainIndex now trusts the stored genesis for height-0 lookups, but ChainStore::new accepts any Tipset. The updated test currently builds gen_ts from a header with epoch: 1, which would make epoch-0 lookups return an epoch-1 tipset if used through the index.

Proposed fix
         let db = db.into();
         let genesis = genesis.into();
+        anyhow::ensure!(
+            genesis.epoch() == 0,
+            "genesis tipset must be at epoch 0, got {}",
+            genesis.epoch()
+        );
-            epoch: 1,
+            epoch: 0,

Also applies to: 735-738

🤖 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/chain/store/chain_store.rs` around lines 115 - 131, Ensure the genesis
tipset passed into ChainStore::new is actually epoch 0 before it gets cached and
handed to ChainIndex::new, since the index now relies on that stored genesis for
height-0 lookups. Update the test fixture that builds gen_ts so it uses a header
at epoch 0 instead of epoch 1, or add validation in ChainStore::new to reject
non-zero genesis tipsets. Use the ChainStore::new and ChainIndex::new symbols to
locate the affected flow.
🧹 Nitpick comments (4)
src/blocks/tipset.rs (1)

430-437: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add context to the new fallible genesis lookup paths.

The spawn_blocking(...).await? and store.get_cbor(&genesis_cid)? errors lose the operation/CID context, which makes failed genesis resolution harder to diagnose.

Proposed fix
-        tokio::task::spawn_blocking(move || this.genesis_blocking(&store)).await?
+        tokio::task::spawn_blocking(move || this.genesis_blocking(&store))
+            .await
+            .context("genesis lookup blocking task failed")?
                     let genesis_block: CachingBlockHeader = store
-                        .get_cbor(&genesis_cid)?
+                        .get_cbor(&genesis_cid)
+                        .with_context(|| format!("failed to load genesis block {genesis_cid}"))?
                         .context("Genesis block missing from database")?;

As per coding guidelines, **/*.rs: add context with .context() when errors occur.

Also applies to: 467-470

🤖 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/blocks/tipset.rs` around lines 430 - 437, The new fallible genesis lookup
paths in Tipset::genesis and genesis_blocking lose useful operation and CID
context when they fail. Update the spawn_blocking(...).await? path to add
context around the async blocking lookup, and add .context() to the
store.get_cbor(&genesis_cid)? failure so the genesis CID and operation are
included. Use the existing Tipset::genesis and genesis_blocking symbols to
locate the changes and keep the error messages specific to genesis resolution.

Source: Coding guidelines

src/chain/store/index.rs (1)

180-180: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update the height-zero contract docs.

Line 180 no longer performs a genesis lookup, so the doc above this method should stop saying height-zero can fail because “genesis lookup fails.”

🤖 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/chain/store/index.rs` at line 180, The doc above the height-zero contract
method is now outdated because `self.genesis.shallow_clone()` no longer implies
a genesis lookup can fail. Update the documentation for the relevant method in
`Store` so it no longer mentions “genesis lookup fails” for height zero, and
make sure the wording matches the current `genesis`-based behavior in
`src/chain/store/index.rs`.
src/tool/subcommands/archive_cmd.rs (2)

553-576: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Consider guarding against a mismatched caller-supplied genesis.

do_export now trusts any Some(genesis) passed in without checking it actually belongs to root's chain (e.g. genesis.epoch() == 0). A future caller passing a genesis from a different chain/store would silently produce a wrong network/finality/output-path derivation and could corrupt an exported snapshot. Only the current caller (ForestChainExportDiff::handle) is self-consistent, but nothing enforces this contract going forward.

🛡️ Proposed cheap guard
     let genesis = if let Some(genesis) = genesis {
+        debug_assert_eq!(
+            genesis.epoch(),
+            0,
+            "caller-supplied genesis must be an epoch-0 tipset"
+        );
         genesis
     } else {
🤖 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/tool/subcommands/archive_cmd.rs` around lines 553 - 576, Guard do_export
against a caller-supplied genesis that does not match the root chain by
validating the optional genesis before using it, such as confirming it is the
actual chain genesis (for example via genesis.epoch() or equivalent Tipset
checks) and rejecting mismatches with an error. Keep the existing fallback path
that derives genesis from ts.genesis(store.shallow_clone()), and ensure the
NetworkChain::from_genesis_or_devnet_placeholder derivation only runs on a
verified genesis.

1059-1064: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

sync_bucket's export loops repeat the slow genesis walk on every iteration instead of reusing the genesis already resolved.

sync_bucket already resolves the genesis tipset once (to get genesis_timestamp at line ~1135-1139), but export_lite_snapshot/export_diff_snapshot are called None for genesis (lines 1062, 1099) inside per-epoch loops (steps_in_range(...)). Each call therefore forces do_export to redo the "slow" ts.genesis(store.shallow_clone()).await? chain-walk once per exported epoch — directly re-introducing the genesis-lookup cost this PR is meant to eliminate, just in a different (batch/tooling) code path.

Thread the genesis Tipset that sync_bucket already computed through export_lite_snapshot/export_diff_snapshot into do_export instead of re-deriving it per epoch.

♻️ Proposed refactor sketch
-async fn export_lite_snapshot<DB>(
-    store: DB,
-    root: Tipset,
-    network: &str,
-    genesis_timestamp: u64,
-    epoch: ChainEpoch,
-) -> anyhow::Result<PathBuf>
+async fn export_lite_snapshot<DB>(
+    store: DB,
+    root: Tipset,
+    network: &str,
+    genesis: Tipset,
+    epoch: ChainEpoch,
+) -> anyhow::Result<PathBuf>
 where
     DB: Blockstore + ShallowClone + Into<DbImpl> + Unpin + Send + Sync + 'static,
 {
-    let output_path: PathBuf = format_lite_snapshot(network, genesis_timestamp, epoch)?.into();
+    let output_path: PathBuf =
+        format_lite_snapshot(network, genesis.min_ticket_block().timestamp, epoch)?.into();
     ...
     do_export(
         &store,
         root,
-        None,
+        Some(genesis),
         output_path.clone(),
         ...

And in sync_bucket, keep the resolved genesis Tipset (not just its timestamp) and pass genesis.clone() into each call site instead of genesis_timestamp alone. Apply the same change to export_diff_snapshot.

Also applies to: 1096-1101, 1116-1207

🤖 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/tool/subcommands/archive_cmd.rs` around lines 1059 - 1064, `sync_bucket`
is still re-running the slow genesis lookup inside the export loops because
`export_lite_snapshot` and `export_diff_snapshot` pass `None` for `genesis` into
`do_export`. Reuse the already-resolved genesis `Tipset` from `sync_bucket` (the
one used to derive `genesis_timestamp`) and thread it through both export
helpers so `do_export` receives that value instead of calling
`ts.genesis(store.shallow_clone()).await?` again for every epoch.
🤖 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.

Outside diff comments:
In `@src/chain/store/chain_store.rs`:
- Around line 115-131: Ensure the genesis tipset passed into ChainStore::new is
actually epoch 0 before it gets cached and handed to ChainIndex::new, since the
index now relies on that stored genesis for height-0 lookups. Update the test
fixture that builds gen_ts so it uses a header at epoch 0 instead of epoch 1, or
add validation in ChainStore::new to reject non-zero genesis tipsets. Use the
ChainStore::new and ChainIndex::new symbols to locate the affected flow.

---

Nitpick comments:
In `@src/blocks/tipset.rs`:
- Around line 430-437: The new fallible genesis lookup paths in Tipset::genesis
and genesis_blocking lose useful operation and CID context when they fail.
Update the spawn_blocking(...).await? path to add context around the async
blocking lookup, and add .context() to the store.get_cbor(&genesis_cid)? failure
so the genesis CID and operation are included. Use the existing Tipset::genesis
and genesis_blocking symbols to locate the changes and keep the error messages
specific to genesis resolution.

In `@src/chain/store/index.rs`:
- Line 180: The doc above the height-zero contract method is now outdated
because `self.genesis.shallow_clone()` no longer implies a genesis lookup can
fail. Update the documentation for the relevant method in `Store` so it no
longer mentions “genesis lookup fails” for height zero, and make sure the
wording matches the current `genesis`-based behavior in
`src/chain/store/index.rs`.

In `@src/tool/subcommands/archive_cmd.rs`:
- Around line 553-576: Guard do_export against a caller-supplied genesis that
does not match the root chain by validating the optional genesis before using
it, such as confirming it is the actual chain genesis (for example via
genesis.epoch() or equivalent Tipset checks) and rejecting mismatches with an
error. Keep the existing fallback path that derives genesis from
ts.genesis(store.shallow_clone()), and ensure the
NetworkChain::from_genesis_or_devnet_placeholder derivation only runs on a
verified genesis.
- Around line 1059-1064: `sync_bucket` is still re-running the slow genesis
lookup inside the export loops because `export_lite_snapshot` and
`export_diff_snapshot` pass `None` for `genesis` into `do_export`. Reuse the
already-resolved genesis `Tipset` from `sync_bucket` (the one used to derive
`genesis_timestamp`) and thread it through both export helpers so `do_export`
receives that value instead of calling
`ts.genesis(store.shallow_clone()).await?` again for every epoch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d64fced2-3c58-4ef2-994a-7dde4b9f04bd

📥 Commits

Reviewing files that changed from the base of the PR and between c13f3c0 and 5dadf7d.

📒 Files selected for processing (14)
  • src/blocks/tipset.rs
  • src/chain/store/chain_store.rs
  • src/chain/store/index.rs
  • src/chain_sync/chain_follower.rs
  • src/daemon/mod.rs
  • src/db/car/many.rs
  • src/rpc/methods/chain.rs
  • src/state_manager/execution.rs
  • src/state_manager/state_computation.rs
  • src/tool/offline_server/server.rs
  • src/tool/subcommands/api_cmd/api_compare_tests.rs
  • src/tool/subcommands/archive_cmd.rs
  • src/tool/subcommands/benchmark_cmd.rs
  • src/tool/subcommands/snapshot_cmd.rs
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • filecoin-project/lotus (manual)
💤 Files with no reviewable changes (1)
  • src/state_manager/execution.rs

@hanabi1224 hanabi1224 force-pushed the hm/optimize-genesis-loading branch from 2cd9c6e to 0179c05 Compare July 3, 2026 06:12

@coderabbitai coderabbitai Bot 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/tool/subcommands/api_cmd/api_compare_tests.rs (1)

508-509: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Ignored parity tests won't catch epoch-0 regressions in default CI runs.

These new tests target the exact scenario from issue #7291 (epoch-0 lookups), but .ignore("Lotus times out") skips them in default test runs. Since Lotus is the side that times out, RpcTest::identity (which requires both Forest and Lotus to agree) can never usefully validate this path — the assertion is effectively disabled rather than deferred. Using RpcTest::basic instead (verifying only that Forest itself returns successfully/quickly) would give continuous regression coverage for the genesis-lookup performance fix without depending on Lotus's behavior.

♻️ Suggested direction
-        RpcTest::identity(ChainGetTipSetByHeight::request((0, Default::default())).unwrap())
-            .ignore("Lotus times out"),
+        RpcTest::basic(ChainGetTipSetByHeight::request((0, Default::default())).unwrap()),

Also applies to: 1402-1419

🤖 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/tool/subcommands/api_cmd/api_compare_tests.rs` around lines 508 - 509,
The epoch-0 parity checks in RpcTest::identity are being skipped, so they won’t
protect against regressions in default CI. Update the affected tests in
api_compare_tests.rs to use RpcTest::basic for the ChainGetTipSetByHeight
request path instead of identity, and remove the Lotus-timeout ignore so the
Forest-side lookup remains continuously validated; apply the same change to the
other epoch-0 cases referenced in the diff.
🤖 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/tool/subcommands/api_cmd/api_compare_tests.rs`:
- Around line 508-509: The epoch-0 parity checks in RpcTest::identity are being
skipped, so they won’t protect against regressions in default CI. Update the
affected tests in api_compare_tests.rs to use RpcTest::basic for the
ChainGetTipSetByHeight request path instead of identity, and remove the
Lotus-timeout ignore so the Forest-side lookup remains continuously validated;
apply the same change to the other epoch-0 cases referenced in the diff.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: bf714423-b1e8-4029-bfa8-af3b65be4ab4

📥 Commits

Reviewing files that changed from the base of the PR and between 2cd9c6e and 0179c05.

📒 Files selected for processing (3)
  • src/chain/store/chain_store.rs
  • src/chain/store/index.rs
  • src/tool/subcommands/api_cmd/api_compare_tests.rs
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • filecoin-project/lotus (manual)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/chain/store/index.rs
  • src/chain/store/chain_store.rs

@hanabi1224 hanabi1224 force-pushed the hm/optimize-genesis-loading branch from d72c525 to cd33bd0 Compare July 3, 2026 06:26
@hanabi1224 hanabi1224 force-pushed the hm/optimize-genesis-loading branch from cd33bd0 to 99df92e Compare July 3, 2026 06:28
@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 53.45622% with 101 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.22%. Comparing base (c13f3c0) to head (f108391).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/tool/subcommands/api_cmd.rs 0.00% 23 Missing ⚠️
src/tool/subcommands/archive_cmd.rs 41.66% 19 Missing and 2 partials ⚠️
...tool/subcommands/api_cmd/generate_test_snapshot.rs 0.00% 14 Missing ⚠️
src/tool/subcommands/snapshot_cmd.rs 0.00% 11 Missing ⚠️
src/db/parity_db.rs 0.00% 8 Missing ⚠️
src/db/parity_db/gc.rs 0.00% 7 Missing ⚠️
src/blocks/tipset.rs 75.00% 3 Missing and 1 partial ⚠️
src/tool/offline_server/server.rs 0.00% 3 Missing ⚠️
src/tool/subcommands/api_cmd/test_snapshot.rs 84.21% 0 Missing and 3 partials ⚠️
src/tool/subcommands/benchmark_cmd.rs 0.00% 3 Missing ⚠️
... and 3 more
Additional details and impacted files
Files with missing lines Coverage Δ
src/beacon/mock_beacon.rs 31.25% <100.00%> (+9.82%) ⬆️
src/chain/ec_finality/calculator/mod.rs 92.19% <100.00%> (ø)
src/chain/store/index.rs 86.72% <100.00%> (+0.81%) ⬆️
src/chain_sync/chain_follower.rs 32.76% <100.00%> (ø)
src/cli/subcommands/info_cmd.rs 84.53% <100.00%> (ø)
src/cli_shared/snapshot.rs 75.57% <100.00%> (ø)
src/daemon/mod.rs 24.67% <100.00%> (ø)
src/db/car/many.rs 55.30% <100.00%> (+0.68%) ⬆️
src/db/memory.rs 89.61% <100.00%> (+0.13%) ⬆️
src/db/mod.rs 56.41% <100.00%> (+3.63%) ⬆️
... and 25 more

... and 5 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c13f3c0...f108391. 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.

@LesnyRumcajs

Copy link
Copy Markdown
Member
FAIL [   0.007s] ( 104/2135) forest-filecoin chain::store::chain_store::tests::genesis_test

@coderabbitai coderabbitai Bot 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/tool/subcommands/api_cmd/test_snapshot.rs (1)

288-330: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Fragile substring replace for eth/filecoin name normalization.

.replace("eth.", "eth_") is a global, unanchored substring replace rather than a prefix check. It currently works because captured names contain only a single underscore (namespace + PascalCase method), but it's non-idiomatic and could silently mis-normalize any future method/namespace name that happens to contain the literal substring "eth." anywhere (not just at the start).

Prefer explicitly anchoring the check to the start of the string:

♻️ Proposed fix using prefix-anchored normalization
-                        .replace("_", ".")
-                        .to_lowercase()
-                        .replace("eth.", "eth_")
+                        .replace("_", ".")
+                        .to_lowercase();
+                    let name = if let Some(rest) = name.strip_prefix("eth.") {
+                        format!("eth_{rest}")
+                    } else {
+                        name
+                    };

Since this pattern deviates from idiomatic string handling, worth double-checking against actual entries in test_snapshots.txt/test_snapshots_ignored.txt to confirm no method or namespace name contains an embedded "eth." sequence beyond the intended prefix.

🤖 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/tool/subcommands/api_cmd/test_snapshot.rs` around lines 288 - 330, The
name normalization in the snapshot coverage logic is too fragile because the
`replace("eth.", "eth_")` call in the `covered` mapping is a global substring
replacement. Update the normalization in `test_snapshot.rs` to use an explicit
prefix-based check for the `eth` namespace when transforming the captured
`name`, so only the intended leading namespace separator is rewritten. Keep the
rest of the `print_uncovered`/coverage matching flow unchanged, and verify the
entries read from `test_snapshots.txt` and `test_snapshots_ignored.txt` still
normalize to the same values.
🤖 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/tool/subcommands/api_cmd/test_snapshot.rs`:
- Around line 288-330: The name normalization in the snapshot coverage logic is
too fragile because the `replace("eth.", "eth_")` call in the `covered` mapping
is a global substring replacement. Update the normalization in
`test_snapshot.rs` to use an explicit prefix-based check for the `eth` namespace
when transforming the captured `name`, so only the intended leading namespace
separator is rewritten. Keep the rest of the `print_uncovered`/coverage matching
flow unchanged, and verify the entries read from `test_snapshots.txt` and
`test_snapshots_ignored.txt` still normalize to the same values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cccf36f2-534a-4ff2-9ca2-3df6f6659122

📥 Commits

Reviewing files that changed from the base of the PR and between 630da33 and 845b45e.

📒 Files selected for processing (4)
  • src/chain/store/chain_store.rs
  • src/tool/subcommands/api_cmd.rs
  • src/tool/subcommands/api_cmd/test_snapshot.rs
  • src/tool/subcommands/api_cmd/test_snapshots.txt
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • filecoin-project/lotus (manual)
✅ Files skipped from review due to trivial changes (1)
  • src/tool/subcommands/api_cmd/test_snapshots.txt
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/tool/subcommands/api_cmd.rs
  • src/chain/store/chain_store.rs

@hanabi1224

Copy link
Copy Markdown
Contributor Author

@LesnyRumcajs all green now

Comment thread src/db/car/many.rs Outdated
@hanabi1224 hanabi1224 enabled auto-merge July 3, 2026 12:15
@hanabi1224 hanabi1224 added this pull request to the merge queue Jul 3, 2026
Merged via the queue into main with commit f79ff79 Jul 3, 2026
34 checks passed
@hanabi1224 hanabi1224 deleted the hm/optimize-genesis-loading branch July 3, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RPC requires calibnet RPC checks to run on CI Snapshot Run snapshot tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

eth_getBlockByNumber is slow for epoch 0

2 participants