From 5e1b135f1d9549228e888715ccf7f409f4dbde9b Mon Sep 17 00:00:00 2001 From: Shashank Date: Tue, 12 Aug 2025 11:51:12 +0530 Subject: [PATCH 01/11] Add more evm methods support --- .../actor_states/methods/evm_actor.rs | 127 ++++++++++++++++++ .../methods/evm_constructor_params.rs | 62 --------- src/lotus_json/actor_states/methods/mod.rs | 2 +- src/rpc/registry/actors/evm.rs | 19 ++- .../subcommands/api_cmd/api_compare_tests.rs | 45 ++++++- 5 files changed, 188 insertions(+), 67 deletions(-) create mode 100644 src/lotus_json/actor_states/methods/evm_actor.rs delete mode 100644 src/lotus_json/actor_states/methods/evm_constructor_params.rs diff --git a/src/lotus_json/actor_states/methods/evm_actor.rs b/src/lotus_json/actor_states/methods/evm_actor.rs new file mode 100644 index 000000000000..8b8cb997f239 --- /dev/null +++ b/src/lotus_json/actor_states/methods/evm_actor.rs @@ -0,0 +1,127 @@ +// Copyright 2019-2025 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT +use super::*; +use crate::shim::econ::TokenAmount; +use ::cid::Cid; +use fvm_ipld_encoding::RawBytes; +use jsonrpsee::core::Serialize; +use paste::paste; +use schemars::JsonSchema; +use serde::Deserialize; +use std::fmt::Debug; + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct EVMConstructorParamsLotusJson { + pub creator: [u8; 20], + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub initcode: RawBytes, +} + +macro_rules! impl_evm_constructor_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_evm_state::[]::ConstructorParams { + type LotusJson = EVMConstructorParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![ + ( + json!({ + "Creator": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + "Initcode": "ESIzRFU=" + }), + Self { + creator: fil_actor_evm_state::evm_shared::[]::address::EthAddress([0; 20]), + initcode: RawBytes::new(hex::decode("1122334455").unwrap()), + }, + ), + ] + } + + fn into_lotus_json(self) -> Self::LotusJson { + EVMConstructorParamsLotusJson { + creator: self.creator.0, + initcode: self.initcode, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + creator: fil_actor_evm_state::evm_shared::[]::address::EthAddress(lotus_json.creator), + initcode: lotus_json.initcode, + } + } + } + } + )+ + }; +} + +impl_evm_constructor_params!(10, 11, 12, 13, 14, 15, 16); + +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "PascalCase")] +pub struct EVMDelegateCallParamsLotusJson { + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub code: Cid, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub input: RawBytes, + pub caller: [u8; 20], + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub value: TokenAmount, +} + +macro_rules! impl_evm_delegate_call_params_lotus_json { +($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_evm_state::[]::DelegateCallParams { + type LotusJson = EVMDelegateCallParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "Code": "bafy2bzaceaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "Input": "ESIzRFU=", + "Caller": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + "Value": "0" + }), + Self { + code: Cid::default(), + input: hex::decode("1122334455").unwrap(), + caller: fil_actor_evm_state::evm_shared::[]::address::EthAddress([0; 20]), + value: TokenAmount::from_atto(0).into(), + }, + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + EVMDelegateCallParamsLotusJson { + code: self.code, + input: self.input.into(), + caller: self.caller.0, + value: self.value.into(), + } + } + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + code: lotus_json.code, + input: lotus_json.input.into(), + caller: fil_actor_evm_state::evm_shared::[]::address::EthAddress(lotus_json.caller), + value: lotus_json.value.into(), + } + } + }} + )+ + }; +} + +impl_evm_delegate_call_params_lotus_json!(10, 11, 12, 13, 14, 15, 16); diff --git a/src/lotus_json/actor_states/methods/evm_constructor_params.rs b/src/lotus_json/actor_states/methods/evm_constructor_params.rs deleted file mode 100644 index a9543dae17f9..000000000000 --- a/src/lotus_json/actor_states/methods/evm_constructor_params.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2019-2025 ChainSafe Systems -// SPDX-License-Identifier: Apache-2.0, MIT -use super::*; -use fvm_ipld_encoding::RawBytes; -use jsonrpsee::core::Serialize; -use paste::paste; -use schemars::JsonSchema; -use serde::Deserialize; -use std::fmt::Debug; - -#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] -#[serde(rename_all = "PascalCase")] -pub struct EVMConstructorParamsLotusJson { - pub creator: [u8; 20], - #[schemars(with = "LotusJson")] - #[serde(with = "crate::lotus_json")] - pub initcode: RawBytes, -} - -macro_rules! impl_evm_constructor_params { - ($($version:literal),+) => { - $( - paste! { - impl HasLotusJson for fil_actor_evm_state::[]::ConstructorParams { - type LotusJson = EVMConstructorParamsLotusJson; - - #[cfg(test)] - fn snapshots() -> Vec<(serde_json::Value, Self)> { - vec![ - ( - json!({ - "Creator": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - "Initcode": "ESIzRFU=" - }), - Self { - creator: fil_actor_evm_state::evm_shared::[]::address::EthAddress([0; 20]), - initcode: RawBytes::new(hex::decode("1122334455").unwrap()), - }, - ), - ] - } - - fn into_lotus_json(self) -> Self::LotusJson { - EVMConstructorParamsLotusJson { - creator: self.creator.0, - initcode: self.initcode, - } - } - - fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { - Self { - creator: fil_actor_evm_state::evm_shared::[]::address::EthAddress(lotus_json.creator), - initcode: lotus_json.initcode, - } - } - } - } - )+ - }; -} - -impl_evm_constructor_params!(10, 11, 12, 13, 14, 15, 16); diff --git a/src/lotus_json/actor_states/methods/mod.rs b/src/lotus_json/actor_states/methods/mod.rs index 49d8ecd20ab0..a6a8ebe0cf63 100644 --- a/src/lotus_json/actor_states/methods/mod.rs +++ b/src/lotus_json/actor_states/methods/mod.rs @@ -3,7 +3,7 @@ use super::*; mod account_authenticate_params; mod account_constructor_params; -mod evm_constructor_params; +mod evm_actor; mod init_constructor_params; mod init_exec4_params; mod init_exec_params; diff --git a/src/rpc/registry/actors/evm.rs b/src/rpc/registry/actors/evm.rs index 618093c5d731..9b9feae63335 100644 --- a/src/rpc/registry/actors/evm.rs +++ b/src/rpc/registry/actors/evm.rs @@ -5,15 +5,30 @@ use crate::rpc::registry::methods_reg::{MethodRegistry, register_actor_methods}; use crate::shim::message::MethodNum; use anyhow::Result; use cid::Cid; +use fvm_ipld_encoding::RawBytes; macro_rules! register_evm_version { ($registry:expr, $code_cid:expr, $state_version:path) => {{ - use $state_version::{ConstructorParams, Method}; + use $state_version::{ConstructorParams, DelegateCallParams, Method}; register_actor_methods!( $registry, $code_cid, - [(Method::Constructor, ConstructorParams)] + [ + (Method::Constructor, ConstructorParams), + (Method::Resurrect, ConstructorParams), + (Method::InvokeContract, RawBytes), + (Method::InvokeContractDelegate, DelegateCallParams), + ] + ); + + register_actor_methods!( + $registry, + $code_cid, + [ + (Method::GetBytecode, empty), + (Method::GetBytecodeHash, empty) + ] ); }}; } diff --git a/src/tool/subcommands/api_cmd/api_compare_tests.rs b/src/tool/subcommands/api_cmd/api_compare_tests.rs index 393b4291ec0c..d50f3165726a 100644 --- a/src/tool/subcommands/api_cmd/api_compare_tests.rs +++ b/src/tool/subcommands/api_cmd/api_compare_tests.rs @@ -1836,6 +1836,17 @@ fn state_decode_params_api_tests(tipset: &Tipset) -> anyhow::Result initcode: fvm_ipld_encoding::RawBytes::new(vec![0x12, 0x34, 0x56]), // dummy bytecode }; + let evm_invoke_contract_params = fil_actor_evm_state::v16::InvokeContractParams { + input_data: vec![0x11, 0x22, 0x33, 0x44, 0x55], // dummy input data + }; + + let evm_delegate_call_params = fil_actor_evm_state::v16::DelegateCallParams { + code: Cid::default(), + input: vec![0x11, 0x22, 0x33, 0x44, 0x55], // dummy input data + caller: fil_actor_evm_state::evm_shared::v16::address::EthAddress([0; 20]), + value: TokenAmount::default().into(), + }; + let init_constructor_params = fil_actor_init_state::v16::ConstructorParams { network_name: "calibnet".to_string(), }; @@ -1966,11 +1977,41 @@ fn state_decode_params_api_tests(tipset: &Tipset) -> anyhow::Result tipset.key().into(), ))?), RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), // evm actor - 1, + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::Constructor as u64, to_vec(&evm_constructor_params)?, tipset.key().into(), ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::Resurrect as u64, + to_vec(&evm_constructor_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::GetBytecode as u64, + vec![], + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::GetBytecodeHash as u64, + vec![], + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::InvokeContract as u64, + to_vec(&evm_invoke_contract_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::InvokeContractDelegate as u64, + to_vec(&evm_delegate_call_params)?, + tipset.key().into(), + ))?), RpcTest::identity(StateDecodeParams::request(( Address::INIT_ACTOR, 1, From 675ea95f6c46bff55b89f64d5ab54ea8690b1abc Mon Sep 17 00:00:00 2001 From: Shashank Date: Tue, 12 Aug 2025 18:59:45 +0530 Subject: [PATCH 02/11] Add test snapshots --- src/tool/subcommands/api_cmd/test_snapshots.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tool/subcommands/api_cmd/test_snapshots.txt b/src/tool/subcommands/api_cmd/test_snapshots.txt index 7999437a279b..7cf2c1298118 100644 --- a/src/tool/subcommands/api_cmd/test_snapshots.txt +++ b/src/tool/subcommands/api_cmd/test_snapshots.txt @@ -161,6 +161,12 @@ filecoin_multisig_statedecodeparams_1754230255631872.rpcsnap.json.zst filecoin_multisig_statedecodeparams_1754230255631946.rpcsnap.json.zst filecoin_multisig_statedecodeparams_1754230255632019.rpcsnap.json.zst filecoin_multisig_statedecodeparams_1754581573704814.rpcsnap.json.zst +filecoin_evm_constructor_statedecodeparams_1755004924714690.rpcsnap.json.zst +filecoin_evm_getbytecode_statedecodeparams_1755004924714460.rpcsnap.json.zst +filecoin_evm_getbytecodehash_statedecodeparams_1755004924714337.rpcsnap.json.zst +filecoin_evm_invokecontract_statedecodeparams_1755004924714521.rpcsnap.json.zst +filecoin_evm_invokecontractdelegate_statedecodeparams_1755004924714578.rpcsnap.json.zst +filecoin_evm_resurrect_statedecodeparams_1755004924714636.rpcsnap.json.zst filecoin_statereplay_1743504051038215.rpcsnap.json.zst filecoin_statesearchmsg_1741784596636715.rpcsnap.json.zst filecoin_statesearchmsglimited_1741784596704876.rpcsnap.json.zst From 0ddf9d927aa68f985856dab1025f4c0dcf19cd57 Mon Sep 17 00:00:00 2001 From: Shashank Date: Wed, 13 Aug 2025 21:40:03 +0530 Subject: [PATCH 03/11] fmt --- src/lotus_json/actor_states/methods/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lotus_json/actor_states/methods/mod.rs b/src/lotus_json/actor_states/methods/mod.rs index e75db68b09d9..545d2cc47e05 100644 --- a/src/lotus_json/actor_states/methods/mod.rs +++ b/src/lotus_json/actor_states/methods/mod.rs @@ -3,8 +3,8 @@ use super::*; mod account_authenticate_params; mod account_constructor_params; -mod evm_actor_params; mod datacap_actor_params; +mod evm_actor_params; mod init_constructor_params; mod init_exec4_params; mod init_exec_params; From c42b6f3f56f73d2a93dfe4a08bdc835b05d3c409 Mon Sep 17 00:00:00 2001 From: Shashank Date: Wed, 13 Aug 2025 21:46:17 +0530 Subject: [PATCH 04/11] fmt --- .../subcommands/api_cmd/api_compare_tests.rs | 112 ++++++++++-------- 1 file changed, 60 insertions(+), 52 deletions(-) diff --git a/src/tool/subcommands/api_cmd/api_compare_tests.rs b/src/tool/subcommands/api_cmd/api_compare_tests.rs index 794eec6d6f81..24afe9adc496 100644 --- a/src/tool/subcommands/api_cmd/api_compare_tests.rs +++ b/src/tool/subcommands/api_cmd/api_compare_tests.rs @@ -1831,22 +1831,6 @@ fn state_decode_params_api_tests(tipset: &Tipset) -> anyhow::Result new_control_addresses: vec![Address::new_id(2001).into()], }; - let evm_constructor_params = fil_actor_evm_state::v16::ConstructorParams { - creator: fil_actor_evm_state::evm_shared::v16::address::EthAddress([0; 20]), - initcode: fvm_ipld_encoding::RawBytes::new(vec![0x12, 0x34, 0x56]), // dummy bytecode - }; - - let evm_invoke_contract_params = fil_actor_evm_state::v16::InvokeContractParams { - input_data: vec![0x11, 0x22, 0x33, 0x44, 0x55], // dummy input data - }; - - let evm_delegate_call_params = fil_actor_evm_state::v16::DelegateCallParams { - code: Cid::default(), - input: vec![0x11, 0x22, 0x33, 0x44, 0x55], // dummy input data - caller: fil_actor_evm_state::evm_shared::v16::address::EthAddress([0; 20]), - value: TokenAmount::default().into(), - }; - let init_constructor_params = fil_actor_init_state::v16::ConstructorParams { network_name: "calibnet".to_string(), }; @@ -1976,42 +1960,6 @@ fn state_decode_params_api_tests(tipset: &Tipset) -> anyhow::Result to_vec(&account_auth_params)?, tipset.key().into(), ))?), - RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), - fil_actor_evm_state::v16::Method::Constructor as u64, - to_vec(&evm_constructor_params)?, - tipset.key().into(), - ))?), - RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), - fil_actor_evm_state::v16::Method::Resurrect as u64, - to_vec(&evm_constructor_params)?, - tipset.key().into(), - ))?), - RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), - fil_actor_evm_state::v16::Method::GetBytecode as u64, - vec![], - tipset.key().into(), - ))?), - RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), - fil_actor_evm_state::v16::Method::GetBytecodeHash as u64, - vec![], - tipset.key().into(), - ))?), - RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), - fil_actor_evm_state::v16::Method::InvokeContract as u64, - to_vec(&evm_invoke_contract_params)?, - tipset.key().into(), - ))?), - RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), - fil_actor_evm_state::v16::Method::InvokeContractDelegate as u64, - to_vec(&evm_delegate_call_params)?, - tipset.key().into(), - ))?), RpcTest::identity(StateDecodeParams::request(( Address::INIT_ACTOR, 1, @@ -2209,6 +2157,66 @@ fn state_decode_params_api_tests(tipset: &Tipset) -> anyhow::Result ]; tests.extend(datacap_actor_state_decode_params_tests(tipset)?); + tests.extend(evm_actor_state_decode_params_tests(tipset)?); + + Ok(tests) +} + +fn evm_actor_state_decode_params_tests(tipset: &Tipset) -> anyhow::Result> { + let evm_constructor_params = fil_actor_evm_state::v16::ConstructorParams { + creator: fil_actor_evm_state::evm_shared::v16::address::EthAddress([0; 20]), + initcode: fvm_ipld_encoding::RawBytes::new(vec![0x12, 0x34, 0x56]), // dummy bytecode + }; + + let evm_invoke_contract_params = fil_actor_evm_state::v16::InvokeContractParams { + input_data: vec![0x11, 0x22, 0x33, 0x44, 0x55], // dummy input data + }; + + let evm_delegate_call_params = fil_actor_evm_state::v16::DelegateCallParams { + code: Cid::default(), + input: vec![0x11, 0x22, 0x33, 0x44, 0x55], // dummy input data + caller: fil_actor_evm_state::evm_shared::v16::address::EthAddress([0; 20]), + value: TokenAmount::default().into(), + }; + + let tests = vec![ + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::Constructor as u64, + to_vec(&evm_constructor_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::Resurrect as u64, + to_vec(&evm_constructor_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::GetBytecode as u64, + vec![], + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::GetBytecodeHash as u64, + vec![], + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::InvokeContract as u64, + to_vec(&evm_invoke_contract_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::from_str(EVM_ADDRESS).unwrap(), + fil_actor_evm_state::v16::Method::InvokeContractDelegate as u64, + to_vec(&evm_delegate_call_params)?, + tipset.key().into(), + ))?), + ]; Ok(tests) } From b105cfc4516049efbb9263e768d61dcf33bff791 Mon Sep 17 00:00:00 2001 From: Shashank Date: Thu, 14 Aug 2025 15:48:14 +0530 Subject: [PATCH 05/11] Use serde --- src/lotus_json/actor_states/methods/evm_actor_params.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lotus_json/actor_states/methods/evm_actor_params.rs b/src/lotus_json/actor_states/methods/evm_actor_params.rs index 8b8cb997f239..77c36686317f 100644 --- a/src/lotus_json/actor_states/methods/evm_actor_params.rs +++ b/src/lotus_json/actor_states/methods/evm_actor_params.rs @@ -4,10 +4,9 @@ use super::*; use crate::shim::econ::TokenAmount; use ::cid::Cid; use fvm_ipld_encoding::RawBytes; -use jsonrpsee::core::Serialize; use paste::paste; use schemars::JsonSchema; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use std::fmt::Debug; #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] From b8be08541e761d378b4c6dad204450bfccd8996a Mon Sep 17 00:00:00 2001 From: Shashank Date: Tue, 19 Aug 2025 21:24:13 +0530 Subject: [PATCH 06/11] add GetStorageAt --- .../actor_states/methods/evm_actor_params.rs | 32 +++++++++++++++++++ src/rpc/methods/eth/types.rs | 12 +++++-- src/rpc/registry/actors/evm.rs | 7 ++++ .../subcommands/api_cmd/api_compare_tests.rs | 8 +++++ .../subcommands/api_cmd/test_snapshots.txt | 1 + 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/lotus_json/actor_states/methods/evm_actor_params.rs b/src/lotus_json/actor_states/methods/evm_actor_params.rs index 77c36686317f..70ebc560054f 100644 --- a/src/lotus_json/actor_states/methods/evm_actor_params.rs +++ b/src/lotus_json/actor_states/methods/evm_actor_params.rs @@ -1,6 +1,7 @@ // Copyright 2019-2025 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT use super::*; +use crate::rpc::eth::types::GetStorageAtParams; use crate::shim::econ::TokenAmount; use ::cid::Cid; use fvm_ipld_encoding::RawBytes; @@ -124,3 +125,34 @@ macro_rules! impl_evm_delegate_call_params_lotus_json { } impl_evm_delegate_call_params_lotus_json!(10, 11, 12, 13, 14, 15, 16); + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "PascalCase")] +pub struct GetStorageAtParamsLotusJson { + #[schemars(with = "Vec")] + pub storage_key: Vec, +} + +impl HasLotusJson for GetStorageAtParams { + type LotusJson = GetStorageAtParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "StorageKey": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10] + }), + GetStorageAtParams::new(vec![0xa]).unwrap(), + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + GetStorageAtParamsLotusJson { + storage_key: self.0.to_vec(), + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + GetStorageAtParams::new(lotus_json.storage_key).unwrap() + } +} diff --git a/src/rpc/methods/eth/types.rs b/src/rpc/methods/eth/types.rs index 98c442715b2f..94588299ed24 100644 --- a/src/rpc/methods/eth/types.rs +++ b/src/rpc/methods/eth/types.rs @@ -62,8 +62,9 @@ impl FromStr for EthBytes { pub struct GetBytecodeReturn(pub Option); const GET_STORAGE_AT_PARAMS_ARRAY_LENGTH: usize = 32; +const LENGTH_BUF_GET_STORAGE_AT_PARAMS: u8 = 129; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Deserialize, Serialize)] pub struct GetStorageAtParams(pub [u8; GET_STORAGE_AT_PARAMS_ARRAY_LENGTH]); impl GetStorageAtParams { @@ -80,11 +81,18 @@ impl GetStorageAtParams { } pub fn serialize_params(&self) -> anyhow::Result> { - const LENGTH_BUF_GET_STORAGE_AT_PARAMS: u8 = 129; let mut encoded = fvm_ipld_encoding::to_vec(&RawBytes::new(self.0.to_vec()))?; encoded.insert(0, LENGTH_BUF_GET_STORAGE_AT_PARAMS); Ok(encoded) } + + pub fn deserialize_params(bytes: &[u8]) -> anyhow::Result { + if bytes.is_empty() || bytes[0] != LENGTH_BUF_GET_STORAGE_AT_PARAMS { + anyhow::bail!("Invalid bytes"); + } + let raw_bytes: RawBytes = fvm_ipld_encoding::from_slice(&bytes[1..])?; + GetStorageAtParams::new(raw_bytes.into()) + } } #[derive( diff --git a/src/rpc/registry/actors/evm.rs b/src/rpc/registry/actors/evm.rs index 9b9feae63335..f8cf56ca4711 100644 --- a/src/rpc/registry/actors/evm.rs +++ b/src/rpc/registry/actors/evm.rs @@ -1,6 +1,7 @@ // Copyright 2019-2025 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT +use crate::rpc::eth::types::GetStorageAtParams; use crate::rpc::registry::methods_reg::{MethodRegistry, register_actor_methods}; use crate::shim::message::MethodNum; use anyhow::Result; @@ -22,6 +23,12 @@ macro_rules! register_evm_version { ] ); + $registry.register_method( + $code_cid, + Method::GetStorageAt as MethodNum, + GetStorageAtParams::deserialize_params, + ); + register_actor_methods!( $registry, $code_cid, diff --git a/src/tool/subcommands/api_cmd/api_compare_tests.rs b/src/tool/subcommands/api_cmd/api_compare_tests.rs index ec6d87c33ac5..b2f6bca0a08b 100644 --- a/src/tool/subcommands/api_cmd/api_compare_tests.rs +++ b/src/tool/subcommands/api_cmd/api_compare_tests.rs @@ -2201,6 +2201,8 @@ fn evm_actor_state_decode_params_tests(tipset: &Tipset) -> anyhow::Result anyhow::Result Date: Tue, 19 Aug 2025 23:21:55 +0530 Subject: [PATCH 07/11] lint fix --- src/rpc/methods/eth/types.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/rpc/methods/eth/types.rs b/src/rpc/methods/eth/types.rs index 94588299ed24..fb6d530a39b2 100644 --- a/src/rpc/methods/eth/types.rs +++ b/src/rpc/methods/eth/types.rs @@ -86,12 +86,13 @@ impl GetStorageAtParams { Ok(encoded) } - pub fn deserialize_params(bytes: &[u8]) -> anyhow::Result { - if bytes.is_empty() || bytes[0] != LENGTH_BUF_GET_STORAGE_AT_PARAMS { - anyhow::bail!("Invalid bytes"); + pub fn deserialize_params(bz: &[u8]) -> anyhow::Result { + let (&prefix, bytes) = bz.split_first().context("unexpected EOF")?; + if prefix != LENGTH_BUF_GET_STORAGE_AT_PARAMS { + anyhow::bail!("expected CBOR array of length 1"); } - let raw_bytes: RawBytes = fvm_ipld_encoding::from_slice(&bytes[1..])?; - GetStorageAtParams::new(raw_bytes.into()) + let decoded: RawBytes = fvm_ipld_encoding::from_slice(bytes)?; + GetStorageAtParams::new(decoded.into()) } } From 0a5bf3213e4e9555301548bafb8a78e546966b62 Mon Sep 17 00:00:00 2001 From: Shashank Date: Wed, 20 Aug 2025 00:38:55 +0530 Subject: [PATCH 08/11] fix error msg --- src/lotus_json/actor_states/methods/evm_actor_params.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lotus_json/actor_states/methods/evm_actor_params.rs b/src/lotus_json/actor_states/methods/evm_actor_params.rs index 70ebc560054f..76ee2051052f 100644 --- a/src/lotus_json/actor_states/methods/evm_actor_params.rs +++ b/src/lotus_json/actor_states/methods/evm_actor_params.rs @@ -153,6 +153,6 @@ impl HasLotusJson for GetStorageAtParams { } fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { - GetStorageAtParams::new(lotus_json.storage_key).unwrap() + GetStorageAtParams::new(lotus_json.storage_key).expect("expected array to have 32 elements") } } From 318fd27254f8c5e80c4689400f91390f7a874803 Mon Sep 17 00:00:00 2001 From: Shashank Date: Wed, 20 Aug 2025 16:53:37 +0530 Subject: [PATCH 09/11] fix --- src/lotus_json/actor_states/methods/evm_actor_params.rs | 1 - src/rpc/methods/eth/types.rs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lotus_json/actor_states/methods/evm_actor_params.rs b/src/lotus_json/actor_states/methods/evm_actor_params.rs index 76ee2051052f..1b994378da27 100644 --- a/src/lotus_json/actor_states/methods/evm_actor_params.rs +++ b/src/lotus_json/actor_states/methods/evm_actor_params.rs @@ -129,7 +129,6 @@ impl_evm_delegate_call_params_lotus_json!(10, 11, 12, 13, 14, 15, 16); #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "PascalCase")] pub struct GetStorageAtParamsLotusJson { - #[schemars(with = "Vec")] pub storage_key: Vec, } diff --git a/src/rpc/methods/eth/types.rs b/src/rpc/methods/eth/types.rs index fb6d530a39b2..6361d12d5498 100644 --- a/src/rpc/methods/eth/types.rs +++ b/src/rpc/methods/eth/types.rs @@ -81,8 +81,8 @@ impl GetStorageAtParams { } pub fn serialize_params(&self) -> anyhow::Result> { - let mut encoded = fvm_ipld_encoding::to_vec(&RawBytes::new(self.0.to_vec()))?; - encoded.insert(0, LENGTH_BUF_GET_STORAGE_AT_PARAMS); + let mut encoded = vec![LENGTH_BUF_GET_STORAGE_AT_PARAMS]; + fvm_ipld_encoding::to_writer(&mut encoded, &RawBytes::new(self.0.to_vec()))?; Ok(encoded) } From fe0cb6a4b4a3b5b4cb744a5cf5dbdee3756d39e4 Mon Sep 17 00:00:00 2001 From: Shashank Date: Mon, 25 Aug 2025 14:49:07 +0530 Subject: [PATCH 10/11] minor fix --- src/lotus_json/actor_states/methods/evm_actor_params.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lotus_json/actor_states/methods/evm_actor_params.rs b/src/lotus_json/actor_states/methods/evm_actor_params.rs index 1b994378da27..8cde8409f13e 100644 --- a/src/lotus_json/actor_states/methods/evm_actor_params.rs +++ b/src/lotus_json/actor_states/methods/evm_actor_params.rs @@ -129,7 +129,7 @@ impl_evm_delegate_call_params_lotus_json!(10, 11, 12, 13, 14, 15, 16); #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "PascalCase")] pub struct GetStorageAtParamsLotusJson { - pub storage_key: Vec, + pub storage_key: [u8; 32], } impl HasLotusJson for GetStorageAtParams { @@ -147,11 +147,12 @@ impl HasLotusJson for GetStorageAtParams { fn into_lotus_json(self) -> Self::LotusJson { GetStorageAtParamsLotusJson { - storage_key: self.0.to_vec(), + storage_key: self.0, } } fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { - GetStorageAtParams::new(lotus_json.storage_key).expect("expected array to have 32 elements") + GetStorageAtParams::new(lotus_json.storage_key.to_vec()) + .expect("expected array to have 32 elements") } } From 20e52b458657ee243cec8ef8e3258a9e0732ad86 Mon Sep 17 00:00:00 2001 From: Shashank Date: Mon, 25 Aug 2025 15:03:12 +0530 Subject: [PATCH 11/11] use ensure --- src/rpc/methods/eth/types.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/rpc/methods/eth/types.rs b/src/rpc/methods/eth/types.rs index 6361d12d5498..a9e4e24431e7 100644 --- a/src/rpc/methods/eth/types.rs +++ b/src/rpc/methods/eth/types.rs @@ -88,9 +88,10 @@ impl GetStorageAtParams { pub fn deserialize_params(bz: &[u8]) -> anyhow::Result { let (&prefix, bytes) = bz.split_first().context("unexpected EOF")?; - if prefix != LENGTH_BUF_GET_STORAGE_AT_PARAMS { - anyhow::bail!("expected CBOR array of length 1"); - } + ensure!( + prefix == LENGTH_BUF_GET_STORAGE_AT_PARAMS, + "expected CBOR array of length 1" + ); let decoded: RawBytes = fvm_ipld_encoding::from_slice(bytes)?; GetStorageAtParams::new(decoded.into()) }