Skip to content
Merged
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
1 change: 1 addition & 0 deletions src/rpc/registry/actors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ pub(crate) mod account;
pub(crate) mod evm;
pub(crate) mod init;
pub(crate) mod miner;
pub(crate) mod system;
32 changes: 32 additions & 0 deletions src/rpc/registry/actors/system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2019-2025 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::rpc::registry::methods_reg::{MethodRegistry, register_actor_methods};
use crate::shim::message::MethodNum;
use cid::Cid;

macro_rules! register_system_version {
($registry:expr, $code_cid:expr, $state_version:path) => {{
use $state_version::*;

register_actor_methods!(
$registry,
$code_cid,
[
(Method::Constructor, empty), // constructor method doesn't accept any kind of param
]
);
}};
}

pub(crate) fn register_actor_methods(registry: &mut MethodRegistry, cid: Cid) {
register_system_version!(registry, cid, fil_actor_system_state::v8);
register_system_version!(registry, cid, fil_actor_system_state::v9);
register_system_version!(registry, cid, fil_actor_system_state::v10);
register_system_version!(registry, cid, fil_actor_system_state::v11);
register_system_version!(registry, cid, fil_actor_system_state::v12);
register_system_version!(registry, cid, fil_actor_system_state::v13);
register_system_version!(registry, cid, fil_actor_system_state::v14);
register_system_version!(registry, cid, fil_actor_system_state::v15);
register_system_version!(registry, cid, fil_actor_system_state::v16);
}
8 changes: 0 additions & 8 deletions src/rpc/registry/actors_reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ impl ActorRegistry {

pub(crate) static ACTOR_REGISTRY: LazyLock<ActorRegistry> = LazyLock::new(ActorRegistry::new);

pub fn get_actor_type_from_code(code_cid: &Cid) -> Result<(BuiltinActor, u64)> {
ACTOR_REGISTRY
.map
.get(code_cid)
.copied()
.ok_or_else(|| anyhow!("Unknown actor code CID: {}", code_cid))
}

macro_rules! load_and_serialize_state {
($store:expr, $code_cid:expr, $state_cid:expr, $actor_type:expr, $state_type:ty) => {{
let state = <$state_type>::load($store, *$code_cid, *$state_cid).context(format!(
Expand Down
52 changes: 34 additions & 18 deletions src/rpc/registry/methods_reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::lotus_json::HasLotusJson;
use crate::rpc::registry::actors::system;
use crate::rpc::registry::actors_reg::{ACTOR_REGISTRY, ActorRegistry};
use crate::shim::machine::BuiltinActor;
use crate::shim::message::MethodNum;
use ahash::{HashMap, HashMapExt};
Expand All @@ -11,8 +13,6 @@ use serde::de::DeserializeOwned;
use serde_json::Value;
use std::sync::LazyLock;

use crate::rpc::registry::actors_reg::{ACTOR_REGISTRY, get_actor_type_from_code};

// Global registry for method parameter deserialization
static METHOD_REGISTRY: LazyLock<MethodRegistry> =
LazyLock::new(MethodRegistry::with_known_methods);
Expand Down Expand Up @@ -63,7 +63,7 @@ impl MethodRegistry {
return Ok(Some(deserializer(params_bytes)?));
}

let (actor_type, version) = get_actor_type_from_code(code_cid)?;
let (actor_type, version) = ActorRegistry::get_actor_details_from_code(code_cid)?;

bail!(
"No deserializer registered for actor type {:?} (v{}), method {}",
Expand All @@ -82,6 +82,7 @@ impl MethodRegistry {
BuiltinActor::Miner => miner::register_miner_actor_methods(self, cid),
BuiltinActor::EVM => evm::register_evm_actor_methods(self, cid),
BuiltinActor::Init => init::register_actor_methods(self, cid),
BuiltinActor::System => system::register_actor_methods(self, cid),
_ => {}
}
}
Expand All @@ -97,6 +98,25 @@ pub fn deserialize_params(
}

macro_rules! register_actor_methods {
// Handle empty params case
($registry:expr, $code_cid:expr, [
$( ($method:expr, empty) ),* $(,)?
]) => {
$(
$registry.register_method(
$code_cid,
$method as MethodNum,
|bytes| -> anyhow::Result<()> {
if bytes.is_empty() {
Ok(())
} else {
Ok(fvm_ipld_encoding::from_slice(bytes)?)
}
},
);
)*
};

($registry:expr, $code_cid:expr, [
$( ($method:expr, $param_type:ty) ),* $(,)?
]) => {
Expand Down Expand Up @@ -250,21 +270,6 @@ mod test {
}
}

#[test]
fn test_unsupported_actor_types() {
// Test actors that are not registered in the method registry
if let Some(system_cid) = get_real_actor_cid(BuiltinActor::System) {
let method_num = 1;

let result = deserialize_params(&system_cid, method_num, &[]);
assert!(result.is_err());

let error_msg = result.unwrap_err().to_string();
assert!(error_msg.contains("No deserializer registered for actor type"));
assert!(error_msg.contains("System"));
}
}

#[test]
fn test_register_actor_methods_macro() {
let mut registry = MethodRegistry::new();
Expand Down Expand Up @@ -292,4 +297,15 @@ mod test {
let result3 = registry.deserialize_params(&test_cid, 3, &encoded);
assert!(result3.is_err());
}

#[test]
fn test_system_actor_deserialize_params_cbor_null() {
let system_cid = get_real_actor_cid(BuiltinActor::System)
.expect("Should have System actor CID in registry");

// Test with null data
let result = deserialize_params(&system_cid, 1, &[]);

assert!(result.is_ok(), "Should handle CBOR null: {result:?}");
}
}
Loading