Skip to content

Commit 0af174d

Browse files
Add support for the Filecoin.EthGetTransactionCount V2 (#6387)
1 parent a4d6142 commit 0af174d

5 files changed

Lines changed: 111 additions & 19 deletions

File tree

CHANGELOG.md

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

3636
- [#6380](https://github.com/ChainSafe/forest/pull/6380) Implemented `Filecoin.EthFeeHistory` for API v2.
3737

38+
- [#6387](https://github.com/ChainSafe/forest/pull/6387) Implemented `Filecoin.EthGetTransactionCount` for API v2.
39+
3840
### Changed
3941

4042
### Removed

src/rpc/methods/eth.rs

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,33 +2393,78 @@ impl RpcMethod<2> for EthGetTransactionCount {
23932393
(sender, block_param): Self::Params,
23942394
) -> Result<Self::Ok, ServerError> {
23952395
let addr = sender.to_filecoin_address()?;
2396-
if let BlockNumberOrHash::PredefinedBlock(ref predefined) = block_param
2397-
&& *predefined == Predefined::Pending
2398-
{
2399-
return Ok(EthUint64(ctx.mpool.get_sequence(&addr)?));
2396+
match block_param {
2397+
BlockNumberOrHash::PredefinedBlock(Predefined::Pending) => {
2398+
Ok(EthUint64(ctx.mpool.get_sequence(&addr)?))
2399+
}
2400+
_ => {
2401+
let ts = tipset_by_block_number_or_hash(
2402+
ctx.chain_store(),
2403+
block_param,
2404+
ResolveNullTipset::TakeOlder,
2405+
)?;
2406+
eth_get_transaction_count(&ctx, &ts, addr).await
2407+
}
24002408
}
2401-
let ts = tipset_by_block_number_or_hash(
2402-
ctx.chain_store(),
2403-
block_param.clone(),
2404-
ResolveNullTipset::TakeOlder,
2405-
)?;
2409+
}
2410+
}
24062411

2407-
let (state_cid, _) = ctx.state_manager.tipset_state(&ts).await?;
2412+
pub enum EthGetTransactionCountV2 {}
2413+
impl RpcMethod<2> for EthGetTransactionCountV2 {
2414+
const NAME: &'static str = "Filecoin.EthGetTransactionCount";
2415+
const NAME_ALIAS: Option<&'static str> = Some("eth_getTransactionCount");
2416+
const PARAM_NAMES: [&'static str; 2] = ["sender", "blockParam"];
2417+
const API_PATHS: BitFlags<ApiPaths> = make_bitflags!(ApiPaths::V2);
2418+
const PERMISSION: Permission = Permission::Read;
2419+
2420+
type Params = (EthAddress, ExtBlockNumberOrHash);
2421+
type Ok = EthUint64;
24082422

2409-
let state = StateTree::new_from_root(ctx.store_owned(), &state_cid)?;
2410-
let actor = state.get_required_actor(&addr)?;
2411-
if is_evm_actor(&actor.code) {
2412-
let evm_state = evm::State::load(ctx.store(), actor.code, actor.state)?;
2413-
if !evm_state.is_alive() {
2414-
return Ok(EthUint64(0));
2423+
async fn handle(
2424+
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
2425+
(sender, block_param): Self::Params,
2426+
) -> Result<Self::Ok, ServerError> {
2427+
let addr = sender.to_filecoin_address()?;
2428+
match block_param {
2429+
ExtBlockNumberOrHash::PredefinedBlock(ExtPredefined::Pending) => {
2430+
Ok(EthUint64(ctx.mpool.get_sequence(&addr)?))
2431+
}
2432+
_ => {
2433+
let ts = tipset_by_block_number_or_hash_v2(
2434+
&ctx,
2435+
block_param,
2436+
ResolveNullTipset::TakeOlder,
2437+
)
2438+
.await?;
2439+
eth_get_transaction_count(&ctx, &ts, addr).await
24152440
}
2416-
Ok(EthUint64(evm_state.nonce()))
2417-
} else {
2418-
Ok(EthUint64(actor.sequence))
24192441
}
24202442
}
24212443
}
24222444

2445+
async fn eth_get_transaction_count<B>(
2446+
ctx: &Ctx<B>,
2447+
ts: &Tipset,
2448+
addr: FilecoinAddress,
2449+
) -> Result<EthUint64, ServerError>
2450+
where
2451+
B: Blockstore + Send + Sync + 'static,
2452+
{
2453+
let (state_cid, _) = ctx.state_manager.tipset_state(ts).await?;
2454+
2455+
let state = StateTree::new_from_root(ctx.store_owned(), &state_cid)?;
2456+
let actor = state.get_required_actor(&addr)?;
2457+
if is_evm_actor(&actor.code) {
2458+
let evm_state = evm::State::load(ctx.store(), actor.code, actor.state)?;
2459+
if !evm_state.is_alive() {
2460+
return Ok(EthUint64(0));
2461+
}
2462+
Ok(EthUint64(evm_state.nonce()))
2463+
} else {
2464+
Ok(EthUint64(actor.sequence))
2465+
}
2466+
}
2467+
24232468
pub enum EthMaxPriorityFeePerGas {}
24242469
impl RpcMethod<0> for EthMaxPriorityFeePerGas {
24252470
const NAME: &'static str = "Filecoin.EthMaxPriorityFeePerGas";

src/rpc/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ macro_rules! for_each_rpc_method {
125125
$callback!($crate::rpc::eth::EthGetTransactionByHash);
126126
$callback!($crate::rpc::eth::EthGetTransactionByHashLimited);
127127
$callback!($crate::rpc::eth::EthGetTransactionCount);
128+
$callback!($crate::rpc::eth::EthGetTransactionCountV2);
128129
$callback!($crate::rpc::eth::EthGetTransactionHashByCid);
129130
$callback!($crate::rpc::eth::EthGetTransactionByBlockNumberAndIndex);
130131
$callback!($crate::rpc::eth::EthGetTransactionByBlockHashAndIndex);

src/tool/subcommands/api_cmd/api_compare_tests.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,49 @@ fn eth_tests_with_tipset<DB: Blockstore>(store: &Arc<DB>, shared_tipset: &Tipset
17571757
))
17581758
.unwrap(),
17591759
),
1760+
RpcTest::identity(
1761+
EthGetTransactionCountV2::request((
1762+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1763+
ExtBlockNumberOrHash::from_block_hash_object(block_hash.clone(), true),
1764+
))
1765+
.unwrap(),
1766+
),
1767+
RpcTest::identity(
1768+
EthGetTransactionCountV2::request((
1769+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1770+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Earliest),
1771+
))
1772+
.unwrap(),
1773+
)
1774+
.policy_on_rejected(PolicyOnRejected::PassWithQuasiIdenticalError),
1775+
RpcTest::basic(
1776+
EthGetTransactionCountV2::request((
1777+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1778+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Pending),
1779+
))
1780+
.unwrap(),
1781+
),
1782+
RpcTest::basic(
1783+
EthGetTransactionCountV2::request((
1784+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1785+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Latest),
1786+
))
1787+
.unwrap(),
1788+
),
1789+
RpcTest::basic(
1790+
EthGetTransactionCountV2::request((
1791+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1792+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Safe),
1793+
))
1794+
.unwrap(),
1795+
),
1796+
RpcTest::basic(
1797+
EthGetTransactionCountV2::request((
1798+
EthAddress::from_str("0xff000000000000000000000000000000000003ec").unwrap(),
1799+
ExtBlockNumberOrHash::from_predefined(ExtPredefined::Finalized),
1800+
))
1801+
.unwrap(),
1802+
),
17601803
RpcTest::identity(
17611804
EthGetStorageAt::request((
17621805
// https://filfox.info/en/address/f410fpoidg73f7krlfohnla52dotowde5p2sejxnd4mq

src/tool/subcommands/api_cmd/test_snapshots.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ filecoin_ethgettransactionbyblocknumberandindex_1740132538304408.rpcsnap.json.zs
7878
filecoin_ethgettransactionbyhash_1741272955520821.rpcsnap.json.zst
7979
filecoin_ethgettransactionbyhashlimited_1741272955509708.rpcsnap.json.zst
8080
filecoin_ethgettransactioncount_1740132538183426.rpcsnap.json.zst
81+
filecoin_ethgettransactioncount_v2_1767847407595348.rpcsnap.json.zst
8182
filecoin_ethgettransactionhashbycid_1737446676698540.rpcsnap.json.zst
8283
filecoin_ethgettransactionreceipt_1741272955712904.rpcsnap.json.zst
8384
filecoin_ethgettransactionreceipt_1765811578590165.rpcsnap.json.zst # transaction not found

0 commit comments

Comments
 (0)