Skip to content

feat(api): implement the ChainGetFinalizedTipset API - #6133

Merged
akaladarshi merged 3 commits into
mainfrom
akaladarshi/add-chain-get-finalized-tipset-api
Oct 9, 2025
Merged

feat(api): implement the ChainGetFinalizedTipset API#6133
akaladarshi merged 3 commits into
mainfrom
akaladarshi/add-chain-get-finalized-tipset-api

Conversation

@akaladarshi

@akaladarshiakaladarshi commented Oct 7, 2025

Copy link
Copy Markdown
Contributor

Summary of changes

Changes introduced in this pull request:

  • Adds implementation for the ChainGetFinalizedTipset API
  • Adds snapshot tests for the ChainGetFinalizedTipset API:
    • The test only verifies basic check since it is dependent on F3 and the latest tipset.

Reference issue to close (if applicable)

Closes#6113

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

  • New Features
    • Finalized tipset retrieval now prefers the latest network certificate when available, with automatic fallback to consensus finality for reliability.
  • Bug Fixes
    • Replaced a stubbed finalized-tipset response with real resolution logic and improved error handling and logging to avoid incorrect or empty results.
  • Tests
    • Added an API test for finalized tipset retrieval and expanded snapshot data to cover the new behavior.

@akaladarshi
akaladarshi requested a review from a team as a code ownerOctober 7, 2025 09:30
@akaladarshi
akaladarshi requested review from elmattic and removed request for a teamOctober 7, 2025 09:30
@akaladarshiakaladarshi added the RPC requires calibnet RPC checks to run on CI label Oct 7, 2025
@coderabbitai

coderabbitaiBot commented Oct 7, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Replaces the stubbed ChainGetFinalizedTipset handler with real finality resolution: computes EC finality epoch from the heaviest tipset, attempts F3 finality via a new helper, and falls back to EC finality on errors. Expands RPC handler contexts to require Send + Sync + 'static, exposes get_rpc_http_client publicly, and adds an API compare test plus snapshot.

Changes

Cohort / File(s)Summary
RPC: Chain finality resolution
src/rpc/methods/chain.rs
Replaces stub with real logic: compute EC finality epoch from heaviest tipset; try F3 finality via new get_f3_finality_tipset helper; if F3 missing/invalid/logged error, fall back to loading EC finality tipset from chain index. Updates handle signature to accept Ctx<impl Blockstore + Send + Sync + 'static> and adds debug/warn logging.
RPC: F3 client and handler context
src/rpc/methods/f3.rs
Widens F3GetLatestCertificate::handle context to Send + Sync + 'static. Makes get_rpc_http_client public (pub fn get_rpc_http_client() -> anyhow::Result<...>).
Tests: API compare
src/tool/subcommands/api_cmd/api_compare_tests.rs
Adds ChainGetFinalizedTipset request to chain_tests_with_tipset via RpcTest::basic(ChainGetFinalizedTipset::request(())?).
Test data: snapshots
src/tool/subcommands/api_cmd/test_snapshots.txt
Adds new snapshot entry: filecoin_chaingetfinalizedtipset_1759828121342574.rpcsnap.json.zst.

Sequence Diagram(s)

sequenceDiagram
autonumber
participant Client
participant RPC as ChainGetFinalizedTipset
participant Ctx as Node/Ctx
participant CI as ChainIndex
participant F3 as F3 service
Client->>RPC: ChainGetFinalizedTipset()
RPC->>Ctx: fetch heaviest tipset
RPC->>CI: compute EC finality epoch
RPC->>F3: request latest certificate + head
alt F3 certificate present and head >= EC epoch
RPC->>CI: load tipset at F3 head
CI-->>RPC: F3 finalized tipset
RPC-->>Client: return F3 finalized tipset
else F3 missing/invalid/error
Note over RPC: warn and fallback to EC finality
RPC->>CI: load tipset at EC finality epoch
CI-->>RPC: EC finalized tipset
RPC-->>Client: return EC finalized tipset
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • sudo-shashank
  • AlexeyKrasnoperov

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title Check✅ PassedThe title succinctly and accurately summarizes the primary change by indicating the addition of the ChainGetFinalizedTipset API, matching both the implementation details in the code and the intent of the pull request. It is clear, concise, and follows conventional commit style without extraneous information.
Linked Issues Check✅ PassedThe pull request implements the ChainGetFinalizedTipset handler with multi-path finality logic, integrates necessary Blockstore context support, and adds corresponding tests and snapshots, fully satisfying the coding requirements of issue #6113 to support the new v1 API endpoint.
Out of Scope Changes Check✅ PassedAll code modifications, including expanded context bounds in f3 handlers and making the HTTP client helper public, directly support the new ChainGetFinalizedTipset implementation or its testing infrastructure, and there are no unrelated or extraneous changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch akaladarshi/add-chain-get-finalized-tipset-api

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

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

