From 9449e64f35d4aafbb16a3c257102b595cba184b5 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Mon, 20 Oct 2025 16:46:20 +0530 Subject: [PATCH 1/5] feat: enable V2 API support for basic Eth RPC methods --- src/rpc/methods/eth.rs | 8 ++++---- src/rpc/reflect/mod.rs | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/rpc/methods/eth.rs b/src/rpc/methods/eth.rs index 32f02ee3804a..969ff25b9ae8 100644 --- a/src/rpc/methods/eth.rs +++ b/src/rpc/methods/eth.rs @@ -736,7 +736,7 @@ impl RpcMethod<0> for EthAccounts { const NAME: &'static str = "Filecoin.EthAccounts"; const NAME_ALIAS: Option<&'static str> = Some("eth_accounts"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -791,7 +791,7 @@ impl RpcMethod<0> for EthChainId { const NAME: &'static str = "Filecoin.EthChainId"; const NAME_ALIAS: Option<&'static str> = Some("eth_chainId"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -1706,7 +1706,7 @@ impl RpcMethod<0> for EthSyncing { const NAME: &'static str = "Filecoin.EthSyncing"; const NAME_ALIAS: Option<&'static str> = Some("eth_syncing"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -2298,7 +2298,7 @@ impl RpcMethod<0> for EthProtocolVersion { const NAME: &'static str = "Filecoin.EthProtocolVersion"; const NAME_ALIAS: Option<&'static str> = Some("eth_protocolVersion"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); diff --git a/src/rpc/reflect/mod.rs b/src/rpc/reflect/mod.rs index 540edb9d27b2..19bf0366680f 100644 --- a/src/rpc/reflect/mod.rs +++ b/src/rpc/reflect/mod.rs @@ -134,6 +134,13 @@ impl ApiPaths { make_bitflags!(Self::{ V0 | V1 }) } + // Remove this helper once all RPC methods are migrated to V2. + // We're incrementally migrating methods to V2 support. Once complete, + // update all() to include V2 and remove this temporary helper. + pub const fn with_v2() -> BitFlags { + make_bitflags!(Self::{ V0 | V1 | V2 }) + } + pub fn from_uri(uri: &Uri) -> anyhow::Result { Ok(Self::from_str( uri.path().split("/").last().expect("infallible"), From c7a73bead04b4c25865aedafbb0d6fe72f29c46d Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Mon, 20 Oct 2025 17:00:46 +0530 Subject: [PATCH 2/5] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56bd8621a5c1..14eb39367809 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ ### Added - [#6166](https://github.com/ChainSafe/forest/pull/6166) Gate `JWT` expiration validation behind environment variable `FOREST_JWT_DISABLE_EXP_VALIDATION`. +- [#6171](https://github.com/ChainSafe/forest/pull/6171) Enable V2 API support for basic Eth RPC methods: `EthChainId`, `EthProtocolVersion`, `EthSyncing`, `EthAccounts`. ### Changed From 1369604c74a6231d20e5c8f9af46e88fec049196 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Wed, 22 Oct 2025 11:53:03 +0530 Subject: [PATCH 3/5] address comments --- src/rpc/methods/eth.rs | 8 ++++---- src/rpc/reflect/mod.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rpc/methods/eth.rs b/src/rpc/methods/eth.rs index 969ff25b9ae8..133bd41e0c4a 100644 --- a/src/rpc/methods/eth.rs +++ b/src/rpc/methods/eth.rs @@ -736,7 +736,7 @@ impl RpcMethod<0> for EthAccounts { const NAME: &'static str = "Filecoin.EthAccounts"; const NAME_ALIAS: Option<&'static str> = Some("eth_accounts"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::with_v2(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -791,7 +791,7 @@ impl RpcMethod<0> for EthChainId { const NAME: &'static str = "Filecoin.EthChainId"; const NAME_ALIAS: Option<&'static str> = Some("eth_chainId"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::with_v2(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -1706,7 +1706,7 @@ impl RpcMethod<0> for EthSyncing { const NAME: &'static str = "Filecoin.EthSyncing"; const NAME_ALIAS: Option<&'static str> = Some("eth_syncing"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::with_v2(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -2298,7 +2298,7 @@ impl RpcMethod<0> for EthProtocolVersion { const NAME: &'static str = "Filecoin.EthProtocolVersion"; const NAME_ALIAS: Option<&'static str> = Some("eth_protocolVersion"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::with_v2(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); diff --git a/src/rpc/reflect/mod.rs b/src/rpc/reflect/mod.rs index 19bf0366680f..51576f532b76 100644 --- a/src/rpc/reflect/mod.rs +++ b/src/rpc/reflect/mod.rs @@ -137,8 +137,8 @@ impl ApiPaths { // Remove this helper once all RPC methods are migrated to V2. // We're incrementally migrating methods to V2 support. Once complete, // update all() to include V2 and remove this temporary helper. - pub const fn with_v2() -> BitFlags { - make_bitflags!(Self::{ V0 | V1 | V2 }) + pub const fn all_with_v2() -> BitFlags { + Self::all().union_c(make_bitflags!(Self::{ V2 })) } pub fn from_uri(uri: &Uri) -> anyhow::Result { From 2ef586290d8607623abda99a8c86ac4e2add774c Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Wed, 22 Oct 2025 12:14:31 +0530 Subject: [PATCH 4/5] add more eth basic method to v2 --- src/rpc/methods/eth.rs | 2 +- src/rpc/methods/net.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpc/methods/eth.rs b/src/rpc/methods/eth.rs index 133bd41e0c4a..1993a0fb85c1 100644 --- a/src/rpc/methods/eth.rs +++ b/src/rpc/methods/eth.rs @@ -714,7 +714,7 @@ impl RpcMethod<0> for Web3ClientVersion { const NAME: &'static str = "Filecoin.Web3ClientVersion"; const NAME_ALIAS: Option<&'static str> = Some("web3_clientVersion"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); diff --git a/src/rpc/methods/net.rs b/src/rpc/methods/net.rs index a421b96491cd..069cf50ef1e3 100644 --- a/src/rpc/methods/net.rs +++ b/src/rpc/methods/net.rs @@ -102,7 +102,7 @@ pub enum NetListening {} impl RpcMethod<0> for NetListening { const NAME: &'static str = "Filecoin.NetListening"; const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; const NAME_ALIAS: Option<&'static str> = Some("net_listening"); @@ -249,7 +249,7 @@ pub enum NetVersion {} impl RpcMethod<0> for NetVersion { const NAME: &'static str = "Filecoin.NetVersion"; const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; const NAME_ALIAS: Option<&'static str> = Some("net_version"); From f0f58604f6f4f59fa74a4d7965425e405c079f47 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Wed, 22 Oct 2025 13:03:53 +0530 Subject: [PATCH 5/5] add more filecoin and eth API's which doesn't need F3 finality to V2 --- src/rpc/methods/eth.rs | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/rpc/methods/eth.rs b/src/rpc/methods/eth.rs index 1993a0fb85c1..a59703f6bcac 100644 --- a/src/rpc/methods/eth.rs +++ b/src/rpc/methods/eth.rs @@ -756,7 +756,7 @@ impl RpcMethod<0> for EthBlockNumber { const NAME: &'static str = "Filecoin.EthBlockNumber"; const NAME_ALIAS: Option<&'static str> = Some("eth_blockNumber"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -810,7 +810,7 @@ impl RpcMethod<0> for EthGasPrice { const NAME: &'static str = "Filecoin.EthGasPrice"; const NAME_ALIAS: Option<&'static str> = Some("eth_gasPrice"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; const DESCRIPTION: Option<&'static str> = Some("Returns the current gas price in attoFIL"); @@ -1457,7 +1457,7 @@ impl RpcMethod<2> for EthGetBlockByHash { const NAME: &'static str = "Filecoin.EthGetBlockByHash"; const NAME_ALIAS: Option<&'static str> = Some("eth_getBlockByHash"); const PARAM_NAMES: [&'static str; 2] = ["blockHash", "fullTxInfo"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (EthHash, bool); @@ -1646,7 +1646,7 @@ impl RpcMethod<1> for EthGetMessageCidByTransactionHash { const NAME: &'static str = "Filecoin.EthGetMessageCidByTransactionHash"; const NAME_ALIAS: Option<&'static str> = Some("eth_getMessageCidByTransactionHash"); const PARAM_NAMES: [&'static str; 1] = ["txHash"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (EthHash,); @@ -2276,7 +2276,7 @@ impl RpcMethod<0> for EthMaxPriorityFeePerGas { const NAME: &'static str = "Filecoin.EthMaxPriorityFeePerGas"; const NAME_ALIAS: Option<&'static str> = Some("eth_maxPriorityFeePerGas"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -2367,7 +2367,7 @@ impl RpcMethod<2> for EthGetTransactionByBlockHashAndIndex { const NAME: &'static str = "Filecoin.EthGetTransactionByBlockHashAndIndex"; const NAME_ALIAS: Option<&'static str> = Some("eth_getTransactionByBlockHashAndIndex"); const PARAM_NAMES: [&'static str; 2] = ["blockHash", "txIndex"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (EthHash, EthUint64); @@ -2410,7 +2410,7 @@ impl RpcMethod<1> for EthGetTransactionByHash { const NAME: &'static str = "Filecoin.EthGetTransactionByHash"; const NAME_ALIAS: Option<&'static str> = Some("eth_getTransactionByHash"); const PARAM_NAMES: [&'static str; 1] = ["txHash"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (EthHash,); @@ -2429,7 +2429,7 @@ impl RpcMethod<2> for EthGetTransactionByHashLimited { const NAME: &'static str = "Filecoin.EthGetTransactionByHashLimited"; const NAME_ALIAS: Option<&'static str> = Some("eth_getTransactionByHashLimited"); const PARAM_NAMES: [&'static str; 2] = ["txHash", "limit"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (EthHash, ChainEpoch); @@ -2502,7 +2502,7 @@ impl RpcMethod<1> for EthGetTransactionHashByCid { const NAME: &'static str = "Filecoin.EthGetTransactionHashByCid"; const NAME_ALIAS: Option<&'static str> = Some("eth_getTransactionHashByCid"); const PARAM_NAMES: [&'static str; 1] = ["cid"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (Cid,); @@ -2601,7 +2601,7 @@ impl RpcMethod<0> for EthNewPendingTransactionFilter { const NAME: &'static str = "Filecoin.EthNewPendingTransactionFilter"; const NAME_ALIAS: Option<&'static str> = Some("eth_newPendingTransactionFilter"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -2622,7 +2622,7 @@ impl RpcMethod<0> for EthNewBlockFilter { const NAME: &'static str = "Filecoin.EthNewBlockFilter"; const NAME_ALIAS: Option<&'static str> = Some("eth_newBlockFilter"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (); @@ -2643,7 +2643,7 @@ impl RpcMethod<1> for EthUninstallFilter { const NAME: &'static str = "Filecoin.EthUninstallFilter"; const NAME_ALIAS: Option<&'static str> = Some("eth_uninstallFilter"); const PARAM_NAMES: [&'static str; 1] = ["filterId"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (FilterID,); @@ -2664,7 +2664,7 @@ impl RpcMethod<0> for EthUnsubscribe { const NAME: &'static str = "Filecoin.EthUnsubscribe"; const NAME_ALIAS: Option<&'static str> = Some("eth_unsubscribe"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; const SUBSCRIPTION: bool = true; @@ -2689,7 +2689,7 @@ impl RpcMethod<0> for EthSubscribe { const NAME: &'static str = "Filecoin.EthSubscribe"; const NAME_ALIAS: Option<&'static str> = Some("eth_subscribe"); const PARAM_NAMES: [&'static str; 0] = []; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; const SUBSCRIPTION: bool = true; @@ -2715,7 +2715,7 @@ impl RpcMethod<1> for EthAddressToFilecoinAddress { const NAME_ALIAS: Option<&'static str> = None; const N_REQUIRED_PARAMS: usize = 1; const PARAM_NAMES: [&'static str; 1] = ["ethAddress"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (EthAddress,); type Ok = FilecoinAddress; @@ -2787,7 +2787,7 @@ impl RpcMethod<1> for EthGetTransactionReceipt { const NAME_ALIAS: Option<&'static str> = Some("eth_getTransactionReceipt"); const N_REQUIRED_PARAMS: usize = 1; const PARAM_NAMES: [&'static str; 1] = ["txHash"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (EthHash,); type Ok = EthTxReceipt; @@ -2805,7 +2805,7 @@ impl RpcMethod<2> for EthGetTransactionReceiptLimited { const NAME_ALIAS: Option<&'static str> = Some("eth_getTransactionReceiptLimited"); const N_REQUIRED_PARAMS: usize = 1; const PARAM_NAMES: [&'static str; 2] = ["txHash", "limit"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (EthHash, ChainEpoch); type Ok = EthTxReceipt; @@ -2822,7 +2822,7 @@ impl RpcMethod<1> for EthSendRawTransaction { const NAME: &'static str = "Filecoin.EthSendRawTransaction"; const NAME_ALIAS: Option<&'static str> = Some("eth_sendRawTransaction"); const PARAM_NAMES: [&'static str; 1] = ["rawTx"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; type Params = (EthBytes,); @@ -3092,7 +3092,7 @@ impl RpcMethod<1> for EthGetFilterLogs { const NAME_ALIAS: Option<&'static str> = Some("eth_getFilterLogs"); const N_REQUIRED_PARAMS: usize = 1; const PARAM_NAMES: [&'static str; 1] = ["filterId"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Write; type Params = (FilterID,); type Ok = EthFilterResult; @@ -3139,7 +3139,7 @@ impl RpcMethod<1> for EthGetFilterChanges { const NAME_ALIAS: Option<&'static str> = Some("eth_getFilterChanges"); const N_REQUIRED_PARAMS: usize = 1; const PARAM_NAMES: [&'static str; 1] = ["filterId"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Write; const DESCRIPTION: Option<&'static str> = Some("Returns event logs which occurred since the last poll"); @@ -3320,7 +3320,7 @@ impl RpcMethod<1> for EthTraceTransaction { const NAME_ALIAS: Option<&'static str> = Some("trace_transaction"); const N_REQUIRED_PARAMS: usize = 1; const PARAM_NAMES: [&'static str; 1] = ["txHash"]; - const API_PATHS: BitFlags = ApiPaths::all(); + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); const PERMISSION: Permission = Permission::Read; const DESCRIPTION: Option<&'static str> = Some("Returns the traces for a specific transaction.");