Skip to content

fix: fix backfill with null tipsets present#6409

Merged
hanabi1224 merged 1 commit intomainfrom
fix-null-ts-backfill
Jan 12, 2026
Merged

fix: fix backfill with null tipsets present#6409
hanabi1224 merged 1 commit intomainfrom
fix-null-ts-backfill

Conversation

@LesnyRumcajs
Copy link
Member

@LesnyRumcajs LesnyRumcajs commented Jan 12, 2026

Summary of changes

Changes introduced in this pull request:

❯ forest-tool index backfill --from 3363360 --n-tipsets 5 --chain calibnet
2026-01-12T17:57:17.696759Z  INFO forest::daemon::db_util: Loaded 18 CARs
2026-01-12T17:57:17.696783Z  INFO forest::tool::offline_server::server: Using chain config for calibnet
2026-01-12T17:57:17.699389Z  INFO forest::genesis: Initialized genesis: bafy2bzacecyaggy24wol5ruvs6qm73gjibs2l2iyhcqmvi7r7a4ph7zx3yqd4
Database path: /home/rumcajs/.local/share/forest/calibnet/0.30.5
From epoch:    3363360
Tipsets:       5
Head epoch:    3363359
Error: looking for tipset with height greater than start point, req: 3363360, head: 3363359

due to the null tipset https://calibration.filscan.io/en/height/3363360/

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.

Summary by CodeRabbit

Bug Fixes

  • Fixed backfill issues with null tipsets by ensuring the starting epoch in indexing operations does not exceed the current head epoch.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 12, 2026

Walkthrough

This pull request adds a changelog entry documenting a backfill fix for null tipsets and modifies the indexing command to clamp the from tipset epoch to not exceed the head tipset epoch when specified, preventing potential downstream issues.

Changes

