-
Notifications
You must be signed in to change notification settings - Fork 182
Add support for evm actor in state decode params API #5928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughConsolidates EVM Lotus JSON mappings into a single module, adds Lotus JSON structs for constructor/delegate-call and GetStorageAt params, implements HasLotusJson conversions for EVM v10..v16, registers new EVM RPC methods (GetBytecode, GetBytecodeHash, GetStorageAt, InvokeContract, InvokeContractDelegate, Constructor, Resurrect), and refactors tests and snapshots. Changes
Sequence Diagram(s)%%{init: {"themeVariables":{"actorBorder":"#1f77b4","noteBackground":"#f7f7f7"}}}%%
sequenceDiagram
participant Client
participant StateDecodeAPI as StateDecodeParams API
participant RPCRegistry as EVM RPC Registry
participant LotusJSON as Lotus JSON Mappers
participant CBOR as CBOR (GetStorageAt)
Client->>StateDecodeAPI: Request decode (actor=EVM, method, params, tipset)
StateDecodeAPI->>RPCRegistry: Resolve method -> param type
RPCRegistry-->>StateDecodeAPI: Param type (Constructor/Delegate/RawBytes/GetStorageAt/empty)
alt GetStorageAt
StateDecodeAPI->>CBOR: GetStorageAtParams::deserialize_params(bytes)
CBOR-->>StateDecodeAPI: GetStorageAtParams (validated)
StateDecodeAPI->>LotusJSON: into_lotus_json(GetStorageAtParams)
else Other params
StateDecodeAPI->>LotusJSON: into_lotus_json(params)
end
LotusJSON-->>StateDecodeAPI: Lotus JSON (v10..v16 aware)
StateDecodeAPI-->>Client: Decoded params JSON
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Assessment against linked issues
Out-of-scope changes
Possibly related issues
Suggested reviewers
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
src/rpc/registry/actors/evm.rs (1)
29-31: Pending: Add GetStorageAt when implementing itYou’ve registered GetBytecode and GetBytecodeHash (empty params). Once GetStorageAt lands, remember to register it here with its correct params type.
I can draft the registration snippet and tests when you pick up GetStorageAt. Want me to open a follow-up issue/PR checklist for the remaining EVM methods?
src/lotus_json/actor_states/methods/evm_actor_params.rs (1)
7-11: Prefer serde::Serialize import for clarity and consistencyAvoid importing Serialize from jsonrpsee. Derive macros expand to serde::Serialize anyway; importing from serde is clearer and consistent with Deserialize.
Apply:
-use jsonrpsee::core::Serialize; -use paste::paste; -use schemars::JsonSchema; -use serde::Deserialize; +use paste::paste; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize};src/tool/subcommands/api_cmd/api_compare_tests.rs (2)
2182-2219: DRY: Reuse parsed EVM address to avoid repeated parsingMinor cleanup to avoid multiple Address::from_str calls.
Apply:
fn evm_actor_state_decode_params_tests(tipset: &Tipset) -> anyhow::Result<Vec<RpcTest>> { + let evm_address = Address::from_str(EVM_ADDRESS).unwrap(); @@ - RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + RpcTest::identity(StateDecodeParams::request(( + evm_address, 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(), + evm_address, 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(), + evm_address, fil_actor_evm_state::v16::Method::GetBytecode as u64, vec![], tipset.key().into(), ))?), RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + evm_address, fil_actor_evm_state::v16::Method::GetBytecodeHash as u64, vec![], tipset.key().into(), ))?), RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + evm_address, 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(), + evm_address, fil_actor_evm_state::v16::Method::InvokeContractDelegate as u64, to_vec(&evm_delegate_call_params)?, tipset.key().into(), ))?),
2196-2206: Note for future coverage: Add GetStorageAt once implementedOnce GetStorageAt is supported, it’d be good to add a matching StateDecodeParams test here for parity with the registry and snapshots.
I can add a placeholder test and snapshot entry when you tackle GetStorageAt. Want me to queue that up?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these settings in your CodeRabbit configuration.
📒 Files selected for processing (6)
src/lotus_json/actor_states/methods/evm_actor_params.rs(1 hunks)src/lotus_json/actor_states/methods/evm_constructor_params.rs(0 hunks)src/lotus_json/actor_states/methods/mod.rs(1 hunks)src/rpc/registry/actors/evm.rs(1 hunks)src/tool/subcommands/api_cmd/api_compare_tests.rs(1 hunks)src/tool/subcommands/api_cmd/test_snapshots.txt(1 hunks)
💤 Files with no reviewable changes (1)
- src/lotus_json/actor_states/methods/evm_constructor_params.rs
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/rpc/registry/actors/evm.rs (4)
src/rpc/registry/actors/init.rs (1)
register_actor_methods(42-55)src/rpc/registry/actors/power.rs (1)
register_actor_methods(117-130)src/rpc/registry/actors/system.rs (1)
register_actor_methods(22-35)src/shim/actors/builtin/market/mod.rs (1)
empty(744-752)
🔇 Additional comments (9)
src/rpc/registry/actors/evm.rs (2)
12-23: Solid method-to-params mapping for Constructor/Resurrect/InvokeContract/InvokeContractDelegateThe registration cleanly wires:
- Constructor/Resurrect → ConstructorParams
- InvokeContract → RawBytes
- InvokeContractDelegate → DelegateCallParams
This aligns with the EVM actor’s API for v10–v16 and keeps things version-agnostic via the macro. Nice separation of typed params vs raw bytes.
20-21: InvokeContract mapping to RawBytes is correctA search of src/rpc/registry/actors/evm.rs and the wider codebase shows no use of InvokeContractParams or duplicate Lotus JSON mappings for InvokeContract. The tuple
(Method::InvokeContract, RawBytes)properly captures the opaque CBOR payload across v10–v16. No changes required.
src/lotus_json/actor_states/methods/evm_actor_params.rs (2)
29-43: Ensurejson!macro is in scope in test-only snapshotsThe snapshots use
json!({...})but this file doesn’t import the macro explicitly. If it isn’t re-exported from a parent module in this context, compilation will fail under tests.If not already imported via
super::*, add:+#[cfg(test)] +use serde_json::json;Also applies to: 88-104
64-79: Lotus JSON mapping for delegate call looks good and reversibleThe Lotus JSON representation for DelegateCallParams properly wraps code/input/value and flattens caller. The into/from mappings are consistent with Vec <-> RawBytes conversions and EthAddress newtype handling.
src/lotus_json/actor_states/methods/mod.rs (1)
7-7: Module swap toevm_actor_paramsis appropriateReplacing
evm_constructor_paramswith the consolidatedevm_actor_paramsmodule improves cohesion and keeps EVM-related Lotus JSON types together.src/tool/subcommands/api_cmd/test_snapshots.txt (1)
180-185: Snapshot coverage added for all registered EVM methodsThe new entries cover Constructor, Resurrect, GetBytecode, GetBytecodeHash, InvokeContract, and InvokeContractDelegate, matching the registry changes and tests.
src/tool/subcommands/api_cmd/api_compare_tests.rs (3)
2159-2163: Good: EVM state-decode tests integrated into the main suiteExtending state_decode_params_api_tests with EVM test cases keeps coverage centralized and ensures parity validation alongside other actors.
2165-2181: Test param construction aligns with Lotus JSON mappings
- ConstructorParams uses RawBytes for initcode.
- InvokeContractParams uses input_data vector.
- DelegateCallParams uses Vec for input and TokenAmount::default for value.
These match the Lotus JSON converters introduced in evm_actor_params.rs.
2171-2174: ConfirmInvokeContractParamsserializes identically toRawBytesWe’ve verified in
src/rpc/registry/actors/evm.rsthatMethod::InvokeContractis decoded asRawBytes, but our tests inapi_compare_tests.rsare still serializing theInvokeContractParamsstruct:• src/tool/subcommands/api_cmd/api_compare_tests.rs:2171–2174
• src/tool/subcommands/api_cmd/api_compare_tests.rs:2207–2219Please verify that in every version module (
fil_actor_evm_state::v10throughv16),InvokeContractParamsis declared as a#[serde(transparent)]wrapper over a byte buffer so its CBOR encoding exactly matches whatRawBytesproduces. For example, you can run something like:grep -R "#\\[serde(transparent)\\]" ~/.cargo/registry/src/*/fil_actor_evm_state-*/src/v1{0..6}.rs -nIf any of these versions do not use a transparent wrapper (or if Lotus expects raw bytes), update the tests to send raw bytes directly:
let evm_invoke_contract_params = fvm_ipld_encoding::RawBytes::new(vec![0x11, 0x22, 0x33, 0x44, 0x55]);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (5)
src/rpc/methods/eth/types.rs (3)
65-65: Prefer hex literal and document CBOR prefix meaning.Make the intent explicit that 0x81 is a CBOR array-of-length-1 prefix.
-const LENGTH_BUF_GET_STORAGE_AT_PARAMS: u8 = 129; +/// CBOR major type 4 (array) with length 1: 0x80 + 1 = 0x81 +const LENGTH_BUF_GET_STORAGE_AT_PARAMS: u8 = 0x81;
83-87: AvoidVec::insert(0, ...)to prevent O(n) shifting.Prepending by insertion at index 0 reallocates/moves the entire buffer. Build the vector with capacity and extend instead.
- pub fn serialize_params(&self) -> anyhow::Result<Vec<u8>> { - 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 serialize_params(&self) -> anyhow::Result<Vec<u8>> { + let encoded = fvm_ipld_encoding::to_vec(&RawBytes::new(self.0.to_vec()))?; + let mut with_prefix = Vec::with_capacity(encoded.len() + 1); + with_prefix.push(LENGTH_BUF_GET_STORAGE_AT_PARAMS); + with_prefix.extend_from_slice(&encoded); + Ok(with_prefix) + }
89-96: Add a negative test for prefix mismatch and a round-trip test fordeserialize_params.Good addition. To harden it, add tests that:
- Round-trip via serialize_params -> deserialize_params.
- Fail with a clear error when the CBOR array-length prefix is not 0x81.
Example tests (place alongside existing tests in this module):
#[test] fn get_storage_at_params_roundtrip() { let original = GetStorageAtParams::new(vec![0xde, 0xad, 0xbe, 0xef]).unwrap(); let ser = original.serialize_params().unwrap(); let de = GetStorageAtParams::deserialize_params(&ser).unwrap(); assert_eq!(original.0, de.0); } #[test] fn get_storage_at_params_bad_prefix() { let good = GetStorageAtParams::new(vec![0x0a]).unwrap().serialize_params().unwrap(); let mut bad = good.clone(); bad[0] = 0x80; // wrong CBOR array-length (0 not 1) let err = GetStorageAtParams::deserialize_params(&bad).unwrap_err(); assert!(err.to_string().contains("expected CBOR array of length 1")); }src/lotus_json/actor_states/methods/evm_actor_params.rs (2)
131-134: Clarify size constraint forStorageKeyin JSON schema/docs.
GetStorageAtParamsultimately requires a 32-byte key (left-padded if shorter). Consider documenting this on the JSON field to set expectations for clients.For example, add a doc comment:
// Must be at most 32 bytes; shorter values are left-padded with zeros to 32 bytes.
155-157: Avoid panic on oversizedstorage_keyduring JSON -> params conversion.
GetStorageAtParams::new(..)errors on >32 bytes;unwrap()will panic, potentially taking down the request handler on bad input. SinceHasLotusJson::from_lotus_jsonis infallible, defensively clamp to the last 32 bytes to avoid panics while matching the “right-aligned” behavior.- fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { - GetStorageAtParams::new(lotus_json.storage_key).unwrap() - } + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + // Clamp to last 32 bytes to avoid panic on oversized input; + // shorter inputs are left-padded by `GetStorageAtParams::new`. + let key = if lotus_json.storage_key.len() > 32 { + lotus_json.storage_key[lotus_json.storage_key.len() - 32..].to_vec() + } else { + lotus_json.storage_key + }; + // `new` only fails if input > 32 bytes, which we prevent above. + GetStorageAtParams::new(key).expect("validated length <= 32") + }If strict rejection is desired instead of clamping, the alternative is to validate earlier in the request decoding path and return a structured error (but
HasLotusJson’s signature doesn’t allow that here).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
src/lotus_json/actor_states/methods/evm_actor_params.rs(1 hunks)src/lotus_json/actor_states/methods/mod.rs(1 hunks)src/rpc/methods/eth/types.rs(2 hunks)src/rpc/registry/actors/evm.rs(1 hunks)src/tool/subcommands/api_cmd/api_compare_tests.rs(2 hunks)src/tool/subcommands/api_cmd/test_snapshots.txt(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- src/tool/subcommands/api_cmd/test_snapshots.txt
- src/lotus_json/actor_states/methods/mod.rs
- src/tool/subcommands/api_cmd/api_compare_tests.rs
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/rpc/methods/eth/types.rs (1)
src/rpc/methods/eth.rs (1)
fvm_ipld_encoding(2212-2212)
src/lotus_json/actor_states/methods/evm_actor_params.rs (1)
src/rpc/methods/eth/types.rs (3)
new(71-81)new(413-418)new(425-427)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: tests-release
- GitHub Check: tests
- GitHub Check: Build forest binaries on Linux AMD64
🔇 Additional comments (6)
src/rpc/methods/eth/types.rs (1)
67-69: Deriving Serialize/Deserialize for GetStorageAtParams looks good.This aligns with the added Lotus JSON conversion and simplifies testing and (de)serialization paths.
src/rpc/registry/actors/evm.rs (3)
17-23: ConfirmResurrectparams areConstructorParamsacross v10–v16.Registration assumes
Resurrect’s params mirrorConstructorParams. Please confirm this matches the actors’ state API for all listed versions.If it differs for any version, split the registration by version to use the correct param type(s).
25-29: Good: customGetStorageAtregistration uses validated deserializer.Directly wiring
GetStorageAtParams::deserialize_paramsensures the CBOR prefix and payload are validated. This matches the serialization path added in eth/types.rs.
31-37: No action needed:emptyis supported byregister_actor_methods!
The macro definition in src/rpc/registry/methods_reg.rs explicitly handles(…, empty), and it’s already used elsewhere (in methods_reg.rs tests, reward.rs, cron.rs). You can safely useemptyfor zero-parameter methods here.src/lotus_json/actor_states/methods/evm_actor_params.rs (2)
22-65: Constructor Lotus-JSON mapping is consistent across v10–v16.Field shapes and the snapshots look correct; base64 for RawBytes is aligned with the project’s lotus_json wrapper.
81-128: Delegate-call Lotus-JSON mapping LGTM.Types and conversions (Cid/RawBytes/EthAddress/TokenAmount) are wired properly with lotus_json wrappers. The snapshot covers the shape and expected encoding.
|
I'll let the decode params expert review it: @akaladarshi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/tool/subcommands/api_cmd/api_compare_tests.rs (2)
1900-1904: Add a quick CBOR equivalence check for GetStorageAt to guard against divergence
GetStorageAtParamsin v16 is a tuple with a singleU256field. You’re using a bespokeserialize_params()that constructs the CBOR array header and encodes a RawBytes payload. It’s fine, but worth asserting that it equals the canonicalto_vecencoding of the actor’sGetStorageAtParamsto avoid subtle regressions if either side changes.Apply this diff within the function to add a sanity assertion:
@@ - let evm_get_storage_at_params = GetStorageAtParams::new(vec![0xa])?; + let evm_get_storage_at_params = GetStorageAtParams::new(vec![0xa])?; + // Sanity: our bespoke encoder matches the actor's canonical CBOR for v16 + { + use fil_actor_evm_state::evm_shared::v16::uints::U256; + let mut key = [0u8; 32]; + key[31] = 0x0a; // same storage position as above + let canonical = to_vec(&fil_actor_evm_state::v16::GetStorageAtParams { + storage_key: U256::from_big_endian(&key), + })?; + assert_eq!( + evm_get_storage_at_params.serialize_params()?, + canonical, + "GetStorageAt params CBOR mismatch" + ); + }Citations: v16
GetStorageAtParams { storage_key: U256 }. (docs.rs)
1904-1944: Nit: avoid repeated parsing of EVM addressYou repeatedly call
Address::from_str(EVM_ADDRESS).unwrap(). Parse once and reuse; it reduces noise and removes theunwrap()in test assembly code.Apply this refactor inside
evm_actor_state_decode_params_tests:@@ - let tests = vec![ + let evm_addr = Address::from_str(EVM_ADDRESS)?; + let tests = vec![ RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + evm_addr, 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(), + evm_addr, 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(), + evm_addr, fil_actor_evm_state::v16::Method::GetBytecode as u64, vec![], tipset.key().into(), ))?), RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + evm_addr, fil_actor_evm_state::v16::Method::GetBytecodeHash as u64, vec![], tipset.key().into(), ))?), RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + evm_addr, 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(), + evm_addr, fil_actor_evm_state::v16::Method::InvokeContractDelegate as u64, to_vec(&evm_delegate_call_params)?, tipset.key().into(), ))?), RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + evm_addr, fil_actor_evm_state::v16::Method::GetStorageAt as u64, evm_get_storage_at_params.serialize_params()?, tipset.key().into(), ))?), ];
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
src/tool/subcommands/api_cmd/api_compare_tests.rs(2 hunks)src/tool/subcommands/api_cmd/test_snapshots.txt(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/tool/subcommands/api_cmd/api_compare_tests.rs (2)
src/rpc/methods/eth/types.rs (4)
new(71-81)new(413-418)new(425-427)serialize_params(83-87)src/blocks/tipset.rs (4)
new(242-260)new(494-511)key(336-339)key(530-533)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: Build Ubuntu
- GitHub Check: cargo-publish-dry-run
- GitHub Check: Build MacOS
- GitHub Check: Build forest binaries on Linux AMD64
- GitHub Check: All lint checks
- GitHub Check: tests
- GitHub Check: tests-release
- GitHub Check: Analyze (rust)
- GitHub Check: Analyze (go)
🔇 Additional comments (6)
src/tool/subcommands/api_cmd/api_compare_tests.rs (4)
1873-1873: Good split: EVM state-decode tests are now isolated and discoverableWiring
evm_actor_state_decode_params_tests(tipset)?into the mainstate_decode_params_api_testskeeps concerns separated and makes future EVM additions easier to maintain. Nice.
1883-1899: Param types for Constructor/Invoke/Delegate are correct for v16
ConstructorParams { creator, initcode }matches the spec.InvokeContractParams { input_data }is correct.DelegateCallParams { code, input, caller, value }matches the v16 schema.No issues spotted here.
Citations: fil_actor_evm_state v16 types show these exact structs. (docs.rs)
1910-1914: Resurrect params are correctly reusing ConstructorParamsIn v16,
ResurrectParamsis a type alias toConstructorParams, so reusingevm_constructor_paramshere is correct.Citations:
pub type ResurrectParams = ConstructorParams;in v16. (docs.rs)
1916-1944: Method coverage for EVM decode looks complete for v16Constructor, Resurrect, GetBytecode, GetBytecodeHash, InvokeContract, InvokeContractDelegate, and GetStorageAt are all exercised with plausible params. Good coverage for the stated objective.
Citations: v16 exposes these methods/params in
fil_actor_evm_state. (docs.rs)src/tool/subcommands/api_cmd/test_snapshots.txt (2)
181-187: Snapshots added for all new EVM state-decode casesThe seven EVM snapshots align with the new tests and should stabilize cross-impl compatibility checks.
187-187: Nice: GetStorageAt snapshot includedIncluding
filecoin_evm_getstorageat_statedecodeparams_*.rpcsnap.json.zstensures the custom serialization path is guarded by golden data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/rpc/methods/eth/types.rs (1)
89-97: Import anyhow::Context; current.context(..)calls won’t compile
.context(..)is used here (and elsewhere in this file) butanyhow::Contextisn’t in scope. Bring the trait into scope to fix the compile error. This was flagged earlier and still applies.Apply this diff (outside the selected range) to the imports:
- use anyhow::ensure; + use anyhow::{ensure, Context};
🧹 Nitpick comments (2)
src/rpc/methods/eth/types.rs (2)
65-65: Clarify magic number: prefer0x81and a short doc comment129 is
0x81(CBOR array length = 1). Encoding this as hex with a brief comment makes intent obvious.-const LENGTH_BUF_GET_STORAGE_AT_PARAMS: u8 = 129; +/// 0x81 == CBOR major type 4 (array) with length = 1 +const LENGTH_BUF_GET_STORAGE_AT_PARAMS: u8 = 0x81;
89-97: Make the prefix-mismatch error actionableIncluding the actual prefix helps diagnose malformed inputs quickly.
- ensure!( - prefix == LENGTH_BUF_GET_STORAGE_AT_PARAMS, - "expected CBOR array of length 1" - ); + ensure!( + prefix == LENGTH_BUF_GET_STORAGE_AT_PARAMS, + "expected CBOR array of length 1 (0x81), got 0x{:02x}", + prefix + );If useful, I can also add unit tests covering:
- EOF (empty slice) -> “unexpected EOF”
- Wrong prefix -> the updated error with the observed byte
- Valid payload -> roundtrip via
serialize_params/deserialize_params
Want me to push those tests?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/rpc/methods/eth/types.rs(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/rpc/methods/eth/types.rs (2)
src/rpc/methods/eth.rs (3)
fvm_ipld_encoding(2212-2212)new(508-520)new(673-678)src/utils/encoding/fallback_de_ipld_dagcbor.rs (1)
from_slice(86-95)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: Build Ubuntu
- GitHub Check: cargo-publish-dry-run
- GitHub Check: Build MacOS
- GitHub Check: Build forest binaries on Linux AMD64
- GitHub Check: tests-release
- GitHub Check: tests
- GitHub Check: All lint checks
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (rust)
🔇 Additional comments (2)
src/rpc/methods/eth/types.rs (2)
83-86: Good perf fix: write CBOR directly instead ofinsert(0, …)Pre-sizing with the prefix and using
to_writeravoids an extra allocation and memmove. Looks good.
67-69: DerivingDeserialize/SerializeforGetStorageAtParamslooks goodThis aligns with its usage in RPC plumbing and doesn’t change the CBOR encoding path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/tool/subcommands/api_cmd/api_compare_tests.rs (3)
1883-1899: Param scaffolding for EVM methods looks sensible.
- ConstructorParams zero-creator and dummy initcode are fine for decode tests.
- InvokeContractParams and DelegateCallParams shapes look correct; using a default CID and zero TokenAmount is acceptable here since we only validate decoding.
If you want to reduce churn in future edits, consider hoisting common dummy values (e.g., input bytes, initcode) into small consts right above the function to de-duplicate magic literals.
1902-1945: DRY: parse the EVM address once and reuse it.You repeatedly call
Address::from_str(EVM_ADDRESS).unwrap()for each test case. Parse once to a localevm_addrand reuse to avoid repeated fallible parsing and improve readability.Apply this diff inside the function:
@@ - let tests = vec![ - RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + let evm_addr = Address::from_str(EVM_ADDRESS).expect("valid EVM actor address"); + let tests = vec![ + RpcTest::identity(StateDecodeParams::request(( + evm_addr, 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(), + evm_addr, 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(), + evm_addr, fil_actor_evm_state::v16::Method::GetBytecode as u64, vec![], tipset.key().into(), ))?), RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + evm_addr, fil_actor_evm_state::v16::Method::GetBytecodeHash as u64, vec![], tipset.key().into(), ))?), RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + evm_addr, 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(), + evm_addr, fil_actor_evm_state::v16::Method::InvokeContractDelegate as u64, to_vec(&evm_delegate_call_params)?, tipset.key().into(), ))?), RpcTest::identity(StateDecodeParams::request(( - Address::from_str(EVM_ADDRESS).unwrap(), + evm_addr, fil_actor_evm_state::v16::Method::GetStorageAt as u64, evm_get_storage_at_params.serialize_params()?, tipset.key().into(), ))?), ];
1883-1949: Optional: make tests resilient across protocol versions.Given EVM methods are only available from v10 onward, you could optionally gate this block based on
StateNetworkVersionfromtipsetand skip when < v10. Not strictly necessary for Calibnet snapshots, but it avoids accidental failures when running against older snapshots.I can draft a small helper that fetches the network version for
tipsetand returnsVec<RpcTest>empty if < v10. Want me to add it?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/tool/subcommands/api_cmd/api_compare_tests.rs(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/tool/subcommands/api_cmd/api_compare_tests.rs (1)
src/rpc/methods/eth/types.rs (4)
new(71-81)new(414-419)new(426-428)serialize_params(83-87)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: cargo-publish-dry-run
- GitHub Check: Build MacOS
- GitHub Check: Build Ubuntu
- GitHub Check: Build forest binaries on Linux AMD64
- GitHub Check: tests
- GitHub Check: tests-release
- GitHub Check: All lint checks
- GitHub Check: Analyze (rust)
- GitHub Check: Analyze (go)
🔇 Additional comments (3)
src/tool/subcommands/api_cmd/api_compare_tests.rs (3)
1873-1873: Good call: wire EVM state-decode tests into the suite.This plugs the new EVM cases into the existing StateDecodeParams test assembly at the right place. No functional concerns.
1909-1914: Resurrect using ConstructorParams is correct.In the EVM actor API, ResurrectParams is an alias of ConstructorParams for v10+; using the same CBOR for both is expected. (docs.rs)
1940-1944: Correct encoding for GetStorageAt params.Using
GetStorageAtParams::serialize_params()is the right choice here – it prefixes the sentinel length byte and CBOR-encodes the RawBytes payload as expected by the EVM actor’s decode path. This should keep Forest/Lotus parity for these tests.If you want to harden this further, we can add an additional negative test with a position > 32 bytes and assert both nodes reject with the same error.
akaladarshi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Summary of changes
Changes introduced in this pull request:
Reference issue to close (if applicable)
Closes #5721
Other information and links
Change checklist
Summary by CodeRabbit
New Features
Refactor
Tests