Actionable comments posted: 0

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

151-165: Include error context in the fallback warning.

When we drop into the EC path we lose the original failure reason, which makes field debugging harder. Please log the error (e.g. with tracing::warn!(error = %err, ...)) before falling back.

- match get_f3_finality_tipset(&ctx, ec_finality_epoch).await {+ match get_f3_finality_tipset(&ctx, ec_finality_epoch).await {
Ok(f3_tipset) => {
tracing::debug!("Using F3 finalized tipset at epoch {}", f3_tipset.epoch());
Ok((*f3_tipset).clone())
}
- Err(_) => {- // fallback to ec finality- tracing::warn!("F3 finalization unavailable, falling back to EC finality");+ Err(error) => {+ // fallback to ec finality+ tracing::warn!(+ error = %error,+ "F3 finalization unavailable, falling back to EC finality"+ );
let ec_tipset = ctx.chain_index().tipset_by_height(
ec_finality_epoch,
head,
ResolveNullTipset::TakeOlder,
)?;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c046fb0 and b215a7d.

📒 Files selected for processing (4)
  • src/rpc/methods/chain.rs (1 hunks)
  • src/rpc/methods/f3.rs (2 hunks)
  • src/tool/subcommands/api_cmd/api_compare_tests.rs (1 hunks)
  • src/tool/subcommands/api_cmd/test_snapshots.txt (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/tool/subcommands/api_cmd/api_compare_tests.rs (2)
src/rpc/reflect/mod.rs (1)
  • request (250-260)
src/rpc/client.rs (1)
  • request (272-285)
src/rpc/methods/chain.rs (1)
src/blocks/tipset.rs (2)
  • epoch (306-308)
  • epoch (543-545)
src/rpc/methods/f3.rs (1)
src/rpc/methods/state.rs (16)
  • handle (109-114)
  • handle (132-138)
  • handle (151-157)
  • handle (172-178)
  • handle (196-205)
  • handle (223-231)
  • handle (248-255)
  • handle (272-282)
  • handle (298-305)
  • handle (335-465)
  • handle (484-492)
  • handle (508-538)
  • handle (555-561)
  • handle (577-597)
  • handle (615-624)
  • handle (641-663)
⏰ 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). (7)
  • GitHub Check: Build Ubuntu
  • GitHub Check: cargo-publish-dry-run
  • GitHub Check: Build MacOS
  • GitHub Check: All lint checks
  • GitHub Check: tests
  • GitHub Check: tests-release
  • GitHub Check: Build forest binaries on Linux AMD64

Comment threadsrc/rpc/methods/chain.rs Outdated
(): Self::Params,
) -> Result<Self::Ok, ServerError> {
let head = ctx.chain_store().heaviest_tipset();
let ec_finality_epoch = head.epoch() - ctx.chain_config().policy.chain_finality;

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.

Suggested change
let ec_finality_epoch = head.epoch() - ctx.chain_config().policy.chain_finality;
let ec_finality_epoch = (head.epoch() - ctx.chain_config().policy.chain_finality).max(0);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

match get_f3_finality_tipset(&ctx, ec_finality_epoch).await {
Ok(f3_tipset) => {
tracing::debug!("Using F3 finalized tipset at epoch {}", f3_tipset.epoch());
Ok((*f3_tipset).clone())

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.

Could we avoid cloning here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think so f3_tipset wrapped in Arc so we will have to clone only.

.await
.map_err(|e| anyhow::anyhow!("Failed to get F3 certificate: {}", e))?;

let f3_finalized_head = f3_finalized_cert.chain_head();

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.

f3_finalized_cert.chain_head() could be newer than chain head during catchup. Lotus does not seem to handle that case, should we handle it? e.g. marking finalized tipset in F3.Finalize RPC method instead.

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.

We could track this in a separate issue, for now the logic matches Lotus

@akaladarshi
akaladarshiforce-pushed the akaladarshi/add-chain-get-finalized-tipset-api branch from b215a7d to de68dc2CompareOctober 8, 2025 13:25

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

Actionable comments posted: 0

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

143-167: LGTM! Well-structured finality resolution with F3 primary and EC fallback.

The implementation correctly:

  • Computes EC finality epoch with .max(0) to prevent negative values
  • Attempts F3 finality first via the new helper
  • Falls back to EC finality on errors with appropriate logging

Optional: Log the discarded error for easier debugging.

Currently, the error from get_f3_finality_tipset (line 156) is silently discarded. Consider logging it at debug level to aid troubleshooting:

 match get_f3_finality_tipset(&ctx, ec_finality_epoch).await {
Ok(f3_tipset) => {
tracing::debug!("Using F3 finalized tipset at epoch {}", f3_tipset.epoch());
Ok((*f3_tipset).clone())
}
- Err(_) => {+ Err(e) => {
// fallback to ec finality
- tracing::warn!("F3 finalization unavailable, falling back to EC finality");+ tracing::warn!("F3 finalization unavailable, falling back to EC finality: {}", e);
let ec_tipset = ctx.chain_index().tipset_by_height(
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b215a7d and de68dc2.

📒 Files selected for processing (4)
  • src/rpc/methods/chain.rs (1 hunks)
  • src/rpc/methods/f3.rs (2 hunks)
  • src/tool/subcommands/api_cmd/api_compare_tests.rs (1 hunks)
  • src/tool/subcommands/api_cmd/test_snapshots.txt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/tool/subcommands/api_cmd/api_compare_tests.rs
  • src/tool/subcommands/api_cmd/test_snapshots.txt
🧰 Additional context used
🧬 Code graph analysis (2)
src/rpc/methods/chain.rs (2)
src/rpc/methods/state.rs (16)
  • handle (109-114)
  • handle (132-138)
  • handle (151-157)
  • handle (172-178)
  • handle (196-205)
  • handle (223-231)
  • handle (248-255)
  • handle (272-282)
  • handle (298-305)
  • handle (335-465)
  • handle (484-492)
  • handle (508-538)
  • handle (555-561)
  • handle (577-597)
  • handle (615-624)
  • handle (641-663)
src/blocks/tipset.rs (2)
  • epoch (306-308)
  • epoch (543-545)
src/rpc/methods/f3.rs (1)
src/rpc/methods/state.rs (16)
  • handle (109-114)
  • handle (132-138)
  • handle (151-157)
  • handle (172-178)
  • handle (196-205)
  • handle (223-231)
  • handle (248-255)
  • handle (272-282)
  • handle (298-305)
  • handle (335-465)
  • handle (484-492)
  • handle (508-538)
  • handle (555-561)
  • handle (577-597)
  • handle (615-624)
  • handle (641-663)
⏰ 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). (7)
  • GitHub Check: tests
  • GitHub Check: tests-release
  • GitHub Check: All lint checks
  • GitHub Check: Build forest binaries on Linux AMD64
  • GitHub Check: cargo-publish-dry-run
  • GitHub Check: Build MacOS
  • GitHub Check: Build Ubuntu
🔇 Additional comments (3)
src/rpc/methods/f3.rs (2)

701-704: LGTM! Signature update enables cross-thread async usage.

Adding Send + Sync + 'static bounds aligns with other async RPC handlers (e.g., StateCall, StateReplay in state.rs) and is necessary for calling this method from ChainGetFinalizedTipset in chain.rs.


954-954: LGTM! Visibility change supports cross-module usage.

Exposing get_rpc_http_client publicly enables the new ChainGetFinalizedTipset implementation in chain.rs to interact with the F3 sidecar.

src/rpc/methods/chain.rs (1)

170-197: LGTM! Robust F3 finality helper with proper validation.

The helper correctly:

  • Fetches the latest F3 certificate via F3GetLatestCertificate::handle
  • Validates that F3 finality is not behind EC finality (lines 180-186)
  • Loads the corresponding tipset from the chain index
  • Provides descriptive error messages for debugging

@akaladarshi
akaladarshi added this pull request to the merge queueOct 9, 2025
Merged via the queue into main with commit 4661ae8Oct 9, 2025
40 checks passed
@akaladarshi
akaladarshi deleted the akaladarshi/add-chain-get-finalized-tipset-api branch October 9, 2025 07:58
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.

Implement ChainGetFinalizedTipset API

3 participants

@akaladarshi@hanabi1224@elmattic