Cohort / File(s) Summary
Documentation Update
CHANGELOG.md
Added entry in Forest unreleased → Fixed section describing backfill fix for null tipsets (PR #6409)
Core Logic Fix
src/tool/subcommands/index_cmd.rs
Clamps from tipset epoch to minimum of provided value and head epoch via from = min(from, head_epoch) before passing to tipset_by_height; includes explanatory comment

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested reviewers

  • sudo-shashank
  • akaladarshi
  • hanabi1224
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: fix backfill with null tipsets present' directly summarizes the main change: fixing a backfill issue when null tipsets are present, which is the core purpose of the PR.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

@LesnyRumcajs LesnyRumcajs marked this pull request as ready for review January 12, 2026 18:14
@LesnyRumcajs LesnyRumcajs requested a review from a team as a code owner January 12, 2026 18:14
@LesnyRumcajs LesnyRumcajs requested review from hanabi1224 and sudo-shashank and removed request for a team January 12, 2026 18:14
Copy link
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: 0

🧹 Nitpick comments (1)
src/tool/subcommands/index_cmd.rs (1)

97-97: Consider updating the displayed "From epoch" to reflect the clamped value.

When the from epoch is clamped due to null tipsets at head, the output will display the original user-specified value rather than the actual clamped starting epoch. This could be slightly confusing if users notice the discrepancy.

♻️ Suggested fix
-                println!("From epoch:    {}", from.unwrap_or_else(|| head_ts.epoch()));
+                let display_from = from.map(|f| std::cmp::min(f, head_ts.epoch())).unwrap_or_else(|| head_ts.epoch());
+                println!("From epoch:    {}", display_from);

Alternatively, compute the clamped value earlier and reuse it:

+                let effective_from = from.map(|f| std::cmp::min(f, head_ts.epoch()));
+
                 println!("Database path: {}", db_root_dir.display());
-                println!("From epoch:    {}", from.unwrap_or_else(|| head_ts.epoch()));
+                println!("From epoch:    {}", effective_from.unwrap_or_else(|| head_ts.epoch()));
                 println!("{spec}");
                 println!("Head epoch:    {}", head_ts.epoch());

-                let from_ts = if let Some(from) = from {
-                    // ensure from epoch is not greater than head epoch. This can happen if the
-                    // assumed head is actually a null tipset.
-                    let from = std::cmp::min(*from, head_ts.epoch());
+                let from_ts = if let Some(from) = effective_from {
                     chain_store.chain_index().tipset_by_height(
                         from,
                         head_ts,
                         ResolveNullTipset::TakeOlder,
                     )?
                 } else {
                     head_ts
                 };
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6dae8b0 and 8904876.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • src/tool/subcommands/index_cmd.rs
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: hanabi1224
Repo: ChainSafe/forest PR: 5944
File: src/chain/store/index.rs:0-0
Timestamp: 2025-08-18T03:09:47.932Z
Learning: In Forest's tipset_by_height caching implementation, hanabi1224 prefers performance-conscious solutions that leverage finality guarantees rather than expensive chain walking for fork detection. The approach of constraining cache lookups to finalized epochs (using CHECKPOINT_INTERVAL >= CHAIN_FINALITY) provides fork safety without the performance cost of ancestry verification.
Learnt from: LesnyRumcajs
Repo: ChainSafe/forest PR: 5907
File: src/rpc/methods/state.rs:523-570
Timestamp: 2025-08-06T15:44:33.467Z
Learning: LesnyRumcajs prefers to rely on BufWriter's Drop implementation for automatic flushing rather than explicit flush() calls in Forest codebase.
📚 Learning: 2025-08-25T13:35:24.230Z
Learnt from: hanabi1224
Repo: ChainSafe/forest PR: 5969
File: src/tool/subcommands/snapshot_cmd.rs:412-412
Timestamp: 2025-08-25T13:35:24.230Z
Learning: In src/tool/subcommands/snapshot_cmd.rs, the +1 in `last_epoch = ts.epoch() - epochs as i64 + 1` fixes an off-by-1 bug where specifying --check-stateroots=N would validate N+1 epochs instead of N epochs, causing out-of-bounds errors when the snapshot contains only N recent state roots.

Applied to files:

  • src/tool/subcommands/index_cmd.rs
📚 Learning: 2025-09-16T12:55:26.955Z
Learnt from: hanabi1224
Repo: ChainSafe/forest PR: 6079
File: src/chain_sync/metrics.rs:6-7
Timestamp: 2025-09-16T12:55:26.955Z
Learning: HEAD_EPOCH references in shell scripts (like scripts/tests/calibnet_eth_mapping_check.sh) that extract data from `forest-cli info show` are unrelated to Rust metrics constants with the same name and should not be flagged when metrics cleanup is performed.

Applied to files:

  • src/tool/subcommands/index_cmd.rs
📚 Learning: 2026-01-05T12:54:40.850Z
Learnt from: hanabi1224
Repo: ChainSafe/forest PR: 6381
File: src/lotus_json/actors/states/cron_state.rs:8-8
Timestamp: 2026-01-05T12:54:40.850Z
Learning: In Rust code reviews, do not derive Eq for a struct if any field does not implement Eq (e.g., types from external dependencies). If a type like CronStateLotusJson includes fields wrapping external dependencies that lack Eq, derive PartialEq (or implement PartialEq manually) but avoid deriving Eq. This ensures comparisons compile and reflect actual equivalence semantics. When needed, consider implementing custom PartialEq (and possibly Eq) only after ensuring all fields (or wrappers) implement Eq, or keep PartialEq-only if full equality semantics cannot be expressed.

Applied to files:

  • src/tool/subcommands/index_cmd.rs
📚 Learning: 2026-01-05T12:56:13.802Z
Learnt from: hanabi1224
Repo: ChainSafe/forest PR: 6381
File: src/lotus_json/actors/states/evm_state.rs:41-44
Timestamp: 2026-01-05T12:56:13.802Z
Learning: In Rust codebases (e.g., Forest), do not add #[cfg(test)] to functions already annotated with #[test]. The #[test] attribute ensures the function is compiled only for tests, so a separate #[cfg(test)] is redundant and can be removed if present. Apply this check to all Rust files that contain #[test] functions.

Applied to files:

  • src/tool/subcommands/index_cmd.rs
📚 Learning: 2025-08-18T03:09:47.932Z
Learnt from: hanabi1224
Repo: ChainSafe/forest PR: 5944
File: src/chain/store/index.rs:0-0
Timestamp: 2025-08-18T03:09:47.932Z
Learning: In Forest's tipset_by_height caching implementation, hanabi1224 prefers performance-conscious solutions that leverage finality guarantees rather than expensive chain walking for fork detection. The approach of constraining cache lookups to finalized epochs (using CHECKPOINT_INTERVAL >= CHAIN_FINALITY) provides fork safety without the performance cost of ancestry verification.

Applied to files:

  • CHANGELOG.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Coverage
  • GitHub Check: tests-release
  • GitHub Check: Build forest binaries on Linux AMD64
  • GitHub Check: Build Ubuntu
  • GitHub Check: cargo-publish-dry-run
  • GitHub Check: Build MacOS
  • GitHub Check: All lint checks
  • GitHub Check: rubocop
🔇 Additional comments (2)
CHANGELOG.md (1)

52-53: LGTM!

The changelog entry is properly formatted, concise, and correctly placed under the "Fixed" section.

src/tool/subcommands/index_cmd.rs (1)

101-112: LGTM!

The fix correctly addresses the null tipset issue by clamping the from epoch to not exceed the head epoch. The explanatory comment clearly documents the edge case being handled. The use of std::cmp::min combined with ResolveNullTipset::TakeOlder ensures robust behavior when dealing with null tipsets.

@codecov
Copy link

codecov bot commented Jan 12, 2026

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.52%. Comparing base (6dae8b0) to head (8904876).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/tool/subcommands/index_cmd.rs 0.00% 2 Missing ⚠️
Additional details and impacted files
Files with missing lines Coverage Δ
src/tool/subcommands/index_cmd.rs 0.00% <0.00%> (ø)

... and 2 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 6dae8b0...8904876. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hanabi1224 hanabi1224 added this pull request to the merge queue Jan 12, 2026
Merged via the queue into main with commit e12b107 Jan 12, 2026
56 checks passed
@hanabi1224 hanabi1224 deleted the fix-null-ts-backfill branch January 12, 2026 22:43
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