diff --git a/CHANGELOG.md b/CHANGELOG.md index 449f5e38f1fb..ecab5d124549 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,8 @@ - [#6469](https://github.com/ChainSafe/forest/pull/6469): Implemented `Filecoin.EthGetTransactionByBlockNumberAndIndex` for API v2. +- [#6451](https://github.com/ChainSafe/forest/pull/6451): Implemented `Filecoin.EthTraceBlock` for API v2. + ### Changed - [#6471](https://github.com/ChainSafe/forest/pull/6471): Moved `forest-tool state` subcommand to `forest-dev`. diff --git a/src/rpc/methods/eth.rs b/src/rpc/methods/eth.rs index 01ab8ba1909b..07937f0ea645 100644 --- a/src/rpc/methods/eth.rs +++ b/src/rpc/methods/eth.rs @@ -3669,26 +3669,50 @@ impl RpcMethod<1> for EthTraceBlock { const PARAM_NAMES: [&'static str; 1] = ["blockParam"]; const API_PATHS: BitFlags = ApiPaths::all(); const PERMISSION: Permission = Permission::Read; + const DESCRIPTION: Option<&'static str> = Some("Returns traces created at given block."); + type Params = (ExtBlockNumberOrHash,); type Ok = Vec; async fn handle( ctx: Ctx, (block_param,): Self::Params, ) -> Result { - trace_block(ctx, block_param).await + let ts = tipset_by_ext_block_number_or_hash( + ctx.chain_store(), + block_param, + ResolveNullTipset::TakeOlder, + )?; + eth_trace_block(&ctx, &ts).await } } -async fn trace_block( - ctx: Ctx, - block_param: ExtBlockNumberOrHash, -) -> Result, ServerError> { - let ts = tipset_by_ext_block_number_or_hash( - ctx.chain_store(), - block_param, - ResolveNullTipset::TakeOlder, - )?; - let (state_root, trace) = ctx.state_manager.execution_trace(&ts)?; +pub enum EthTraceBlockV2 {} +impl RpcMethod<1> for EthTraceBlockV2 { + const NAME: &'static str = "Filecoin.EthTraceBlock"; + const NAME_ALIAS: Option<&'static str> = Some("trace_block"); + const N_REQUIRED_PARAMS: usize = 1; + const PARAM_NAMES: [&'static str; 1] = ["blockParam"]; + const API_PATHS: BitFlags = make_bitflags!(ApiPaths::V2); + const PERMISSION: Permission = Permission::Read; + const DESCRIPTION: Option<&'static str> = Some("Returns traces created at given block."); + + type Params = (ExtBlockNumberOrHash,); + type Ok = Vec; + async fn handle( + ctx: Ctx, + (block_param,): Self::Params, + ) -> Result { + let ts = tipset_by_block_number_or_hash_v2(&ctx, block_param, ResolveNullTipset::TakeOlder) + .await?; + eth_trace_block(&ctx, &ts).await + } +} + +async fn eth_trace_block(ctx: &Ctx, ts: &Tipset) -> Result, ServerError> +where + DB: Blockstore + Send + Sync + 'static, +{ + let (state_root, trace) = ctx.state_manager.execution_trace(ts)?; let state = StateTree::new_from_root(ctx.store_owned(), &state_root)?; let cid = ts.key().cid()?; let block_hash: EthHash = cid.into(); @@ -3750,14 +3774,17 @@ impl RpcMethod<1> for EthTraceTransaction { .await? .ok_or(ServerError::internal_error("transaction not found", None))?; - let traces = trace_block( - ctx, + let ts = tipset_by_ext_block_number_or_hash( + ctx.chain_store(), ExtBlockNumberOrHash::from_block_number(eth_txn.block_number.0 as i64), - ) - .await? - .into_iter() - .filter(|trace| trace.transaction_hash == eth_hash) - .collect(); + ResolveNullTipset::TakeOlder, + )?; + + let traces = eth_trace_block(&ctx, &ts) + .await? + .into_iter() + .filter(|trace| trace.transaction_hash == eth_hash) + .collect(); Ok(traces) } } diff --git a/src/rpc/mod.rs b/src/rpc/mod.rs index e4348967a923..c781897ac83d 100644 --- a/src/rpc/mod.rs +++ b/src/rpc/mod.rs @@ -146,6 +146,7 @@ macro_rules! for_each_rpc_method { $callback!($crate::rpc::eth::EthSubscribe); $callback!($crate::rpc::eth::EthSyncing); $callback!($crate::rpc::eth::EthTraceBlock); + $callback!($crate::rpc::eth::EthTraceBlockV2); $callback!($crate::rpc::eth::EthTraceFilter); $callback!($crate::rpc::eth::EthTraceTransaction); $callback!($crate::rpc::eth::EthTraceReplayBlockTransactions); diff --git a/src/tool/subcommands/api_cmd/api_compare_tests.rs b/src/tool/subcommands/api_cmd/api_compare_tests.rs index 489d8f085344..85a8424980ca 100644 --- a/src/tool/subcommands/api_cmd/api_compare_tests.rs +++ b/src/tool/subcommands/api_cmd/api_compare_tests.rs @@ -2270,6 +2270,34 @@ fn eth_tests_with_tipset(store: &Arc, shared_tipset: &Tipset ),)) .unwrap(), ), + RpcTest::identity( + EthTraceBlockV2::request((ExtBlockNumberOrHash::from_block_number( + shared_tipset.epoch(), + ),)) + .unwrap(), + ), + RpcTest::basic( + EthTraceBlockV2::request((ExtBlockNumberOrHash::from_predefined( + ExtPredefined::Pending, + ),)) + .unwrap(), + ), + RpcTest::basic( + EthTraceBlockV2::request((ExtBlockNumberOrHash::from_predefined( + ExtPredefined::Latest, + ),)) + .unwrap(), + ), + RpcTest::basic( + EthTraceBlockV2::request((ExtBlockNumberOrHash::from_predefined(ExtPredefined::Safe),)) + .unwrap(), + ), + RpcTest::basic( + EthTraceBlockV2::request((ExtBlockNumberOrHash::from_predefined( + ExtPredefined::Finalized, + ),)) + .unwrap(), + ), RpcTest::identity( EthTraceReplayBlockTransactions::request(( ExtBlockNumberOrHash::from_block_number(shared_tipset.epoch()), diff --git a/src/tool/subcommands/api_cmd/test_snapshots.txt b/src/tool/subcommands/api_cmd/test_snapshots.txt index c20a4cbd3031..6100d3c0677f 100644 --- a/src/tool/subcommands/api_cmd/test_snapshots.txt +++ b/src/tool/subcommands/api_cmd/test_snapshots.txt @@ -99,6 +99,11 @@ filecoin_ethnewfilter_1741781607617949.rpcsnap.json.zst filecoin_ethnewpendingtransactionfilter_1741781890872902.rpcsnap.json.zst filecoin_ethprotocolversion_1737446676698826.rpcsnap.json.zst filecoin_ethtraceblock_1737446676736475.rpcsnap.json.zst +filecoin_ethtraceblock_1768911857430141.rpcsnap.json.zst +filecoin_ethtraceblock_v2_finalized_1769092405093534.rpcsnap.json.zst +filecoin_ethtraceblock_v2_latest_1769092400908495.rpcsnap.json.zst +filecoin_ethtraceblock_v2_pending_1769092400918744.rpcsnap.json.zst +filecoin_ethtraceblock_v2_safe_1769092401374979.rpcsnap.json.zst filecoin_ethtracefilter_1742371405673188.rpcsnap.json.zst filecoin_ethtracefilter_1742983898701553.rpcsnap.json.zst filecoin_ethtracefilter_1746449543820062.rpcsnap.json.zst