Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@

- [#6498](https://github.com/ChainSafe/forest/pull/6498): Implemented `Filecoin.EthGetBlockReceiptsLimited` for API v2.

- [#6522](https://github.com/ChainSafe/forest/pull/6522): Implemented `Filecoin.EthTraceFilter` for API v2.

### Changed

- [#6471](https://github.com/ChainSafe/forest/pull/6471): Moved `forest-tool state` subcommand to `forest-dev`.
Expand Down
63 changes: 63 additions & 0 deletions src/rpc/methods/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4101,6 +4101,22 @@ fn get_eth_block_number_from_string<DB: Blockstore>(
))
}

async fn get_eth_block_number_from_string_v2<DB: Blockstore + Send + Sync + 'static>(
ctx: &Ctx<DB>,
block: Option<&str>,
resolve: ResolveNullTipset,
) -> Result<EthUint64> {
let block_param = match block {
Some(block_str) => ExtBlockNumberOrHash::from_str(block_str)?,
None => bail!("cannot parse fromBlock"),
};
Ok(EthUint64(
tipset_by_block_number_or_hash_v2(ctx, block_param, resolve)
.await?
.epoch() as u64,
))
}

pub enum EthTraceFilter {}
impl RpcMethod<1> for EthTraceFilter {
const N_REQUIRED_PARAMS: usize = 1;
Expand Down Expand Up @@ -4146,6 +4162,53 @@ impl RpcMethod<1> for EthTraceFilter {
}
}

pub enum EthTraceFilterV2 {}
impl RpcMethod<1> for EthTraceFilterV2 {
const N_REQUIRED_PARAMS: usize = 1;
const NAME: &'static str = "Filecoin.EthTraceFilter";
const NAME_ALIAS: Option<&'static str> = Some("trace_filter");
const PARAM_NAMES: [&'static str; 1] = ["filter"];
const API_PATHS: BitFlags<ApiPaths> = make_bitflags!(ApiPaths::V2);
const PERMISSION: Permission = Permission::Read;
const DESCRIPTION: Option<&'static str> =
Some("Returns the traces for transactions matching the filter criteria.");
type Params = (EthTraceFilterCriteria,);
type Ok = Vec<EthBlockTrace>;

async fn handle(
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
(filter,): Self::Params,
) -> Result<Self::Ok, ServerError> {
let from_block = get_eth_block_number_from_string_v2(
&ctx,
filter.from_block.as_deref(),
ResolveNullTipset::TakeNewer,
)
.await
.context("cannot parse fromBlock")?;

let to_block = get_eth_block_number_from_string_v2(
&ctx,
filter.to_block.as_deref(),
ResolveNullTipset::TakeOlder,
)
.await
.context("cannot parse toBlock")?;

Ok(trace_filter(ctx, filter, from_block, to_block)
.await?
.into_iter()
.sorted_by_key(|trace| {
(
trace.block_number,
trace.transaction_position,
trace.trace.trace_address.clone(),
)
})
.collect::<Vec<_>>())
}
}

async fn trace_filter(
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
filter: EthTraceFilterCriteria,
Expand Down
1 change: 1 addition & 0 deletions src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ macro_rules! for_each_rpc_method {
$callback!($crate::rpc::eth::EthTraceBlock);
$callback!($crate::rpc::eth::EthTraceBlockV2);
$callback!($crate::rpc::eth::EthTraceFilter);
$callback!($crate::rpc::eth::EthTraceFilterV2);
$callback!($crate::rpc::eth::EthTraceTransaction);
$callback!($crate::rpc::eth::EthTraceReplayBlockTransactions);
$callback!($crate::rpc::eth::EthTraceReplayBlockTransactionsV2);
Expand Down
67 changes: 67 additions & 0 deletions src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/tool/subcommands/api_cmd/api_compare_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2469,6 +2469,18 @@ fn eth_tests_with_tipset<DB: Blockstore>(store: &Arc<DB>, shared_tipset: &Tipset
// both nodes could fail on, e.g., "too many results, maximum supported is 500, try paginating
// requests with After and Count"
.policy_on_rejected(PolicyOnRejected::PassWithIdenticalError),
RpcTest::identity(
EthTraceFilterV2::request((EthTraceFilterCriteria {
from_block: Some(format!(
"0x{:x}",
shared_tipset.epoch() - (SAFE_EPOCH_DELAY + 1)
)),
to_block: Some(format!("0x{:x}", shared_tipset.epoch() - SAFE_EPOCH_DELAY)),
..Default::default()
},))
.unwrap(),
)
.policy_on_rejected(PolicyOnRejected::PassWithIdenticalError),
RpcTest::identity(
EthGetTransactionReceipt::request((
// A transaction that should not exist, to test the `null` response in case
Expand Down
1 change: 1 addition & 0 deletions src/tool/subcommands/api_cmd/test_snapshots.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ 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
filecoin_ethtracefilter_1770191732520294.rpcsnap.json.zst
filecoin_ethtracereplayblocktransactions_1768898971081023.rpcsnap.json.zst
filecoin_ethtracereplayblocktransactions_1768898971153948.rpcsnap.json.zst
filecoin_ethtracetransaction_1741765677273941.rpcsnap.json.zst
Expand Down
Loading