Skip to content

Commit 7d9b1b1

Browse files
Add support for the Filecoin.EthGetBalance V2 (#6403)
1 parent 5547983 commit 7d9b1b1

File tree

5 files changed

+114
-4
lines changed

5 files changed

+114
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737

3838
- [#6387](https://github.com/ChainSafe/forest/pull/6387) Implemented `Filecoin.EthGetTransactionCount` for API v2.
3939

40+
- [#6403](https://github.com/ChainSafe/forest/pull/6403) Implemented `Filecoin.EthGetBalance` for API v2.
41+
4042
### Changed
4143

4244
- [#6368](https://github.com/ChainSafe/forest/pull/6368): Migrated build and development tooling from Makefile to `mise`. Contributors should install `mise` and use `mise run` commands instead of `make` commands.

src/rpc/methods/eth.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,8 @@ impl RpcMethod<2> for EthGetBalance {
864864
const PARAM_NAMES: [&'static str; 2] = ["address", "blockParam"];
865865
const API_PATHS: BitFlags<ApiPaths> = ApiPaths::all();
866866
const PERMISSION: Permission = Permission::Read;
867+
const DESCRIPTION: Option<&'static str> =
868+
Some("Returns the balance of an Ethereum address at the specified block state");
867869

868870
type Params = (EthAddress, BlockNumberOrHash);
869871
type Ok = EthBigInt;
@@ -872,18 +874,51 @@ impl RpcMethod<2> for EthGetBalance {
872874
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
873875
(address, block_param): Self::Params,
874876
) -> Result<Self::Ok, ServerError> {
875-
let fil_addr = address.to_filecoin_address()?;
876877
let ts = tipset_by_block_number_or_hash(
877878
ctx.chain_store(),
878879
block_param,
879880
ResolveNullTipset::TakeOlder,
880881
)?;
881-
let state = StateTree::new_from_root(ctx.store_owned(), ts.parent_state())?;
882-
let actor = state.get_required_actor(&fil_addr)?;
883-
Ok(EthBigInt(actor.balance.atto().clone()))
882+
let balance = eth_get_balance(&ctx, &address, &ts)?;
883+
Ok(balance)
884884
}
885885
}
886886

887+
pub enum EthGetBalanceV2 {}
888+
impl RpcMethod<2> for EthGetBalanceV2 {
889+
const NAME: &'static str = "Filecoin.EthGetBalance";
890+
const NAME_ALIAS: Option<&'static str> = Some("eth_getBalance");
891+
const PARAM_NAMES: [&'static str; 2] = ["address", "blockParam"];
892+
const API_PATHS: BitFlags<ApiPaths> = make_bitflags!(ApiPaths::V2);
893+
const PERMISSION: Permission = Permission::Read;
894+
const DESCRIPTION: Option<&'static str> =
895+
Some("Returns the balance of an Ethereum address at the specified block state");
896+
897+
type Params = (EthAddress, ExtBlockNumberOrHash);
898+
type Ok = EthBigInt;
899+
900+
async fn handle(
901+
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
902+
(address, block_param): Self::Params,
903+
) -> Result<Self::Ok, ServerError> {
904+
let ts = tipset_by_block_number_or_hash_v2(&ctx, block_param, ResolveNullTipset::TakeOlder)
905+
.await?;
906+
let balance = eth_get_balance(&ctx, &address, &ts)?;
907+
Ok(balance)
908+
}
909+
}
910+
911+
fn eth_get_balance<DB: Blockstore>(
912+
ctx: &Ctx<DB>,
913+
address: &EthAddress,
914+
ts: &Tipset,
915+
) -> Result<EthBigInt> {
916+
let fil_addr = address.to_filecoin_address()?;
917+
let state = StateTree::new_from_root(ctx.store_owned(), ts.parent_state())?;
918+
let actor = state.get_required_actor(&fil_addr)?;
919+
Ok(EthBigInt(actor.balance.atto().clone()))
920+
}
921+
887922
fn get_tipset_from_hash<DB: Blockstore>(
888923
chain_store: &ChainStore<DB>,
889924
block_hash: &EthHash,

src/rpc/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ macro_rules! for_each_rpc_method {
110110
$callback!($crate::rpc::eth::EthFeeHistoryV2);
111111
$callback!($crate::rpc::eth::EthGasPrice);
112112
$callback!($crate::rpc::eth::EthGetBalance);
113+
$callback!($crate::rpc::eth::EthGetBalanceV2);
113114
$callback!($crate::rpc::eth::EthGetBlockByHash);
114115
$callback!($crate::rpc::eth::EthGetBlockByNumber);
115116
$callback!($crate::rpc::eth::EthGetBlockReceipts);

src/tool/subcommands/api_cmd/api_compare_tests.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,6 +1642,77 @@ fn eth_tests_with_tipset<DB: Blockstore>(store: &Arc<DB>, shared_tipset: &Tipset
16421642
))
16431643
.unwrap(),
16441644
),
1645+
RpcTest::identity(
1646+
EthGetBalanceV2::request((
1647+
EthAddress::from_str("0xff38c072f286e3b20b3954ca9f99c05fbecc64aa").unwrap(),
1648+
ExtBlockNumberOrHash::from_block_number(shared_tipset.epoch()),
1649+
))
1650+
.unwrap(),
1651+
),
1652+
RpcTest::identity(
1653+
EthGetBalanceV2::request((
1654+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1655+
ExtBlockNumberOrHash::from_block_number(shared_tipset.epoch()),
1656+
))
1657+
.unwrap(),
1658+
),
1659+
RpcTest::identity(
1660+
EthGetBalanceV2::request((
1661+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1662+
ExtBlockNumberOrHash::from_block_number_object(shared_tipset.epoch()),
1663+
))
1664+
.unwrap(),
1665+
),
1666+
RpcTest::identity(
1667+
EthGetBalanceV2::request((
1668+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1669+
ExtBlockNumberOrHash::from_block_hash_object(block_hash.clone(), false),
1670+
))
1671+
.unwrap(),
1672+
),
1673+
RpcTest::identity(
1674+
EthGetBalanceV2::request((
1675+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1676+
ExtBlockNumberOrHash::from_block_hash_object(block_hash.clone(), true),
1677+
))
1678+
.unwrap(),
1679+
),
1680+
RpcTest::identity(
1681+
EthGetBalanceV2::request((
1682+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1683+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Earliest),
1684+
))
1685+
.unwrap(),
1686+
)
1687+
.policy_on_rejected(PolicyOnRejected::PassWithQuasiIdenticalError),
1688+
RpcTest::basic(
1689+
EthGetBalanceV2::request((
1690+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1691+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Pending),
1692+
))
1693+
.unwrap(),
1694+
),
1695+
RpcTest::basic(
1696+
EthGetBalanceV2::request((
1697+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1698+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Latest),
1699+
))
1700+
.unwrap(),
1701+
),
1702+
RpcTest::basic(
1703+
EthGetBalanceV2::request((
1704+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1705+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Safe),
1706+
))
1707+
.unwrap(),
1708+
),
1709+
RpcTest::basic(
1710+
EthGetBalanceV2::request((
1711+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1712+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Finalized),
1713+
))
1714+
.unwrap(),
1715+
),
16451716
RpcTest::identity(
16461717
EthGetBlockByNumber::request((
16471718
ExtBlockNumberOrHash::from_block_number(shared_tipset.epoch()),

src/tool/subcommands/api_cmd/test_snapshots.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ filecoin_ethfeehistory_1737446676883828.rpcsnap.json.zst
5959
filecoin_ethfeehistory_v2_1767605175056660.rpcsnap.json.zst
6060
filecoin_ethgasprice_1758725940980141.rpcsnap.json.zst
6161
filecoin_ethgetbalance_1740048634848277.rpcsnap.json.zst
62+
filecoin_ethgetbalance_v2_1768188109932986.rpcsnap.json.zst
6263
filecoin_ethgetblockbyhash_1740132537807408.rpcsnap.json.zst
6364
filecoin_ethgetblockbynumber_1737446676696328.rpcsnap.json.zst
6465
filecoin_ethgetblockreceipts_1740132537907751.rpcsnap.json.zst

0 commit comments

Comments
 (0)