diff --git a/src/lotus_json/actor_states/methods/mod.rs b/src/lotus_json/actor_states/methods/mod.rs index 836d36075545..49d8ecd20ab0 100644 --- a/src/lotus_json/actor_states/methods/mod.rs +++ b/src/lotus_json/actor_states/methods/mod.rs @@ -9,5 +9,6 @@ mod init_exec4_params; mod init_exec_params; mod miner_change_worker_params; mod miner_constructor_params; +mod multisig_actor; mod power_actor; mod reward_methods; diff --git a/src/lotus_json/actor_states/methods/multisig_actor.rs b/src/lotus_json/actor_states/methods/multisig_actor.rs new file mode 100644 index 000000000000..8de3eb4f5e97 --- /dev/null +++ b/src/lotus_json/actor_states/methods/multisig_actor.rs @@ -0,0 +1,467 @@ +// Copyright 2019-2025 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +use super::*; +use crate::shim::address::Address; +use crate::shim::clock::ChainEpoch; +use crate::shim::econ::TokenAmount; +use crate::shim::message::MethodNum; +use fvm_ipld_encoding::RawBytes; +use paste::paste; +use serde::{Deserialize, Serialize}; + +// ConstructorParams +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct ConstructorParamsLotusJson { + #[schemars(with = "LotusJson>")] + #[serde(with = "crate::lotus_json")] + pub signers: Vec
, + + pub num_approvals_threshold: u64, + + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub unlock_duration: ChainEpoch, + + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub start_epoch: ChainEpoch, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct ProposeParamsLotusJson { + #[schemars(with = "LotusJson
")] + #[serde(with = "crate::lotus_json")] + pub to: Address, + + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub value: TokenAmount, + + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub method: MethodNum, + + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub params: RawBytes, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct TxnIDParamsLotusJson { + #[schemars(with = "i64")] + #[serde(rename = "ID")] + pub id: i64, + + #[schemars(with = "LotusJson>")] + #[serde(with = "crate::lotus_json")] + pub proposal_hash: Vec, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct AddSignerParamsLotusJson { + #[schemars(with = "LotusJson
")] + #[serde(with = "crate::lotus_json")] + pub signer: Address, + + pub increase: bool, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct RemoveSignerParamsLotusJson { + #[schemars(with = "LotusJson
")] + #[serde(with = "crate::lotus_json")] + pub signer: Address, + + pub decrease: bool, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct SwapSignerParamsLotusJson { + #[schemars(with = "LotusJson
")] + #[serde(with = "crate::lotus_json")] + pub from: Address, + + #[schemars(with = "LotusJson
")] + #[serde(with = "crate::lotus_json")] + pub to: Address, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct ChangeNumApprovalsThresholdParamsLotusJson { + pub new_threshold: u64, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct LockBalanceParamsLotusJson { + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub start_epoch: ChainEpoch, + + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub unlock_duration: ChainEpoch, + + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub amount: TokenAmount, +} + +// Macro to implement HasLotusJson for ConstructorParams across all versions +macro_rules! impl_multisig_constructor_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_multisig_state::[]::ConstructorParams { + type LotusJson = ConstructorParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "Signers": ["f01234", "f01235"], + "NumApprovalsThreshold": 2, + "UnlockDuration": 100, + "StartEpoch": 0, + }), + Self { + signers: vec![Address::new_id(1234).into(), Address::new_id(1235).into()], + num_approvals_threshold: 2, + unlock_duration: 100, + start_epoch: 0, + }, + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + ConstructorParamsLotusJson { + signers: self.signers.into_iter().map(|a| a.into()).collect(), + num_approvals_threshold: self.num_approvals_threshold, + unlock_duration: self.unlock_duration, + start_epoch: self.start_epoch, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + signers: lotus_json.signers.into_iter().map(|a| a.into()).collect(), + num_approvals_threshold: lotus_json.num_approvals_threshold, + unlock_duration: lotus_json.unlock_duration, + start_epoch: lotus_json.start_epoch, + } + } + } + } + )+ + }; +} + +// Macro to implement HasLotusJson for ProposeParams across all versions +macro_rules! impl_multisig_propose_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_multisig_state::[]::ProposeParams { + type LotusJson = ProposeParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "To": "f01234", + "Value": "1000000000000000000", + "Method": 0, + "Params": "Ynl0ZSBhcnJheQ==", + }), + Self { + to: Address::new_id(1234).into(), + value: TokenAmount::from_atto(1000000000000000000u64).into(), + method: 0, + params: RawBytes::new(b"byte array".to_vec()), + }, + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + ProposeParamsLotusJson { + to: self.to.into(), + value: self.value.into(), + method: self.method, + params: self.params, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + to: lotus_json.to.into(), + value: lotus_json.value.into(), + method: lotus_json.method, + params: lotus_json.params, + } + } + } + } + )+ + }; +} + +// Macro to implement HasLotusJson for TxnIDParams across all versions +macro_rules! impl_multisig_txn_id_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_multisig_state::[]::TxnIDParams { + type LotusJson = TxnIDParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "ID": 1234, + "ProposalHash": "YWJjZGVmZ2g=", + }), + Self { + id: fil_actor_multisig_state::[]::TxnID(1234), + proposal_hash: b"abcdefgh".to_vec(), + }, + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + TxnIDParamsLotusJson { + id: self.id.0, + proposal_hash: self.proposal_hash, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + id: fil_actor_multisig_state::[]::TxnID(lotus_json.id), + proposal_hash: lotus_json.proposal_hash, + } + } + } + } + )+ + }; +} + +// Macro to implement HasLotusJson for AddSignerParams across all versions +macro_rules! impl_multisig_add_signer_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_multisig_state::[]::AddSignerParams { + type LotusJson = AddSignerParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "Signer": "f01234", + "Increase": true, + }), + Self { + signer: Address::new_id(1234).into(), + increase: true, + }, + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + AddSignerParamsLotusJson { + signer: self.signer.into(), + increase: self.increase, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + signer: lotus_json.signer.into(), + increase: lotus_json.increase, + } + } + } + } + )+ + }; +} + +// Macro to implement HasLotusJson for RemoveSignerParams across all versions +macro_rules! impl_multisig_remove_signer_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_multisig_state::[]::RemoveSignerParams { + type LotusJson = RemoveSignerParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "Signer": "f01234", + "Decrease": false, + }), + Self { + signer: Address::new_id(1234).into(), + decrease: false, + }, + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + RemoveSignerParamsLotusJson { + signer: self.signer.into(), + decrease: self.decrease, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + signer: lotus_json.signer.into(), + decrease: lotus_json.decrease, + } + } + } + } + )+ + }; +} + +// Macro to implement HasLotusJson for SwapSignerParams across all versions +macro_rules! impl_multisig_swap_signer_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_multisig_state::[]::SwapSignerParams { + type LotusJson = SwapSignerParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "From": "f01234", + "To": "f01235", + }), + Self { + from: Address::new_id(1234).into(), + to: Address::new_id(1235).into(), + }, + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + SwapSignerParamsLotusJson { + from: self.from.into(), + to: self.to.into(), + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + from: lotus_json.from.into(), + to: lotus_json.to.into(), + } + } + } + } + )+ + }; +} + +// Macro to implement HasLotusJson for ChangeNumApprovalsThresholdParams across all versions +macro_rules! impl_multisig_change_num_approvals_threshold_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_multisig_state::[]::ChangeNumApprovalsThresholdParams { + type LotusJson = ChangeNumApprovalsThresholdParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "NewThreshold": 3, + }), + Self { new_threshold: 3 }, + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + ChangeNumApprovalsThresholdParamsLotusJson { + new_threshold: self.new_threshold, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + new_threshold: lotus_json.new_threshold, + } + } + } + } + )+ + }; +} + +// Macro to implement HasLotusJson for LockBalanceParams across all versions +macro_rules! impl_multisig_lock_balance_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_multisig_state::[]::LockBalanceParams { + type LotusJson = LockBalanceParamsLotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![( + json!({ + "StartEpoch": 100, + "UnlockDuration": 200, + "Amount": "5000000000000000000", + }), + Self { + start_epoch: 100, + unlock_duration: 200, + amount: TokenAmount::from_atto(5000000000000000000u64).into(), + }, + )] + } + + fn into_lotus_json(self) -> Self::LotusJson { + LockBalanceParamsLotusJson { + start_epoch: self.start_epoch, + unlock_duration: self.unlock_duration, + amount: self.amount.into(), + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + start_epoch: lotus_json.start_epoch, + unlock_duration: lotus_json.unlock_duration, + amount: lotus_json.amount.into(), + } + } + } + } + )+ + }; +} + +impl_multisig_constructor_params!(8, 9, 10, 11, 12, 13, 14, 15, 16); +impl_multisig_propose_params!(8, 9, 10, 11, 12, 13, 14, 15, 16); +impl_multisig_txn_id_params!(8, 9, 10, 11, 12, 13, 14, 15, 16); +impl_multisig_add_signer_params!(8, 9, 10, 11, 12, 13, 14, 15, 16); +impl_multisig_remove_signer_params!(8, 9, 10, 11, 12, 13, 14, 15, 16); +impl_multisig_swap_signer_params!(8, 9, 10, 11, 12, 13, 14, 15, 16); +impl_multisig_change_num_approvals_threshold_params!(8, 9, 10, 11, 12, 13, 14, 15, 16); +impl_multisig_lock_balance_params!(8, 9, 10, 11, 12, 13, 14, 15, 16); diff --git a/src/rpc/registry/actors/mod.rs b/src/rpc/registry/actors/mod.rs index ce52f05d104f..7d995f8e3658 100644 --- a/src/rpc/registry/actors/mod.rs +++ b/src/rpc/registry/actors/mod.rs @@ -5,6 +5,7 @@ pub(crate) mod account; pub(crate) mod evm; pub(crate) mod init; pub(crate) mod miner; +pub(crate) mod multisig; pub(crate) mod power; pub(crate) mod reward; pub(crate) mod system; diff --git a/src/rpc/registry/actors/multisig.rs b/src/rpc/registry/actors/multisig.rs new file mode 100644 index 000000000000..543e11d1890a --- /dev/null +++ b/src/rpc/registry/actors/multisig.rs @@ -0,0 +1,89 @@ +// 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 anyhow::Result; +use cid::Cid; + +// Macro for version 8 that doesn't have UniversalReceiverHook +macro_rules! register_multisig_v8 { + ($registry:expr, $code_cid:expr, $state_version:path) => {{ + use $state_version::{ + AddSignerParams, ChangeNumApprovalsThresholdParams, ConstructorParams, + LockBalanceParams, Method, ProposeParams, RemoveSignerParams, SwapSignerParams, + TxnIDParams, + }; + + register_actor_methods!( + $registry, + $code_cid, + [ + (Method::Constructor, ConstructorParams), + (Method::Propose, ProposeParams), + (Method::Approve, TxnIDParams), + (Method::Cancel, TxnIDParams), + (Method::AddSigner, AddSignerParams), + (Method::RemoveSigner, RemoveSignerParams), + (Method::SwapSigner, SwapSignerParams), + ( + Method::ChangeNumApprovalsThreshold, + ChangeNumApprovalsThresholdParams + ), + (Method::LockBalance, LockBalanceParams), + ] + ); + }}; +} + +// Macro for versions 9+ that has UniversalReceiverHook +macro_rules! register_multisig_v9_plus { + ($registry:expr, $code_cid:expr, $state_version:path) => {{ + use $state_version::{ + AddSignerParams, ChangeNumApprovalsThresholdParams, ConstructorParams, + LockBalanceParams, Method, ProposeParams, RemoveSignerParams, SwapSignerParams, + TxnIDParams, + }; + + register_actor_methods!( + $registry, + $code_cid, + [ + (Method::Constructor, ConstructorParams), + (Method::Propose, ProposeParams), + (Method::Approve, TxnIDParams), + (Method::Cancel, TxnIDParams), + (Method::AddSigner, AddSignerParams), + (Method::RemoveSigner, RemoveSignerParams), + (Method::SwapSigner, SwapSignerParams), + ( + Method::ChangeNumApprovalsThreshold, + ChangeNumApprovalsThresholdParams + ), + (Method::LockBalance, LockBalanceParams), + ] + ); + + // UniversalReceiverHook doesn't have specific params + register_actor_methods!( + $registry, + $code_cid, + [(Method::UniversalReceiverHook, empty)] + ); + }}; +} + +pub(crate) fn register_actor_methods(registry: &mut MethodRegistry, cid: Cid, version: u64) { + match version { + 8 => register_multisig_v8!(registry, cid, fil_actor_multisig_state::v8), + 9 => register_multisig_v9_plus!(registry, cid, fil_actor_multisig_state::v9), + 10 => register_multisig_v9_plus!(registry, cid, fil_actor_multisig_state::v10), + 11 => register_multisig_v9_plus!(registry, cid, fil_actor_multisig_state::v11), + 12 => register_multisig_v9_plus!(registry, cid, fil_actor_multisig_state::v12), + 13 => register_multisig_v9_plus!(registry, cid, fil_actor_multisig_state::v13), + 14 => register_multisig_v9_plus!(registry, cid, fil_actor_multisig_state::v14), + 15 => register_multisig_v9_plus!(registry, cid, fil_actor_multisig_state::v15), + 16 => register_multisig_v9_plus!(registry, cid, fil_actor_multisig_state::v16), + _ => {} + } +} diff --git a/src/rpc/registry/methods_reg.rs b/src/rpc/registry/methods_reg.rs index bdabd0d7768c..eccfe1d75818 100644 --- a/src/rpc/registry/methods_reg.rs +++ b/src/rpc/registry/methods_reg.rs @@ -73,7 +73,9 @@ impl MethodRegistry { } fn register_known_methods(&mut self) { - use crate::rpc::registry::actors::{account, evm, init, miner, power, reward, system}; + use crate::rpc::registry::actors::{ + account, evm, init, miner, multisig, power, reward, system, + }; for (&cid, &(actor_type, version)) in ACTOR_REGISTRY.iter() { match actor_type { @@ -86,6 +88,7 @@ impl MethodRegistry { BuiltinActor::System => system::register_actor_methods(self, cid, version), BuiltinActor::Power => power::register_actor_methods(self, cid, version), BuiltinActor::Reward => reward::register_actor_methods(self, cid, version), + BuiltinActor::Multisig => multisig::register_actor_methods(self, cid, version), _ => {} } } @@ -113,7 +116,9 @@ macro_rules! register_actor_methods { if bytes.is_empty() { Ok(serde_json::json!({})) } else { - Ok(fvm_ipld_encoding::from_slice(bytes)?) + use base64::{Engine as _, prelude::BASE64_STANDARD}; + // Return bytes as base64 string, matching Lotus behavior + Ok(serde_json::json!(BASE64_STANDARD.encode(bytes).as_str())) } }, ); @@ -312,4 +317,30 @@ mod test { assert!(result.is_ok(), "Should handle CBOR null: {result:?}"); } + + #[test] + fn test_empty_param_type_with_bytes_returns_base64() { + let mut registry = MethodRegistry::new(); + let test_cid = create_test_cid(b"empty_param_test"); + + // Register a method with empty parameter type + register_actor_methods!(registry, test_cid, [(42, empty)]); + + // Test with empty bytes - should return empty JSON object + let result = registry.deserialize_params(&test_cid, 42, &[]); + assert!(result.is_ok()); + let json_value = result.unwrap().unwrap(); + assert_eq!(json_value, json!({})); + + // Test with non-empty bytes - should return base64 encoded string + let test_bytes = vec![0x82, 0x18, 0x2a, 0x44, 0x12, 0x34, 0x56, 0x78]; // Sample CBOR bytes + let result = registry.deserialize_params(&test_cid, 42, &test_bytes); + assert!(result.is_ok()); + let json_value = result.unwrap().unwrap(); + + use base64::engine::{Engine as _, general_purpose::STANDARD}; + let expected_base64 = STANDARD.encode(&test_bytes); + assert_eq!(json_value, json!(expected_base64)); + assert_eq!(json_value.as_str().unwrap(), "ghgqRBI0Vng="); + } } diff --git a/src/tool/subcommands/api_cmd/api_compare_tests.rs b/src/tool/subcommands/api_cmd/api_compare_tests.rs index 9d5b9f8607fb..393b4291ec0c 100644 --- a/src/tool/subcommands/api_cmd/api_compare_tests.rs +++ b/src/tool/subcommands/api_cmd/api_compare_tests.rs @@ -39,6 +39,7 @@ use crate::tool::subcommands::api_cmd::report::ReportBuilder; use crate::utils::proofs_api::{self, ensure_proof_params_downloaded}; use crate::{Config, rpc}; use ahash::HashMap; +use base64::{Engine as _, prelude::BASE64_STANDARD}; use bls_signatures::Serialize as _; use chrono::Utc; use cid::Cid; @@ -1896,6 +1897,49 @@ fn state_decode_params_api_tests(tipset: &Tipset) -> anyhow::Result ))), }; + let multisig_constructor_params = fil_actor_multisig_state::v16::ConstructorParams { + signers: vec![Address::new_id(1000).into(), Address::new_id(1001).into()], + num_approvals_threshold: Default::default(), + unlock_duration: Default::default(), + start_epoch: Default::default(), + }; + + let multisig_propose_params = fil_actor_multisig_state::v16::ProposeParams { + to: Address::new_id(1000).into(), + value: Default::default(), + method: 0, + params: Default::default(), + }; + + let multisig_tx_id_params = fil_actor_multisig_state::v16::TxnIDParams { + id: Default::default(), + proposal_hash: vec![Default::default()], + }; + + let multisig_add_signer_params = fil_actor_multisig_state::v16::AddSignerParams { + signer: Address::new_id(1012).into(), + increase: false, + }; + + let multisig_remove_signer_params = fil_actor_multisig_state::v16::RemoveSignerParams { + signer: Address::new_id(1012).into(), + decrease: false, + }; + + let multisig_swap_signer_params = fil_actor_multisig_state::v16::SwapSignerParams { + from: Address::new_id(122).into(), + to: Address::new_id(1234).into(), + }; + + let multisig_change_num_app_params = + fil_actor_multisig_state::v16::ChangeNumApprovalsThresholdParams { new_threshold: 2 }; + + let multisig_lock_bal_params = fil_actor_multisig_state::v16::LockBalanceParams { + start_epoch: 22, + unlock_duration: 12, + amount: Default::default(), + }; + let tests = vec![ RpcTest::identity(StateDecodeParams::request(( MINER_ADDRESS, @@ -2005,14 +2049,6 @@ fn state_decode_params_api_tests(tipset: &Tipset) -> anyhow::Result to_vec(&power_miner_raw_params)?, tipset.key().into(), ))?), - // Not supported by the lotus, - // TODO(go-state-types): https://github.com/filecoin-project/go-state-types/issues/401 - // RpcTest::identity(StateDecodeParams::request(( - // Address::POWER_ACTOR, - // Method::MinerPowerExported as u64, - // to_vec(&power_miner_power_exp_params)?, - // tipset.key().into(), - // ))?), RpcTest::identity(StateDecodeParams::request(( Address::POWER_ACTOR, fil_actor_power_state::v16::Method::Constructor as u64, @@ -2049,6 +2085,80 @@ fn state_decode_params_api_tests(tipset: &Tipset) -> anyhow::Result vec![], tipset.key().into(), ))?), + // Not supported by the lotus, + // TODO(go-state-types): https://github.com/filecoin-project/go-state-types/issues/401 + // RpcTest::identity(StateDecodeParams::request(( + // Address::POWER_ACTOR, + // Method::MinerPowerExported as u64, + // to_vec(&power_miner_power_exp_params)?, + // tipset.key().into(), + // ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::Constructor as u64, + to_vec(&multisig_constructor_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::Propose as u64, + to_vec(&multisig_propose_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::Approve as u64, + to_vec(&multisig_tx_id_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::Cancel as u64, + to_vec(&multisig_tx_id_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::AddSigner as u64, + to_vec(&multisig_add_signer_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::RemoveSigner as u64, + to_vec(&multisig_remove_signer_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::SwapSigner as u64, + to_vec(&multisig_swap_signer_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::ChangeNumApprovalsThreshold as u64, + to_vec(&multisig_change_num_app_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::LockBalance as u64, + to_vec(&multisig_lock_bal_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::LockBalance as u64, + to_vec(&multisig_lock_bal_params)?, + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + Address::new_id(18101), // https://calibration.filscan.io/en/address/t018101/, + fil_actor_multisig_state::v16::Method::UniversalReceiverHook as u64, + BASE64_STANDARD.decode("ghgqRBI0Vng=").unwrap(), + tipset.key().into(), + ))?), RpcTest::identity(StateDecodeParams::request(( Address::SYSTEM_ACTOR, fil_actor_system_state::v16::Method::Constructor as u64, diff --git a/src/tool/subcommands/api_cmd/test_snapshots.txt b/src/tool/subcommands/api_cmd/test_snapshots.txt index 8132fc8e4c0a..7999437a279b 100644 --- a/src/tool/subcommands/api_cmd/test_snapshots.txt +++ b/src/tool/subcommands/api_cmd/test_snapshots.txt @@ -151,6 +151,16 @@ filecoin_power_currenttotalpower_statedecodeparams_1754479441718859.rpcsnap.json filecoin_power_onepochtickend_statedecodeparams_1754479441718920.rpcsnap.json.zst filecoin_reward_thisepochreward_statedecodeparams_1754479441718972.rpcsnap.json.zst filecoin_power_networkrawpower_statedecodeparams_1754479441719018.rpcsnap.json.zst +filecoin_multisig_statedecodeparams_1754230255606413.rpcsnap.json.zst +filecoin_multisig_statedecodeparams_1754230255613553.rpcsnap.json.zst +filecoin_multisig_statedecodeparams_1754230255623566.rpcsnap.json.zst +filecoin_multisig_statedecodeparams_1754230255631530.rpcsnap.json.zst +filecoin_multisig_statedecodeparams_1754230255631697.rpcsnap.json.zst +filecoin_multisig_statedecodeparams_1754230255631789.rpcsnap.json.zst +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_statereplay_1743504051038215.rpcsnap.json.zst filecoin_statesearchmsg_1741784596636715.rpcsnap.json.zst filecoin_statesearchmsglimited_1741784596704876.rpcsnap.json.zst