Add support for the Filecoin.EthGetBalance V2#6403
Conversation
WalkthroughAdds a V2 RPC method for Filecoin.EthGetBalance (accepting ExtBlockNumberOrHash) and refactors shared balance lookup into a new helper used by both v1 and v2. Registers the new method, expands tests for v2, and updates snapshots and changelog. Changes
Sequence Diagram(s)sequenceDiagram participant Client participant RPC_Server participant TipsetResolver participant StateStore participant ActorLookup Client->>RPC_Server: filecoin_eth_getBalance(address, blockParam) (v2) RPC_Server->>TipsetResolver: resolve blockParam (tipset_by_block_number_or_hash_v2) TipsetResolver-->>RPC_Server: tipset / block state RPC_Server->>StateStore: construct state at tipset StateStore->>ActorLookup: load actor by converted EthAddress ActorLookup-->>StateStore: actor (or none) StateStore-->>RPC_Server: balance (bigint) or zero RPC_Server-->>Client: EthBigInt(balance) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @src/tool/subcommands/api_cmd/api_compare_tests.rs: - Around line 1645-1715: Add an `offline` parameter to eth_tests_with_tipset and gate the ExtPredefined::Safe and ExtPredefined::Finalized EthGetBalanceV2 tests behind `if !offline`; specifically, update the eth_tests_with_tipset signature to accept the same offline boolean used by chain_tests_with_tipset, propagate the caller’s offline value into eth_tests_with_tipset, and wrap the RpcTest::basic requests that use ExtPredefined::Safe and ExtPredefined::Finalized so they are only pushed when `!offline` (similar to the gating in chain_tests_with_tipset); reference functions/types: eth_tests_with_tipset, chain_tests_with_tipset, EthGetBalanceV2::request, ExtPredefined::Safe, ExtPredefined::Finalized, and get_latest_finalized_tipset for consistency with existing finality handling. 📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
CHANGELOG.mdsrc/rpc/methods/eth.rssrc/rpc/mod.rssrc/tool/subcommands/api_cmd/api_compare_tests.rssrc/tool/subcommands/api_cmd/test_snapshots.txt
🧰 Additional context used
🧠 Learnings (5)
📚 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/rpc/mod.rssrc/rpc/methods/eth.rssrc/tool/subcommands/api_cmd/api_compare_tests.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/rpc/mod.rssrc/rpc/methods/eth.rssrc/tool/subcommands/api_cmd/api_compare_tests.rs
📚 Learning: 2025-09-02T14:23:53.808Z
Learnt from: akaladarshi Repo: ChainSafe/forest PR: 5923 File: src/tool/subcommands/api_cmd/test_snapshots.txt:206-252 Timestamp: 2025-09-02T14:23:53.808Z Learning: In the Forest project, .rpcsnap.json.zst snapshot files listed in src/tool/subcommands/api_cmd/test_snapshots.txt are not stored in the repository itself but are downloaded from a DigitalOcean (DO) bucket when needed. The manifest file serves as an index/catalog of available snapshots. Applied to files:
src/tool/subcommands/api_cmd/test_snapshots.txt
📚 Learning: 2025-08-25T14:11:10.790Z
Learnt from: hanabi1224 Repo: ChainSafe/forest PR: 5978 File: .github/workflows/unit-tests.yml:86-96 Timestamp: 2025-08-25T14:11:10.790Z Learning: hanabi1224's RPC snapshot tests include a checksum validation mechanism that compares against HTTP HEAD headers, automatically re-downloading snapshots if the cached version doesn't match, providing protection against corrupted cached files. Applied to files:
src/tool/subcommands/api_cmd/test_snapshots.txt
📚 Learning: 2025-09-02T10:05:34.350Z
Learnt from: akaladarshi Repo: ChainSafe/forest PR: 5923 File: src/rpc/registry/actors/miner.rs:221-223 Timestamp: 2025-09-02T10:05:34.350Z Learning: For miner actor ChangeOwnerAddress and ChangeOwnerAddressExported methods: versions 8-10 use bare Address as parameter type, while versions 11+ use ChangeOwnerAddressParams. This reflects the evolution of the Filecoin miner actor parameter structures across versions. Applied to files:
src/rpc/methods/eth.rs
🧬 Code graph analysis (1)
src/tool/subcommands/api_cmd/api_compare_tests.rs (1)
src/rpc/methods/eth.rs (11)
from_str(285-287)from_str(393-404)from_str(453-472)from_block_number(366-368)from_block_number(426-428)from_block_number_object(377-381)from_block_number_object(437-441)from_block_hash_object(386-391)from_block_hash_object(446-451)from_predefined(362-364)from_predefined(422-424)
⏰ 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). (3)
- GitHub Check: Coverage
- GitHub Check: Build forest binaries on Linux AMD64
- GitHub Check: tests-release
🔇 Additional comments (6)
CHANGELOG.md (1)
40-41: LGTM!The changelog entry follows the established format and is correctly placed in the "Added" section alongside other API v2 implementations.
src/tool/subcommands/api_cmd/test_snapshots.txt (1)
62-62: LGTM!The new snapshot file for
EthGetBalanceV2follows the established naming convention and is correctly placed in alphabetical order. Based on learnings, these snapshots are downloaded from the DigitalOcean bucket when needed for testing.src/rpc/mod.rs (1)
112-113: LGTM!The
EthGetBalanceV2method is correctly registered in thefor_each_rpc_methodmacro, following the established pattern where V2 methods are placed immediately after their V1 counterparts. This is consistent with other V2 methods likeEthCallV2,EthEstimateGasV2,EthFeeHistoryV2, andEthGetTransactionCountV2.src/rpc/methods/eth.rs (3)
871-882: Nice dedup: EthGetBalance now delegates to shared helper.
885-905: EthGetBalanceV2 wiring looks consistent (V2 path + ExtBlockNumberOrHash + shared helper).
907-916: Please verify “missing account” semantics (error vs zero) match Lotus/Ethereum expectations.
eth_get_balancecurrently usesstate.get_required_actor(&fil_addr)?;, so a non-existent actor becomes an error. If Lotus returns0x0for unknown accounts (Ethereum common behavior), Forest would diverge.Possible adjustment (only if Lotus expects “0 for missing”)
fn eth_get_balance<DB: Blockstore>( ctx: &Ctx<DB>, address: &EthAddress, ts: &Tipset, ) -> Result<EthBigInt> { let fil_addr = address.to_filecoin_address()?; let state = StateTree::new_from_root(ctx.store_owned(), ts.parent_state())?; - let actor = state.get_required_actor(&fil_addr)?; - Ok(EthBigInt(actor.balance.atto().clone())) + match state.get_actor(&fil_addr)? { + Some(actor) => Ok(EthBigInt(actor.balance.atto().clone())), + None => Ok(EthBigInt(BigInt::zero())), + } }
Codecov Report❌ Patch coverage is
Additional details and impacted files
... and 9 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
| @sudo-shashank One small question, should we specify in the description if the API is |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/rpc/methods/eth.rs
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-09-02T10:05:34.350Z
Learnt from: akaladarshi Repo: ChainSafe/forest PR: 5923 File: src/rpc/registry/actors/miner.rs:221-223 Timestamp: 2025-09-02T10:05:34.350Z Learning: For miner actor ChangeOwnerAddress and ChangeOwnerAddressExported methods: versions 8-10 use bare Address as parameter type, while versions 11+ use ChangeOwnerAddressParams. This reflects the evolution of the Filecoin miner actor parameter structures across versions. Applied to files:
src/rpc/methods/eth.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/rpc/methods/eth.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/rpc/methods/eth.rs
⏰ 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). (9)
- GitHub Check: cargo-publish-dry-run
- GitHub Check: rubocop
- GitHub Check: Build Ubuntu
- GitHub Check: Build MacOS
- GitHub Check: Build forest binaries on Linux AMD64
- GitHub Check: All lint checks
- GitHub Check: Coverage
- GitHub Check: tests-release
- GitHub Check: Check
🔇 Additional comments (3)
src/rpc/methods/eth.rs (3)
867-868: LGTM!The DESCRIPTION constant addition is appropriate and consistent with other RPC methods in the file.
882-883: LGTM!Clean refactor to use the shared helper function, maintaining the same behavior while enabling code reuse with V2.
887-909: LGTM!The V2 implementation correctly follows the established pattern for other V2 methods in this codebase:
- Uses
ExtBlockNumberOrHashwhich supportssafeandfinalizedblock tags- Uses the async
tipset_by_block_number_or_hash_v2for proper handling of extended predefined blocks- Shares the common
eth_get_balancehelper with V1- API paths correctly restricted to V2 only
Not required I feel, we can add it later if required for all the V2 API |
Summary of changes
Changes introduced in this pull request:
Filecoin.EthGetBalanceV2 and added test.Reference issue to close (if applicable)
Closes #6293
Other information and links
Change checklist
Summary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.