Skip to content

Commit 74892d1

Browse files
authored
feat: add support for system actor in state decode params API (#5861)
1 parent ec25ca9 commit 74892d1

4 files changed

Lines changed: 67 additions & 26 deletions

File tree

src/rpc/registry/actors/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pub(crate) mod account;
55
pub(crate) mod evm;
66
pub(crate) mod init;
77
pub(crate) mod miner;
8+
pub(crate) mod system;

src/rpc/registry/actors/system.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2019-2025 ChainSafe Systems
2+
// SPDX-License-Identifier: Apache-2.0, MIT
3+
4+
use crate::rpc::registry::methods_reg::{MethodRegistry, register_actor_methods};
5+
use crate::shim::message::MethodNum;
6+
use cid::Cid;
7+
8+
macro_rules! register_system_version {
9+
($registry:expr, $code_cid:expr, $state_version:path) => {{
10+
use $state_version::*;
11+
12+
register_actor_methods!(
13+
$registry,
14+
$code_cid,
15+
[
16+
(Method::Constructor, empty), // constructor method doesn't accept any kind of param
17+
]
18+
);
19+
}};
20+
}
21+
22+
pub(crate) fn register_actor_methods(registry: &mut MethodRegistry, cid: Cid) {
23+
register_system_version!(registry, cid, fil_actor_system_state::v8);
24+
register_system_version!(registry, cid, fil_actor_system_state::v9);
25+
register_system_version!(registry, cid, fil_actor_system_state::v10);
26+
register_system_version!(registry, cid, fil_actor_system_state::v11);
27+
register_system_version!(registry, cid, fil_actor_system_state::v12);
28+
register_system_version!(registry, cid, fil_actor_system_state::v13);
29+
register_system_version!(registry, cid, fil_actor_system_state::v14);
30+
register_system_version!(registry, cid, fil_actor_system_state::v15);
31+
register_system_version!(registry, cid, fil_actor_system_state::v16);
32+
}

src/rpc/registry/actors_reg.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,6 @@ impl ActorRegistry {
5050

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

53-
pub fn get_actor_type_from_code(code_cid: &Cid) -> Result<(BuiltinActor, u64)> {
54-
ACTOR_REGISTRY
55-
.map
56-
.get(code_cid)
57-
.copied()
58-
.ok_or_else(|| anyhow!("Unknown actor code CID: {}", code_cid))
59-
}
60-
6153
macro_rules! load_and_serialize_state {
6254
($store:expr, $code_cid:expr, $state_cid:expr, $actor_type:expr, $state_type:ty) => {{
6355
let state = <$state_type>::load($store, *$code_cid, *$state_cid).context(format!(

src/rpc/registry/methods_reg.rs

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// SPDX-License-Identifier: Apache-2.0, MIT
33

44
use crate::lotus_json::HasLotusJson;
5+
use crate::rpc::registry::actors::system;
6+
use crate::rpc::registry::actors_reg::{ACTOR_REGISTRY, ActorRegistry};
57
use crate::shim::machine::BuiltinActor;
68
use crate::shim::message::MethodNum;
79
use ahash::{HashMap, HashMapExt};
@@ -11,8 +13,6 @@ use serde::de::DeserializeOwned;
1113
use serde_json::Value;
1214
use std::sync::LazyLock;
1315

14-
use crate::rpc::registry::actors_reg::{ACTOR_REGISTRY, get_actor_type_from_code};
15-
1616
// Global registry for method parameter deserialization
1717
static METHOD_REGISTRY: LazyLock<MethodRegistry> =
1818
LazyLock::new(MethodRegistry::with_known_methods);
@@ -63,7 +63,7 @@ impl MethodRegistry {
6363
return Ok(Some(deserializer(params_bytes)?));
6464
}
6565

66-
let (actor_type, version) = get_actor_type_from_code(code_cid)?;
66+
let (actor_type, version) = ActorRegistry::get_actor_details_from_code(code_cid)?;
6767

6868
bail!(
6969
"No deserializer registered for actor type {:?} (v{}), method {}",
@@ -82,6 +82,7 @@ impl MethodRegistry {
8282
BuiltinActor::Miner => miner::register_miner_actor_methods(self, cid),
8383
BuiltinActor::EVM => evm::register_evm_actor_methods(self, cid),
8484
BuiltinActor::Init => init::register_actor_methods(self, cid),
85+
BuiltinActor::System => system::register_actor_methods(self, cid),
8586
_ => {}
8687
}
8788
}
@@ -97,6 +98,25 @@ pub fn deserialize_params(
9798
}
9899

99100
macro_rules! register_actor_methods {
101+
// Handle empty params case
102+
($registry:expr, $code_cid:expr, [
103+
$( ($method:expr, empty) ),* $(,)?
104+
]) => {
105+
$(
106+
$registry.register_method(
107+
$code_cid,
108+
$method as MethodNum,
109+
|bytes| -> anyhow::Result<()> {
110+
if bytes.is_empty() {
111+
Ok(())
112+
} else {
113+
Ok(fvm_ipld_encoding::from_slice(bytes)?)
114+
}
115+
},
116+
);
117+
)*
118+
};
119+
100120
($registry:expr, $code_cid:expr, [
101121
$( ($method:expr, $param_type:ty) ),* $(,)?
102122
]) => {
@@ -250,21 +270,6 @@ mod test {
250270
}
251271
}
252272

253-
#[test]
254-
fn test_unsupported_actor_types() {
255-
// Test actors that are not registered in the method registry
256-
if let Some(system_cid) = get_real_actor_cid(BuiltinActor::System) {
257-
let method_num = 1;
258-
259-
let result = deserialize_params(&system_cid, method_num, &[]);
260-
assert!(result.is_err());
261-
262-
let error_msg = result.unwrap_err().to_string();
263-
assert!(error_msg.contains("No deserializer registered for actor type"));
264-
assert!(error_msg.contains("System"));
265-
}
266-
}
267-
268273
#[test]
269274
fn test_register_actor_methods_macro() {
270275
let mut registry = MethodRegistry::new();
@@ -292,4 +297,15 @@ mod test {
292297
let result3 = registry.deserialize_params(&test_cid, 3, &encoded);
293298
assert!(result3.is_err());
294299
}
300+
301+
#[test]
302+
fn test_system_actor_deserialize_params_cbor_null() {
303+
let system_cid = get_real_actor_cid(BuiltinActor::System)
304+
.expect("Should have System actor CID in registry");
305+
306+
// Test with null data
307+
let result = deserialize_params(&system_cid, 1, &[]);
308+
309+
assert!(result.is_ok(), "Should handle CBOR null: {result:?}");
310+
}
295311
}

0 commit comments

Comments
 (0)