From a0316a13148ef112392dfb12141b5036cfd558f1 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Tue, 26 Aug 2025 13:22:30 +0530 Subject: [PATCH 1/4] add support for the payment channel actor in state decode params api --- src/lotus_json/actor_states/methods/mod.rs | 1 + .../actor_states/methods/paych_params.rs | 546 ++++++++++++++++++ src/rpc/registry/actors/mod.rs | 1 + src/rpc/registry/actors/payment_channel.rs | 44 ++ src/rpc/registry/methods_reg.rs | 6 +- 5 files changed, 597 insertions(+), 1 deletion(-) create mode 100644 src/lotus_json/actor_states/methods/paych_params.rs create mode 100644 src/rpc/registry/actors/payment_channel.rs diff --git a/src/lotus_json/actor_states/methods/mod.rs b/src/lotus_json/actor_states/methods/mod.rs index 02c6312aa7e3..2146a6f65c5d 100644 --- a/src/lotus_json/actor_states/methods/mod.rs +++ b/src/lotus_json/actor_states/methods/mod.rs @@ -13,6 +13,7 @@ mod init_exec_params; mod miner_change_worker_params; mod miner_constructor_params; mod multisig_actor; +mod paych_params; mod power_actor; mod reward_methods; pub mod verified_reg_actor; diff --git a/src/lotus_json/actor_states/methods/paych_params.rs b/src/lotus_json/actor_states/methods/paych_params.rs new file mode 100644 index 000000000000..42901f7dc381 --- /dev/null +++ b/src/lotus_json/actor_states/methods/paych_params.rs @@ -0,0 +1,546 @@ +// 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 fvm_ipld_encoding::RawBytes; +use paste::paste; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct ConstructorParamsLotusJson { + #[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 ModVerifyParamsLotusJson { + #[schemars(with = "LotusJson
")] + #[serde(with = "crate::lotus_json")] + pub actor: Address, + pub method: u64, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub data: RawBytes, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct MergeLotusJson { + pub lane: u64, + pub nonce: u64, +} + +// Version-specific structs for different FVM versions to avoid conversion issues +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct SignedVoucherV2LotusJson { + #[schemars(with = "LotusJson
")] + #[serde(with = "crate::lotus_json")] + pub channel_addr: Address, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub time_lock_min: ChainEpoch, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub time_lock_max: ChainEpoch, + #[schemars(with = "LotusJson>")] + #[serde(with = "crate::lotus_json", rename = "SecretHash")] + pub secret_pre_image: Vec, + pub extra: Option, + pub lane: u64, + pub nonce: u64, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub amount: TokenAmount, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub min_settle_height: ChainEpoch, + // Lotus returns null (not []) when there are no merges; model as Option, so None means empty. + pub merges: Option>, + #[schemars(with = "LotusJson>")] + #[serde(with = "crate::lotus_json")] + pub signature: Option, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct SignedVoucherV3LotusJson { + #[schemars(with = "LotusJson
")] + #[serde(with = "crate::lotus_json")] + pub channel_addr: Address, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub time_lock_min: ChainEpoch, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub time_lock_max: ChainEpoch, + #[schemars(with = "LotusJson>")] + #[serde(with = "crate::lotus_json", rename = "SecretHash")] + pub secret_pre_image: Vec, + pub extra: Option, + pub lane: u64, + pub nonce: u64, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub amount: TokenAmount, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub min_settle_height: ChainEpoch, + // Lotus returns null (not []) when there are no merges; model as Option, so None means empty. + pub merges: Option>, + #[schemars(with = "LotusJson>")] + #[serde(with = "crate::lotus_json")] + pub signature: Option, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct SignedVoucherV4LotusJson { + #[schemars(with = "LotusJson
")] + #[serde(with = "crate::lotus_json")] + pub channel_addr: Address, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub time_lock_min: ChainEpoch, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub time_lock_max: ChainEpoch, + #[schemars(with = "LotusJson>")] + #[serde(with = "crate::lotus_json", rename = "SecretHash")] + pub secret_pre_image: Vec, + pub extra: Option, + pub lane: u64, + pub nonce: u64, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub amount: TokenAmount, + #[schemars(with = "LotusJson")] + #[serde(with = "crate::lotus_json")] + pub min_settle_height: ChainEpoch, + // Lotus returns null (not []) when there are no merges; model as Option, so None means empty. + pub merges: Option>, + #[schemars(with = "LotusJson>")] + #[serde(with = "crate::lotus_json")] + pub signature: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct UpdateChannelStateParamsV2LotusJson { + pub sv: SignedVoucherV2LotusJson, + #[serde(with = "crate::lotus_json")] + pub secret: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct UpdateChannelStateParamsV3LotusJson { + pub sv: SignedVoucherV3LotusJson, + #[serde(with = "crate::lotus_json")] + pub secret: Vec, +} + +#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] +#[serde(rename_all = "PascalCase")] +pub struct UpdateChannelStateParamsV4LotusJson { + pub sv: SignedVoucherV4LotusJson, + #[schemars(with = "LotusJson>")] + #[serde(with = "crate::lotus_json")] + pub secret: Vec, +} + +// Implementation for ConstructorParams +macro_rules! impl_paych_constructor_params { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_paych_state::[]::ConstructorParams { + type LotusJson = ConstructorParamsLotusJson; + + #[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 { + ConstructorParamsLotusJson { + 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(), + } + } + } + } + )+ + }; +} + +// Implementation for UpdateChannelStateParams with version-specific types +macro_rules! impl_paych_update_channel_state_params_v2 { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_paych_state::[]::UpdateChannelStateParams { + type LotusJson = UpdateChannelStateParamsV2LotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![ + ( + json!({ + "Sv": { + "ChannelAddr": "f01234", + "TimeLockMin": 0, + "TimeLockMax": 0, + "SecretPreImage": "", + "Extra": null, + "Lane": 0, + "Nonce": 1, + "Amount": "1000", + "MinSettleHeight": 0, + "Merges": [], + "Signature": null + }, + "Secret": "" + }), + Self { + sv: fil_actor_paych_state::[]::SignedVoucher { + channel_addr: Address::new_id(1234).into(), + time_lock_min: 0, + time_lock_max: 0, + secret_pre_image: vec![], + extra: None, + lane: 0, + nonce: 1, + amount: TokenAmount::from_atto(1000).into(), + min_settle_height: 0, + merges: vec![], + signature: None, + }, + secret: vec![], + }, + ), + ] + } + + fn into_lotus_json(self) -> Self::LotusJson { + UpdateChannelStateParamsV2LotusJson { + sv: SignedVoucherV2LotusJson { + channel_addr: self.sv.channel_addr.into(), + time_lock_min: self.sv.time_lock_min, + time_lock_max: self.sv.time_lock_max, + secret_pre_image: self.sv.secret_pre_image, + extra: self.sv.extra.map(|e| ModVerifyParamsLotusJson { + actor: e.actor.into(), + method: e.method, + data: e.data, + }), + lane: self.sv.lane, + nonce: self.sv.nonce, + amount: self.sv.amount.into(), + min_settle_height: self.sv.min_settle_height, + merges: if self.sv.merges.is_empty() { + None + } else { + Some(self.sv.merges.into_iter().map(|m| MergeLotusJson { + lane: m.lane, + nonce: m.nonce, + }).collect()) + }, + signature: self.sv.signature, + }, + secret: self.secret, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + sv: fil_actor_paych_state::[]::SignedVoucher { + channel_addr: lotus_json.sv.channel_addr.into(), + time_lock_min: lotus_json.sv.time_lock_min, + time_lock_max: lotus_json.sv.time_lock_max, + secret_pre_image: lotus_json.sv.secret_pre_image, + extra: lotus_json.sv.extra.map(|e| fil_actor_paych_state::[]::ModVerifyParams { + actor: e.actor.into(), + method: e.method, + data: e.data, + }), + lane: lotus_json.sv.lane, + nonce: lotus_json.sv.nonce, + amount: lotus_json.sv.amount.into(), + min_settle_height: lotus_json.sv.min_settle_height, + merges: if lotus_json.sv.merges.is_none() { + vec![] + } else { + lotus_json.sv.merges.unwrap().into_iter().map(|m| fil_actor_paych_state::[]::Merge { + lane: m.lane, + nonce: m.nonce, + }).collect() + }, + signature: lotus_json.sv.signature, + }, + secret: lotus_json.secret, + } + } + } + } + )+ + }; +} + +macro_rules! impl_paych_update_channel_state_params_v3 { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_paych_state::[]::UpdateChannelStateParams { + type LotusJson = UpdateChannelStateParamsV3LotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![ + ( + json!({ + "Sv": { + "ChannelAddr": "f01234", + "TimeLockMin": 0, + "TimeLockMax": 0, + "SecretPreImage": "", + "Extra": null, + "Lane": 0, + "Nonce": 1, + "Amount": "1000", + "MinSettleHeight": 0, + "Merges": [], + "Signature": null + }, + "Secret": "" + }), + Self { + sv: fil_actor_paych_state::[]::SignedVoucher { + channel_addr: Address::new_id(1234).into(), + time_lock_min: 0, + time_lock_max: 0, + secret_pre_image: vec![], + extra: None, + lane: 0, + nonce: 1, + amount: TokenAmount::from_atto(1000).into(), + min_settle_height: 0, + merges: vec![], + signature: None, + }, + secret: vec![], + }, + ), + ] + } + + fn into_lotus_json(self) -> Self::LotusJson { + UpdateChannelStateParamsV3LotusJson { + sv: SignedVoucherV3LotusJson { + channel_addr: self.sv.channel_addr.into(), + time_lock_min: self.sv.time_lock_min, + time_lock_max: self.sv.time_lock_max, + secret_pre_image: self.sv.secret_pre_image, + extra: self.sv.extra.map(|e| ModVerifyParamsLotusJson { + actor: e.actor.into(), + method: e.method, + data: e.data, + }), + lane: self.sv.lane, + nonce: self.sv.nonce, + amount: self.sv.amount.into(), + min_settle_height: self.sv.min_settle_height, + merges: if self.sv.merges.is_empty() { + None + } else { + Some(self.sv.merges.into_iter().map(|m| MergeLotusJson { + lane: m.lane, + nonce: m.nonce, + }).collect()) + }, + signature: self.sv.signature, + }, + secret: self.secret, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + sv: fil_actor_paych_state::[]::SignedVoucher { + channel_addr: lotus_json.sv.channel_addr.into(), + time_lock_min: lotus_json.sv.time_lock_min, + time_lock_max: lotus_json.sv.time_lock_max, + secret_pre_image: lotus_json.sv.secret_pre_image, + extra: lotus_json.sv.extra.map(|e| fil_actor_paych_state::[]::ModVerifyParams { + actor: e.actor.into(), + method: e.method, + data: e.data, + }), + lane: lotus_json.sv.lane, + nonce: lotus_json.sv.nonce, + amount: lotus_json.sv.amount.into(), + min_settle_height: lotus_json.sv.min_settle_height, + merges: if lotus_json.sv.merges.is_none() { + vec![] + } else { + lotus_json.sv.merges.unwrap().into_iter().map(|m| fil_actor_paych_state::[]::Merge { + lane: m.lane, + nonce: m.nonce, + }).collect() + }, + signature: lotus_json.sv.signature, + }, + secret: lotus_json.secret, + } + } + } + } + )+ + }; +} + +macro_rules! impl_paych_update_channel_state_params_v4 { + ($($version:literal),+) => { + $( + paste! { + impl HasLotusJson for fil_actor_paych_state::[]::UpdateChannelStateParams { + type LotusJson = UpdateChannelStateParamsV4LotusJson; + + #[cfg(test)] + fn snapshots() -> Vec<(serde_json::Value, Self)> { + vec![ + ( + json!({ + "Sv": { + "ChannelAddr": "f01234", + "TimeLockMin": 0, + "TimeLockMax": 0, + "SecretPreImage": "", + "Extra": null, + "Lane": 0, + "Nonce": 1, + "Amount": "1000", + "MinSettleHeight": 0, + "Merges": [], + "Signature": null + }, + "Secret": "" + }), + Self { + sv: fil_actor_paych_state::[]::SignedVoucher { + channel_addr: Address::new_id(1234).into(), + time_lock_min: 0, + time_lock_max: 0, + secret_pre_image: vec![], + extra: None, + lane: 0, + nonce: 1, + amount: TokenAmount::from_atto(1000).into(), + min_settle_height: 0, + merges: vec![], + signature: None, + }, + secret: vec![], + }, + ), + ] + } + + fn into_lotus_json(self) -> Self::LotusJson { + UpdateChannelStateParamsV4LotusJson { + sv: SignedVoucherV4LotusJson { + channel_addr: self.sv.channel_addr.into(), + time_lock_min: self.sv.time_lock_min, + time_lock_max: self.sv.time_lock_max, + secret_pre_image: self.sv.secret_pre_image, + extra: self.sv.extra.map(|e| ModVerifyParamsLotusJson { + actor: e.actor.into(), + method: e.method, + data: e.data, + }), + lane: self.sv.lane, + nonce: self.sv.nonce, + amount: self.sv.amount.into(), + min_settle_height: self.sv.min_settle_height, + merges: if self.sv.merges.is_empty() { + None + } else { + Some(self.sv.merges.into_iter().map(|m| MergeLotusJson { + lane: m.lane, + nonce: m.nonce, + }).collect()) + }, + signature: self.sv.signature, + }, + secret: self.secret, + } + } + + fn from_lotus_json(lotus_json: Self::LotusJson) -> Self { + Self { + sv: fil_actor_paych_state::[]::SignedVoucher { + channel_addr: lotus_json.sv.channel_addr.into(), + time_lock_min: lotus_json.sv.time_lock_min, + time_lock_max: lotus_json.sv.time_lock_max, + secret_pre_image: lotus_json.sv.secret_pre_image, + extra: lotus_json.sv.extra.map(|e| fil_actor_paych_state::[]::ModVerifyParams { + actor: e.actor.into(), + method: e.method, + data: e.data, + }), + lane: lotus_json.sv.lane, + nonce: lotus_json.sv.nonce, + amount: lotus_json.sv.amount.into(), + min_settle_height: lotus_json.sv.min_settle_height, + merges: if lotus_json.sv.merges.is_none() { + vec![] + } else { + lotus_json.sv.merges.unwrap().into_iter().map(|m| fil_actor_paych_state::[]::Merge { + lane: m.lane, + nonce: m.nonce, + }).collect() + }, + signature: lotus_json.sv.signature, + }, + secret: lotus_json.secret, + } + } + } + } + )+ + }; +} + +// Apply implementations with correct fvm_shared versions +impl_paych_constructor_params!(8, 9, 10, 11, 12, 13, 14, 15, 16); +impl_paych_update_channel_state_params_v2!(8, 9); +impl_paych_update_channel_state_params_v3!(10, 11); +impl_paych_update_channel_state_params_v4!(12, 13, 14, 15, 16); diff --git a/src/rpc/registry/actors/mod.rs b/src/rpc/registry/actors/mod.rs index 4935fe4b8a51..1918d1c31b2e 100644 --- a/src/rpc/registry/actors/mod.rs +++ b/src/rpc/registry/actors/mod.rs @@ -8,6 +8,7 @@ pub(crate) mod evm; pub(crate) mod init; pub(crate) mod miner; pub(crate) mod multisig; +pub(crate) mod payment_channel; pub(crate) mod power; pub(crate) mod reward; pub(crate) mod system; diff --git a/src/rpc/registry/actors/payment_channel.rs b/src/rpc/registry/actors/payment_channel.rs new file mode 100644 index 000000000000..c29751e2dbbf --- /dev/null +++ b/src/rpc/registry/actors/payment_channel.rs @@ -0,0 +1,44 @@ +// 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_payment_channel_reg_versions { + ($registry:expr, $code_cid:expr, $state_version:path) => {{ + use $state_version::{ConstructorParams, Method, UpdateChannelStateParams}; + + // Register methods with parameters + register_actor_methods!( + $registry, + $code_cid, + [ + (Method::Constructor, ConstructorParams), + (Method::UpdateChannelState, UpdateChannelStateParams), + ] + ); + + // Register methods without parameters + register_actor_methods!( + $registry, + $code_cid, + [(Method::Settle, empty), (Method::Collect, empty),] + ); + }}; +} + +pub(crate) fn register_actor_methods(registry: &mut MethodRegistry, cid: Cid, version: u64) { + match version { + 8 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v8), + 9 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v9), + 10 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v10), + 11 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v11), + 12 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v12), + 13 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v13), + 14 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v14), + 15 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v15), + 16 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v16), + _ => {} + } +} diff --git a/src/rpc/registry/methods_reg.rs b/src/rpc/registry/methods_reg.rs index 4aa6d6c0f1d5..768ad6d49829 100644 --- a/src/rpc/registry/methods_reg.rs +++ b/src/rpc/registry/methods_reg.rs @@ -74,7 +74,8 @@ impl MethodRegistry { fn register_known_methods(&mut self) { use crate::rpc::registry::actors::{ - account, cron, datacap, evm, init, miner, multisig, power, reward, system, verified_reg, + account, cron, datacap, evm, init, miner, multisig, payment_channel, power, reward, + system, verified_reg, }; for (&cid, &(actor_type, version)) in ACTOR_REGISTRY.iter() { @@ -96,6 +97,9 @@ impl MethodRegistry { BuiltinActor::VerifiedRegistry => { verified_reg::register_actor_methods(self, cid, version) } + BuiltinActor::PaymentChannel => { + payment_channel::register_actor_methods(self, cid, version) + } _ => {} } } From 2d41366ff3439cc6ad8f32c8fef40b3d2a9e1248 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Tue, 26 Aug 2025 14:01:32 +0530 Subject: [PATCH 2/4] add snapshot tests for payment channel actor --- .../subcommands/api_cmd/api_compare_tests.rs | 60 +++++++++++++++++++ .../subcommands/api_cmd/test_snapshots.txt | 4 ++ 2 files changed, 64 insertions(+) diff --git a/src/tool/subcommands/api_cmd/api_compare_tests.rs b/src/tool/subcommands/api_cmd/api_compare_tests.rs index 1b28f2e57e0e..bbab64f46201 100644 --- a/src/tool/subcommands/api_cmd/api_compare_tests.rs +++ b/src/tool/subcommands/api_cmd/api_compare_tests.rs @@ -1876,10 +1876,70 @@ fn state_decode_params_api_tests(tipset: &Tipset) -> anyhow::Result tests.extend(datacap_actor_state_decode_params_tests(tipset)?); tests.extend(multisig_actor_state_decode_params_tests(tipset)?); tests.extend(verified_reg_actor_state_decode_params_tests(tipset)?); + tests.extend(paych_actor_state_decode_params_tests(tipset)?); Ok(tests) } +fn paych_actor_state_decode_params_tests(tipset: &Tipset) -> anyhow::Result> { + // payment channel actor address `t066116` + // https://calibration.filscan.io/en/address/t066116/ + let paych_address = Address::new_id(66116); + + let constructor_params = fil_actor_paych_state::v16::ConstructorParams { + from: Address::new_id(1234).into(), + to: Address::new_id(8457).into(), + }; + + let update_channel_state = fil_actor_paych_state::v16::UpdateChannelStateParams { + sv: fil_actor_paych_state::v16::SignedVoucher { + channel_addr: Address::new_id(1000).into(), + time_lock_min: 21, + time_lock_max: 234, + secret_pre_image: vec![], + extra: Some(fil_actor_paych_state::v16::ModVerifyParams { + actor: Address::new_id(1234).into(), + method: 223, + data: Default::default(), + }), + lane: 234, + nonce: 231, + amount: Default::default(), + min_settle_height: 0, + merges: vec![], + signature: None, + }, + secret: vec![0x11, 0x22, 0x33, 0x44, 0x55], // dummy data + }; + + Ok(vec![ + RpcTest::identity(StateDecodeParams::request(( + paych_address, + fil_actor_paych_state::v16::Method::Constructor as u64, + to_vec(&constructor_params).unwrap(), + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + paych_address, + fil_actor_paych_state::v16::Method::UpdateChannelState as u64, + to_vec(&update_channel_state).unwrap(), + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + paych_address, + fil_actor_paych_state::v16::Method::Settle as u64, + vec![], + tipset.key().into(), + ))?), + RpcTest::identity(StateDecodeParams::request(( + paych_address, + fil_actor_paych_state::v16::Method::Collect as u64, + vec![], + tipset.key().into(), + ))?), + ]) +} + 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]), diff --git a/src/tool/subcommands/api_cmd/test_snapshots.txt b/src/tool/subcommands/api_cmd/test_snapshots.txt index e3eec68b33f0..4a0fc3986e30 100644 --- a/src/tool/subcommands/api_cmd/test_snapshots.txt +++ b/src/tool/subcommands/api_cmd/test_snapshots.txt @@ -201,6 +201,10 @@ filecoin_verified_reg_statedecodeparams_1754401651147022.rpcsnap.json.zst filecoin_verified_reg_statedecodeparams_1754401651147091.rpcsnap.json.zst filecoin_verified_reg_statedecodeparams_1754401651147157.rpcsnap.json.zst filecoin_verified_reg_statedecodeparams_1754401651147231.rpcsnap.json.zst +filecoin_payment_channel_statedecodeparams_1756194613312797.rpcsnap.json.zst +filecoin_payment_channel_statedecodeparams_1756194613312868.rpcsnap.json.zst +filecoin_payment_channel_statedecodeparams_1756194613312941.rpcsnap.json.zst +filecoin_payment_channel_statedecodeparams_1756194613313007.rpcsnap.json.zst filecoin_statereplay_1743504051038215.rpcsnap.json.zst filecoin_statesearchmsg_1741784596636715.rpcsnap.json.zst filecoin_statesearchmsglimited_1741784596704876.rpcsnap.json.zst From a67816335d1f703c9e646e49da9f88270cd17911 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Tue, 2 Sep 2025 19:56:59 +0530 Subject: [PATCH 3/4] fix formatting issue --- CHANGELOG.md | 1 - src/rpc/registry/methods_reg.rs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97fff86f534e..1719f009c10c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,6 @@ - [#6014](https://github.com/ChainSafe/forest/pull/6014) Removed `unordered-graph-traversal` from `forest-tool benchmark`. - ### Fixed ## Forest v0.29.0 "Fëanor" diff --git a/src/rpc/registry/methods_reg.rs b/src/rpc/registry/methods_reg.rs index 7747986e028e..f75f982e323b 100644 --- a/src/rpc/registry/methods_reg.rs +++ b/src/rpc/registry/methods_reg.rs @@ -74,8 +74,8 @@ impl MethodRegistry { fn register_known_methods(&mut self) { use crate::rpc::registry::actors::{ - account, cron, datacap, eth_account, evm, init, miner, multisig,payment_channel, power, reward, system, - verified_reg, + account, cron, datacap, eth_account, evm, init, miner, multisig, payment_channel, + power, reward, system, verified_reg, }; for (&cid, &(actor_type, version)) in ACTOR_REGISTRY.iter() { From 65535882d3a246a2367dab47523d200823affafb Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Tue, 2 Sep 2025 20:42:38 +0530 Subject: [PATCH 4/4] address comment Co-authored-by: hanabi1224 --- src/rpc/registry/actors/payment_channel.rs | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/rpc/registry/actors/payment_channel.rs b/src/rpc/registry/actors/payment_channel.rs index c29751e2dbbf..7176c4484d60 100644 --- a/src/rpc/registry/actors/payment_channel.rs +++ b/src/rpc/registry/actors/payment_channel.rs @@ -6,8 +6,10 @@ use crate::shim::message::MethodNum; use cid::Cid; macro_rules! register_payment_channel_reg_versions { - ($registry:expr, $code_cid:expr, $state_version:path) => {{ - use $state_version::{ConstructorParams, Method, UpdateChannelStateParams}; + ($registry:expr, $code_cid:expr, $version:literal) => {{ + paste::paste!{ + use fil_actor_paych_state::[]::{ConstructorParams, Method, UpdateChannelStateParams}; + } // Register methods with parameters register_actor_methods!( @@ -29,16 +31,15 @@ macro_rules! register_payment_channel_reg_versions { } pub(crate) fn register_actor_methods(registry: &mut MethodRegistry, cid: Cid, version: u64) { - match version { - 8 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v8), - 9 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v9), - 10 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v10), - 11 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v11), - 12 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v12), - 13 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v13), - 14 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v14), - 15 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v15), - 16 => register_payment_channel_reg_versions!(registry, cid, fil_actor_paych_state::v16), - _ => {} + macro_rules! register_versions { + ($($version:literal),+) => {{ + match version { + $( + $version => register_payment_channel_reg_versions!(registry, cid, $version), + )+ + _ => {} + } + }}; } + register_versions!(8, 9, 10, 11, 12, 13, 14, 15, 16) }