diff --git a/Cargo.lock b/Cargo.lock
index 3458cf4d4e95..1bab72dc3b01 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2610,9 +2610,9 @@ dependencies = [
[[package]]
name = "fil_actor_account_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee54bfbd6f576dc263026db73b6e77f6fc23654556c68e5d2b69768171a3fdab"
+checksum = "14c6392faf8bc6ce3f36a136c52e0357c4fd1e64a4f0eb9834abd8c63b9b19cf"
dependencies = [
"frc42_dispatch",
"frc42_macros",
@@ -2627,9 +2627,9 @@ dependencies = [
[[package]]
name = "fil_actor_cron_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b74b3dc3e53aa0636fac281b1cb98af53f16769045119ff47cd1892df60390ee"
+checksum = "0fe305e8b1612eec1ba1b3c7dba62bc312d898606a5b9525a464d9c47139e70a"
dependencies = [
"fvm_ipld_encoding",
"fvm_shared 2.11.2",
@@ -2642,9 +2642,9 @@ dependencies = [
[[package]]
name = "fil_actor_datacap_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf7c439d60a7b9979199bb50479b3e42021b2ccf6979bee9a8617e61a67c568f"
+checksum = "a122d4735ab7d52ec38ca91bda8d56c0d1fea0a13ef9be70e2b5b0dd7d9f0a0b"
dependencies = [
"fil_actors_shared",
"frc42_dispatch",
@@ -2663,9 +2663,9 @@ dependencies = [
[[package]]
name = "fil_actor_eam_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a82e385dbace66a6ea56a67fb9782d555988ac59bab005d645dfc8f4db13b70"
+checksum = "7ef468e409399faf23e6da95e27d5f7a27cac22ba7f6e5f41bf3d485309b936d"
dependencies = [
"fil_actor_evm_state",
"fvm_ipld_encoding",
@@ -2678,9 +2678,9 @@ dependencies = [
[[package]]
name = "fil_actor_ethaccount_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1adb598222ed2992854e1e5feca6c42c75403f7ca6683b14d09387c7ff08c7a"
+checksum = "8322c4de54e80ca761d82bf259dc3b1b2104de44008dcf2493078df1dd6f044d"
dependencies = [
"fvm_ipld_encoding",
"fvm_shared 3.13.2",
@@ -2692,9 +2692,9 @@ dependencies = [
[[package]]
name = "fil_actor_evm_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5cd2fd5ff6c1491267c046b9088ae5877e9a05957bd8665d88dbc44e48c5d47"
+checksum = "90610613408cd84da78aeade27ea0f44158b03f5dd6d0d56bd47831543638e63"
dependencies = [
"cid",
"fil_actors_shared",
@@ -2713,9 +2713,9 @@ dependencies = [
[[package]]
name = "fil_actor_init_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2715e2049987c00fdec6ed087deb3332afb766c0b988ad25fe62f0b8e1ce2a7"
+checksum = "8db5cb637d20451009ebe905d592c235d8ce6fb8626f72f04e3851b4b7744496"
dependencies = [
"anyhow",
"cid",
@@ -2733,9 +2733,9 @@ dependencies = [
[[package]]
name = "fil_actor_market_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f945a03e386885d87b1c231b3021a860dab9480da89d096f825562d7d3fc16a"
+checksum = "bdb17e1b96534b072d76aa3f4717c2c618b3caf435dcb63f396335259b6eb2e0"
dependencies = [
"anyhow",
"cid",
@@ -2761,9 +2761,9 @@ dependencies = [
[[package]]
name = "fil_actor_miner_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1382e2944310ac60bb0e7794299166228ac307005e6e3ee64393477cdb398444"
+checksum = "302b9ba04c75efde657c5e06e1033e1585288119da437f29d7e22c5328a6b996"
dependencies = [
"anyhow",
"bitflags 2.9.4",
@@ -2792,9 +2792,9 @@ dependencies = [
[[package]]
name = "fil_actor_multisig_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "308cea7b8cdde90b8f683e4fee3b4b5067295cca63bd66d52a8ad4957e7267e2"
+checksum = "84ced2ed760180cb09a03ae0438ed9fb82b495bba97c2da8d7ac5ef61c49b7bb"
dependencies = [
"anyhow",
"cid",
@@ -2816,9 +2816,9 @@ dependencies = [
[[package]]
name = "fil_actor_paych_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf3ea5272da3f671db18ace120712eac7bf88e1d4e3183ddb6c1fc3da75cf573"
+checksum = "bf6352ea0452bc6dc533528e5c4ff1267f9a94baaf1b11e19145c103a6773780"
dependencies = [
"cid",
"fil_actors_shared",
@@ -2835,9 +2835,9 @@ dependencies = [
[[package]]
name = "fil_actor_power_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73ea4fb569085e1bbe5c20de364c2e4b6478084d842d62b0937ac08d4c5cf2ee"
+checksum = "d97b98196fc3da0e31c00686c79f922eb8805a06a903f576dc9fb6b684ee6845"
dependencies = [
"anyhow",
"cid",
@@ -2859,9 +2859,9 @@ dependencies = [
[[package]]
name = "fil_actor_reward_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6a1142fc9b74f5f107361c1dd6142b2500c5872138f8aa66a523e1af783cb67"
+checksum = "33020cb0a086cff43d94c63034e98b960ff331dc5adc31fc931b695e181f5919"
dependencies = [
"fil_actors_shared",
"fvm_ipld_encoding",
@@ -2876,9 +2876,9 @@ dependencies = [
[[package]]
name = "fil_actor_system_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c7798a173573473e45a6ca8ac2b309222638b8ddea2e2c4c6ee93b9dc577daf"
+checksum = "d26709383303cd27da59f1bd5361249a8043f736721e46b3d5ae674d4f0ff93c"
dependencies = [
"cid",
"fil_actors_shared",
@@ -2894,9 +2894,9 @@ dependencies = [
[[package]]
name = "fil_actor_verifreg_state"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "554578f23efb1e9753bffa9c84803e5b3175847ad7cb3d604fa02a30c6e7dfd9"
+checksum = "92f8794eab7e2da54225f26ec65bdb2d7565b731c39d661771a516871594354b"
dependencies = [
"anyhow",
"cid",
@@ -2916,9 +2916,9 @@ dependencies = [
[[package]]
name = "fil_actors_shared"
-version = "24.1.1"
+version = "24.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32f767a616bd469a24c3d9599b4fbd77a293abe213cf9c3cbac3c8c0e59f7678"
+checksum = "0017d2215c114878850e25cfffea5d475abbba72e972fa77c15ed46d6a6be6f8"
dependencies = [
"anyhow",
"cid",
@@ -2947,6 +2947,7 @@ dependencies = [
"strum",
"thiserror 2.0.16",
"unsigned-varint 0.8.0",
+ "walkdir",
]
[[package]]
diff --git a/src/lotus_json/actor_states/methods/market_actor_params.rs b/src/lotus_json/actor_states/methods/market_actor_params.rs
new file mode 100644
index 000000000000..b6311ae9e6db
--- /dev/null
+++ b/src/lotus_json/actor_states/methods/market_actor_params.rs
@@ -0,0 +1,1592 @@
+// 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::deal::DealID;
+use crate::shim::econ::TokenAmount;
+use crate::shim::piece::PaddedPieceSize;
+use crate::shim::sector::RegisteredSealProof;
+use crate::test_snapshots;
+use fil_actors_shared::fvm_ipld_bitfield::BitField;
+
+use ::cid::Cid;
+use paste::paste;
+use schemars::JsonSchema;
+use serde::{Deserialize, Serialize};
+use std::fmt::Debug;
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct WithdrawBalanceParamsLotusJson {
+ #[schemars(with = "LotusJson
")]
+ #[serde(with = "crate::lotus_json", rename = "ProviderOrClientAddress")]
+ pub provider_or_client: Address,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub amount: TokenAmount,
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct AddBalanceParamsLotusJson(
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ Address,
+);
+
+macro_rules! impl_lotus_json_for_add_balance_params {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::AddBalanceParams {
+ type LotusJson = AddBalanceParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!("f0100"),
+ Self { provider_or_client: Address::new_id(100).into() }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ AddBalanceParamsLotusJson(self.provider_or_client.into())
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ provider_or_client: json.0.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+macro_rules! impl_lotus_json_for_withdraw_balance_params {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::WithdrawBalanceParams {
+ type LotusJson = WithdrawBalanceParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![(
+ json!({
+ "ProviderOrClientAddress": "f01234",
+ "Amount": "1000000000000000000",
+ }),
+ Self{
+ provider_or_client: Address::new_id(1234).into(),
+ amount: TokenAmount::from_atto(1000000000000000000u64).into(),
+ },
+ )]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ provider_or_client: self.provider_or_client.into(),
+ amount: self.amount.into(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ provider_or_client: json.provider_or_client.into(),
+ amount: json.amount.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
+#[serde(untagged)]
+pub enum LabelLotusJson {
+ String(String),
+ Bytes(Vec),
+}
+
+macro_rules! impl_lotus_json_for_label {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::Label {
+ type LotusJson = LabelLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (serde_json::json!("label-string"), Self::String("label-string".to_owned())),
+ (serde_json::json!([1,2,3]), Self::Bytes(vec![1,2,3])),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ match self {
+ Self::Bytes(bytes) => LabelLotusJson::Bytes(bytes),
+ Self::String(string) => LabelLotusJson::String(string),
+ }
+ }
+
+ fn from_lotus_json(lotus_json: Self::LotusJson) -> Self {
+ match lotus_json {
+ LabelLotusJson::Bytes(bytes) => Self::Bytes(bytes),
+ LabelLotusJson::String(string) => Self::String(string),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct DealProposalLotusJson {
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ #[serde(rename = "PieceCID")]
+ pub piece_cid: Cid,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub piece_size: PaddedPieceSize,
+ pub verified_deal: bool,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub client: Address,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub provider: Address,
+ pub label: LabelLotusJson,
+ pub start_epoch: ChainEpoch,
+ pub end_epoch: ChainEpoch,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub storage_price_per_epoch: TokenAmount,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub provider_collateral: TokenAmount,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub client_collateral: TokenAmount,
+}
+
+macro_rules! impl_lotus_json_for_deal_proposal {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::DealProposal {
+ type LotusJson = DealProposalLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ // Create minimal test data using Default where possible
+
+ // Note: We need to create version-specific test data due to different fvm_shared versions
+ // For now, we'll use a minimal example that should work across versions
+ let test_cid = ::cid::Cid::try_from("baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq").unwrap();
+
+ vec![(
+ serde_json::json!({
+ "PieceCID": { "/": test_cid.to_string() },
+ "PieceSize": 1024,
+ "VerifiedDeal": false,
+ "Client": "f01234",
+ "Provider": "f05678",
+ "Label": "test",
+ "StartEpoch": 100,
+ "EndEpoch": 200,
+ "StoragePricePerEpoch": "1000",
+ "ProviderCollateral": "2000",
+ "ClientCollateral": "3000"
+ }),
+ // Create the corresponding object using from_lotus_json to ensure compatibility
+ Self::from_lotus_json(crate::lotus_json::actor_states::methods::market_actor_params::DealProposalLotusJson {
+ piece_cid: test_cid,
+ piece_size: 1024u64.into(),
+ verified_deal: false,
+ client: crate::shim::address::Address::new_id(1234).into(),
+ provider: crate::shim::address::Address::new_id(5678).into(),
+ label: crate::lotus_json::actor_states::methods::market_actor_params::LabelLotusJson::String("test".to_string()),
+ start_epoch: 100,
+ end_epoch: 200,
+ storage_price_per_epoch: crate::shim::econ::TokenAmount::from_atto(1000u64).into(),
+ provider_collateral: crate::shim::econ::TokenAmount::from_atto(2000u64).into(),
+ client_collateral: crate::shim::econ::TokenAmount::from_atto(3000u64).into(),
+ })
+ )]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ let Self {
+ piece_cid,
+ piece_size,
+ verified_deal,
+ client,
+ provider,
+ label,
+ start_epoch,
+ end_epoch,
+ storage_price_per_epoch,
+ provider_collateral,
+ client_collateral,
+ } = self;
+ Self::LotusJson {
+ piece_cid: piece_cid.into(),
+ piece_size: piece_size.into(),
+ verified_deal: verified_deal.into(),
+ client: client.into(),
+ provider: provider.into(),
+ label: label.into_lotus_json(),
+ start_epoch: start_epoch.into(),
+ end_epoch: end_epoch.into(),
+ storage_price_per_epoch: storage_price_per_epoch.into(),
+ provider_collateral: provider_collateral.into(),
+ client_collateral: client_collateral.into(),
+ }
+ }
+
+ fn from_lotus_json(lotus_json: Self::LotusJson) -> Self {
+ let Self::LotusJson {
+ piece_cid,
+ piece_size,
+ verified_deal,
+ client,
+ provider,
+ label,
+ start_epoch,
+ end_epoch,
+ storage_price_per_epoch,
+ provider_collateral,
+ client_collateral,
+ } = lotus_json;
+ Self {
+ piece_cid,
+ piece_size: piece_size.into(),
+ verified_deal,
+ client: client.into(),
+ provider: provider.into(),
+ label: fil_actor_market_state::[]::Label::from_lotus_json(label), // delegate
+ start_epoch,
+ end_epoch,
+ storage_price_per_epoch: storage_price_per_epoch.into(),
+ provider_collateral: provider_collateral.into(),
+ client_collateral: client_collateral.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct ClientDealProposalV2LotusJson {
+ pub proposal: DealProposalLotusJson,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub client_signature: fvm_shared2::crypto::signature::Signature,
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct ClientDealProposalV3LotusJson {
+ pub proposal: DealProposalLotusJson,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub client_signature: fvm_shared3::crypto::signature::Signature,
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct ClientDealProposalV4LotusJson {
+ pub proposal: DealProposalLotusJson,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub client_signature: fvm_shared4::crypto::signature::Signature,
+}
+
+macro_rules! impl_lotus_json_for_client_deal_proposal {
+ ($type_suffix:path: $lotus_json_type:ty: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::ClientDealProposal {
+ type LotusJson = $lotus_json_type;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ // Use the same test data as DealProposal, but add a client signature
+ let test_cid = ::cid::Cid::try_from("baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq").unwrap();
+
+ vec![(
+ serde_json::json!({
+ "Proposal": {
+ "PieceCID": { "/": test_cid.to_string() },
+ "PieceSize": 1024,
+ "VerifiedDeal": false,
+ "Client": "f01234",
+ "Provider": "f05678",
+ "Label": "test",
+ "StartEpoch": 100,
+ "EndEpoch": 200,
+ "StoragePricePerEpoch": "1000",
+ "ProviderCollateral": "2000",
+ "ClientCollateral": "3000"
+ },
+ "ClientSignature": {
+ "Type": 1,
+ "Data": "dGVzdA==" // base64 for "test"
+ }
+ }),
+ // Create object using from_lotus_json to ensure compatibility
+ Self::from_lotus_json($lotus_json_type {
+ proposal: crate::lotus_json::actor_states::methods::market_actor_params::DealProposalLotusJson {
+ piece_cid: test_cid,
+ piece_size: 1024u64.into(),
+ verified_deal: false,
+ client: crate::shim::address::Address::new_id(1234).into(),
+ provider: crate::shim::address::Address::new_id(5678).into(),
+ label: crate::lotus_json::actor_states::methods::market_actor_params::LabelLotusJson::String("test".to_string()),
+ start_epoch: 100,
+ end_epoch: 200,
+ storage_price_per_epoch: crate::shim::econ::TokenAmount::from_atto(1000u64).into(),
+ provider_collateral: crate::shim::econ::TokenAmount::from_atto(2000u64).into(),
+ client_collateral: crate::shim::econ::TokenAmount::from_atto(3000u64).into(),
+ },
+ client_signature: $type_suffix::Signature {
+ sig_type: $type_suffix::SignatureType::Secp256k1,
+ bytes: b"test".to_vec(),
+ },
+ })
+ )]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ proposal: self.proposal.into_lotus_json(),
+ client_signature: self.client_signature.into(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ proposal: fil_actor_market_state::[]::DealProposal::from_lotus_json(json.proposal),
+ client_signature: json.client_signature.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct PublishStorageDealsParamsV2LotusJson {
+ pub deals: Vec,
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct PublishStorageDealsParamsV3LotusJson {
+ pub deals: Vec,
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct PublishStorageDealsParamsV4LotusJson {
+ pub deals: Vec,
+}
+
+macro_rules! impl_publish_storage_deals_params_snapshots_v2 {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::PublishStorageDealsParams {
+ type LotusJson = PublishStorageDealsParamsV2LotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ json!({
+ "Deals": [
+ {
+ "Proposal": {
+ "PieceCID": {
+ "/": "baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq"
+ },
+ "PieceSize": 1024,
+ "VerifiedDeal": false,
+ "Client": "f17uoq6tp427uzv7fztkbsnn64iwotfrristwpryy",
+ "Provider": "f01000",
+ "Label": "test-deal",
+ "StartEpoch": 100,
+ "EndEpoch": 200,
+ "StoragePricePerEpoch": "1000",
+ "ProviderCollateral": "2000",
+ "ClientCollateral": "1500"
+ },
+ "ClientSignature": {
+ "Type": 1,
+ "Data": "VGVzdCBzaWduYXR1cmU="
+ }
+ }
+ ]
+ }),
+ fil_actor_market_state::[]::PublishStorageDealsParams::from_lotus_json(PublishStorageDealsParamsV2LotusJson {
+ deals: vec![
+ ClientDealProposalV2LotusJson {
+ proposal: DealProposalLotusJson {
+ piece_cid: "baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq".parse().unwrap(),
+ piece_size: 1024u64.into(),
+ verified_deal: false,
+ client: "f17uoq6tp427uzv7fztkbsnn64iwotfrristwpryy".parse().unwrap(),
+ provider: "f01000".parse().unwrap(),
+ label: LabelLotusJson::String("test-deal".to_string()),
+ start_epoch: ChainEpoch::from(100),
+ end_epoch: ChainEpoch::from(200),
+ storage_price_per_epoch: TokenAmount::from_atto(1000u64),
+ provider_collateral: TokenAmount::from_atto(2000u64),
+ client_collateral: TokenAmount::from_atto(1500u64),
+ },
+ client_signature: fvm_shared2::crypto::signature::Signature {
+ sig_type: fvm_shared2::crypto::signature::SignatureType::Secp256k1,
+ bytes: b"Test signature".to_vec(),
+ },
+ }
+ ]
+ })
+ )
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ deals: self.deals.into_iter().map(|d| d.into_lotus_json()).collect(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ deals: json.deals.into_iter()
+ .map(|d| fil_actor_market_state::[]::ClientDealProposal::from_lotus_json(d)) // delegate
+ .collect(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+macro_rules! impl_publish_storage_deals_params_snapshots_v3 {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::PublishStorageDealsParams {
+ type LotusJson = PublishStorageDealsParamsV3LotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ json!({
+ "Deals": [
+ {
+ "Proposal": {
+ "PieceCID": {
+ "/": "baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq"
+ },
+ "PieceSize": 1024,
+ "VerifiedDeal": false,
+ "Client": "f17uoq6tp427uzv7fztkbsnn64iwotfrristwpryy",
+ "Provider": "f01000",
+ "Label": "test-deal",
+ "StartEpoch": 100,
+ "EndEpoch": 200,
+ "StoragePricePerEpoch": "1000",
+ "ProviderCollateral": "2000",
+ "ClientCollateral": "1500"
+ },
+ "ClientSignature": {
+ "Type": 1,
+ "Data": "VGVzdCBzaWduYXR1cmU="
+ }
+ }
+ ]
+ }),
+ fil_actor_market_state::[]::PublishStorageDealsParams::from_lotus_json(PublishStorageDealsParamsV3LotusJson {
+ deals: vec![
+ ClientDealProposalV3LotusJson {
+ proposal: DealProposalLotusJson {
+ piece_cid: "baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq".parse().unwrap(),
+ piece_size: 1024u64.into(),
+ verified_deal: false,
+ client: "f17uoq6tp427uzv7fztkbsnn64iwotfrristwpryy".parse().unwrap(),
+ provider: "f01000".parse().unwrap(),
+ label: LabelLotusJson::String("test-deal".to_string()),
+ start_epoch: ChainEpoch::from(100),
+ end_epoch: ChainEpoch::from(200),
+ storage_price_per_epoch: TokenAmount::from_atto(1000u64),
+ provider_collateral: TokenAmount::from_atto(2000u64),
+ client_collateral: TokenAmount::from_atto(1500u64),
+ },
+ client_signature: fvm_shared3::crypto::signature::Signature {
+ sig_type: fvm_shared3::crypto::signature::SignatureType::Secp256k1,
+ bytes: b"Test signature".to_vec(),
+ },
+ }
+ ]
+ })
+ )
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ deals: self.deals.into_iter().map(|d| d.into_lotus_json()).collect(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ deals: json.deals.into_iter()
+ .map(|d| fil_actor_market_state::[]::ClientDealProposal::from_lotus_json(d)) // delegate
+ .collect(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+macro_rules! impl_publish_storage_deals_params_snapshots_v4 {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::PublishStorageDealsParams {
+ type LotusJson = PublishStorageDealsParamsV4LotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ json!({
+ "Deals": [
+ {
+ "Proposal": {
+ "PieceCID": {
+ "/": "baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq"
+ },
+ "PieceSize": 1024,
+ "VerifiedDeal": false,
+ "Client": "f17uoq6tp427uzv7fztkbsnn64iwotfrristwpryy",
+ "Provider": "f01000",
+ "Label": "test-deal",
+ "StartEpoch": 100,
+ "EndEpoch": 200,
+ "StoragePricePerEpoch": "1000",
+ "ProviderCollateral": "2000",
+ "ClientCollateral": "1500"
+ },
+ "ClientSignature": {
+ "Type": 1,
+ "Data": "VGVzdCBzaWduYXR1cmU="
+ }
+ }
+ ]
+ }),
+ fil_actor_market_state::[]::PublishStorageDealsParams::from_lotus_json(PublishStorageDealsParamsV4LotusJson {
+ deals: vec![
+ ClientDealProposalV4LotusJson {
+ proposal: DealProposalLotusJson {
+ piece_cid: "baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq".parse().unwrap(),
+ piece_size: 1024u64.into(),
+ verified_deal: false,
+ client: "f17uoq6tp427uzv7fztkbsnn64iwotfrristwpryy".parse().unwrap(),
+ provider: "f01000".parse().unwrap(),
+ label: LabelLotusJson::String("test-deal".to_string()),
+ start_epoch: ChainEpoch::from(100),
+ end_epoch: ChainEpoch::from(200),
+ storage_price_per_epoch: TokenAmount::from_atto(1000u64),
+ provider_collateral: TokenAmount::from_atto(2000u64),
+ client_collateral: TokenAmount::from_atto(1500u64),
+ },
+ client_signature: fvm_shared4::crypto::signature::Signature {
+ sig_type: fvm_shared4::crypto::signature::SignatureType::Secp256k1,
+ bytes: b"Test signature".to_vec(),
+ },
+ }
+ ]
+ })
+ )
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ deals: self.deals.into_iter().map(|d| d.into_lotus_json()).collect(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ deals: json.deals.into_iter()
+ .map(|d| fil_actor_market_state::[]::ClientDealProposal::from_lotus_json(d)) // delegate
+ .collect(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct SectorDealsLotusJson {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ #[serde(default)]
+ pub sector_number: Option,
+ #[schemars(with = "LotusJson")]
+ #[serde(skip_serializing_if = "Option::is_none")]
+ #[serde(with = "crate::lotus_json")]
+ #[serde(default)]
+ pub sector_type: Option,
+ pub sector_expiry: ChainEpoch,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json", rename = "DealIDs")]
+ pub deal_ids: Vec,
+}
+
+macro_rules! impl_lotus_json_for_sector_deals {
+ // Handling version where both `sector_number` and `sector_type` should be None (v8)
+ ($type_suffix:path: no_sector_type: no_sector_number: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::SectorDeals {
+ type LotusJson = SectorDealsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "SectorExpiry": 1000,
+ "DealIDs": [1,2,3]
+ }),
+ Self {
+ sector_expiry: 1000,
+ deal_ids: vec![1,2,3],
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ sector_number: None,
+ sector_type: None,
+ sector_expiry: self.sector_expiry.into_lotus_json(),
+ deal_ids: self.deal_ids.into(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ sector_expiry: json.sector_expiry.into(),
+ deal_ids: json.deal_ids.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+ // Handling versions where `sector_number` should be None (v9, v10, v11, v12)
+ ($type_suffix:path: no_sector_number: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::SectorDeals {
+ type LotusJson = SectorDealsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "SectorType": 1,
+ "SectorExpiry": 1000,
+ "DealIDs": [1,2,3]
+ }),
+ Self {
+ sector_type: RegisteredSealProof::from(1).into(),
+ sector_expiry: 1000,
+ deal_ids: vec![1,2,3],
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ sector_number: None,
+ sector_type: Some(self.sector_type.into()),
+ sector_expiry: self.sector_expiry.into_lotus_json(),
+ deal_ids: self.deal_ids.into(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ sector_expiry: json.sector_expiry.into(),
+ sector_type: json.sector_type.unwrap_or(RegisteredSealProof::invalid()).into(),
+ deal_ids: json.deal_ids.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+ ($type_suffix:path: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::SectorDeals {
+ type LotusJson = SectorDealsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "SectorNumber": 42,
+ "SectorType": 1,
+ "SectorExpiry": 1000,
+ "DealIDs": [1,2,3]
+ }),
+ Self {
+ sector_number: 42,
+ sector_type: RegisteredSealProof::from(1).into(),
+ sector_expiry: 1000,
+ deal_ids: vec![1,2,3],
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ sector_number: Some(self.sector_number),
+ sector_type: Some(self.sector_type.into()),
+ sector_expiry: self.sector_expiry.into_lotus_json(),
+ deal_ids: self.deal_ids.into(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ sector_number: json.sector_number.unwrap_or(0),
+ sector_type: json.sector_type.unwrap_or(RegisteredSealProof::invalid()).into(),
+ sector_expiry: json.sector_expiry.into(),
+ deal_ids: json.deal_ids.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct VerifyDealsForActivationParamsLotusJson {
+ pub sectors: Vec,
+}
+
+macro_rules! impl_lotus_json_for_verify_deals_for_activation_params {
+ // Version 8: SectorDeals has only sector_expiry and deal_ids
+ (v8) => {
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::v8::VerifyDealsForActivationParams {
+ type LotusJson = VerifyDealsForActivationParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "Sectors": [
+ {
+ "SectorExpiry": 1000,
+ "DealIDs": [1,2,3]
+ }
+ ]
+ }),
+ Self {
+ sectors: vec![
+ fil_actor_market_state::v8::SectorDeals {
+ sector_expiry: 1000,
+ deal_ids: vec![1,2,3],
+ }
+ ],
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ sectors: self.sectors.into_iter().map(|s| s.into_lotus_json()).collect(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ sectors: json
+ .sectors
+ .into_iter()
+ .map(|s| fil_actor_market_state::v8::SectorDeals::from_lotus_json(s))
+ .collect(),
+ }
+ }
+ }
+ }
+ };
+ // Versions 9-12: SectorDeals has sector_type (which gets default value invalid() = 0)
+ (v9_to_v12: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::VerifyDealsForActivationParams {
+ type LotusJson = VerifyDealsForActivationParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "Sectors": [
+ {
+ "SectorExpiry": 1000,
+ "DealIDs": [1,2,3],
+ "SectorType": 0
+ }
+ ]
+ }),
+ Self {
+ sectors: vec![
+ fil_actor_market_state::[]::SectorDeals {
+ sector_expiry: 1000,
+ deal_ids: vec![1,2,3],
+ sector_type: RegisteredSealProof::invalid().into(),
+ }
+ ],
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ sectors: self.sectors.into_iter().map(|s| s.into_lotus_json()).collect(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ sectors: json
+ .sectors
+ .into_iter()
+ .map(|s| fil_actor_market_state::[]::SectorDeals::from_lotus_json(s))
+ .collect(),
+ }
+ }
+ }
+ }
+ )+
+ };
+ // Versions 13+: SectorDeals has both sector_type and sector_number (both get default values)
+ (v13_plus: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::VerifyDealsForActivationParams {
+ type LotusJson = VerifyDealsForActivationParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "Sectors": [
+ {
+ "SectorExpiry": 1000,
+ "DealIDs": [1,2,3],
+ "SectorType": 0,
+ "SectorNumber": 0
+ }
+ ]
+ }),
+ Self {
+ sectors: vec![
+ fil_actor_market_state::[]::SectorDeals {
+ sector_expiry: 1000,
+ deal_ids: vec![1,2,3],
+ sector_type: RegisteredSealProof::invalid().into(),
+ sector_number: 0u64.into(),
+ }
+ ],
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ sectors: self.sectors.into_iter().map(|s| s.into_lotus_json()).collect(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ sectors: json
+ .sectors
+ .into_iter()
+ .map(|s| fil_actor_market_state::[]::SectorDeals::from_lotus_json(s))
+ .collect(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct ActivateDealsParamsLotusJson {
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json", rename = "DealIDs")]
+ pub deal_ids: Vec,
+ pub sector_expiry: ChainEpoch,
+}
+
+macro_rules! impl_lotus_json_for_activate_deals_params {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::ActivateDealsParams {
+ type LotusJson = ActivateDealsParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "DealIDs": [1,2,3],
+ "SectorExpiry": 1000
+ }),
+ Self {
+ deal_ids: vec![1,2,3],
+ sector_expiry: 1000,
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ deal_ids: self.deal_ids.into(),
+ sector_expiry: self.sector_expiry.into_lotus_json(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ deal_ids: json.deal_ids.into(),
+ sector_expiry: json.sector_expiry.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct BatchActivateDealsParamsLotusJson {
+ pub sectors: Vec,
+ pub compute_cid: bool,
+}
+
+macro_rules! impl_lotus_json_for_batch_activate_deals_params {
+ // Version 12: SectorDeals has sector_type but no sector_number
+ (v12: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::BatchActivateDealsParams {
+ type LotusJson = BatchActivateDealsParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "Sectors": [
+ {
+ "SectorType": 1,
+ "SectorExpiry": 1000,
+ "DealIDs": [1,2,3]
+ }
+ ],
+ "ComputeCid": true
+ }),
+ Self {
+ sectors: vec![
+ fil_actor_market_state::[]::SectorDeals::from_lotus_json(
+ SectorDealsLotusJson {
+ sector_number: None, // No sector_number in v12
+ sector_type: Some(RegisteredSealProof::from(1).into()),
+ sector_expiry: 1000,
+ deal_ids: vec![1,2,3],
+ }
+ )
+ ],
+ compute_cid: true,
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ sectors: self.sectors.into_iter().map(|s| s.into_lotus_json()).collect(),
+ compute_cid: self.compute_cid,
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ sectors: json
+ .sectors
+ .into_iter()
+ .map(|s| fil_actor_market_state::[]::SectorDeals::from_lotus_json(s))
+ .collect(),
+ compute_cid: json.compute_cid,
+ }
+ }
+ }
+ }
+ )+
+ };
+ // Versions 13-16: SectorDeals has both sector_type and sector_number
+ (v13_onwards: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::BatchActivateDealsParams {
+ type LotusJson = BatchActivateDealsParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "Sectors": [
+ {
+ "SectorNumber": 42,
+ "SectorType": 1,
+ "SectorExpiry": 1000,
+ "DealIDs": [1,2,3]
+ }
+ ],
+ "ComputeCid": true
+ }),
+ Self {
+ sectors: vec![
+ fil_actor_market_state::[]::SectorDeals::from_lotus_json(
+ SectorDealsLotusJson {
+ sector_number: Some(42), // Has sector_number in v13+
+ sector_type: Some(RegisteredSealProof::from(1).into()),
+ sector_expiry: 1000,
+ deal_ids: vec![1,2,3],
+ }
+ )
+ ],
+ compute_cid: true,
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ sectors: self.sectors.into_iter().map(|s| s.into_lotus_json()).collect(),
+ compute_cid: self.compute_cid,
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ sectors: json
+ .sectors
+ .into_iter()
+ .map(|s| fil_actor_market_state::[]::SectorDeals::from_lotus_json(s))
+ .collect(),
+ compute_cid: json.compute_cid,
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct OnMinerSectorsTerminateParamsLotusJsonV8 {
+ pub epoch: ChainEpoch,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json", rename = "DealIDs")]
+ pub deal_ids: Vec,
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct OnMinerSectorsTerminateParamsLotusJsonV13 {
+ pub epoch: ChainEpoch,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub sectors: BitField,
+}
+
+macro_rules! impl_lotus_json_for_on_miner_sectors_terminate_params {
+ (OnMinerSectorsTerminateParamsLotusJsonV8: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::OnMinerSectorsTerminateParams {
+ type LotusJson = OnMinerSectorsTerminateParamsLotusJsonV8;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "Epoch": 1000,
+ "DealIDs": [1,2,3]
+ }),
+ Self {
+ epoch: 1000,
+ deal_ids: vec![1,2,3],
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ epoch: self.epoch.into(),
+ deal_ids: self.deal_ids.into(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ epoch: json.epoch.into(),
+ deal_ids: json.deal_ids.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+ (OnMinerSectorsTerminateParamsLotusJsonV13: $($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::OnMinerSectorsTerminateParams {
+ type LotusJson = OnMinerSectorsTerminateParamsLotusJsonV13;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ let mut sectors = BitField::new();
+ sectors.set(1);
+
+ vec![
+ (
+ serde_json::json!({
+ "Epoch": 1000,
+ "Sectors": [1, 1]
+ }),
+ Self {
+ epoch: 1000,
+ sectors,
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ epoch: self.epoch.into(),
+ sectors: self.sectors.into(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ epoch: json.epoch.into(),
+ sectors: json.sectors.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct SectorDataSpecLotusJson {
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json", rename = "DealIDs")]
+ pub deal_ids: Vec,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub sector_type: RegisteredSealProof,
+}
+
+macro_rules! impl_lotus_json_for_sector_data_spec {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::SectorDataSpec {
+ type LotusJson = SectorDataSpecLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "DealIDs": [1,2,3],
+ "SectorType": 1
+ }),
+ Self {
+ deal_ids: vec![1,2,3],
+ sector_type: RegisteredSealProof::from(1).into(),
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ deal_ids: self.deal_ids.into(),
+ sector_type: self.sector_type.into(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ deal_ids: json.deal_ids.into(),
+ sector_type: json.sector_type.into(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct ComputeDataCommitmentParamsLotusJson {
+ pub inputs: Vec,
+}
+
+macro_rules! impl_lotus_json_for_compute_data_commitment_params {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::ComputeDataCommitmentParams {
+ type LotusJson = ComputeDataCommitmentParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "Inputs": [
+ {
+ "DealIDs": [1,2,3],
+ "SectorType": 1
+ }
+ ]
+ }),
+ Self {
+ inputs: vec![
+ fil_actor_market_state::[]::SectorDataSpec::from_lotus_json(
+ SectorDataSpecLotusJson {
+ deal_ids: vec![1,2,3],
+ sector_type: RegisteredSealProof::from(1).into(),
+ }
+ )
+ ],
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ inputs: self.inputs.into_iter().map(|s| s.into_lotus_json()).collect(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ inputs: json
+ .inputs
+ .into_iter()
+ .map(|s| fil_actor_market_state::[]::SectorDataSpec::from_lotus_json(s)) // delegate
+ .collect(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct DealQueryParamsLotusJson(
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ DealID,
+);
+
+macro_rules! impl_lotus_json_for_deal_query_params {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::DealQueryParams {
+ type LotusJson = DealQueryParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!(42),
+ Self { id: 42 }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ DealQueryParamsLotusJson(self.id.into())
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ id: json.0,
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct SettleDealPaymentsParamsLotusJson(
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ BitField,
+);
+
+macro_rules! impl_lotus_json_for_settle_deal_payments_params {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::SettleDealPaymentsParams {
+ type LotusJson = SettleDealPaymentsParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!([0]),
+ Self { deal_ids: BitField::new() }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ SettleDealPaymentsParamsLotusJson(self.deal_ids.into())
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ deal_ids: json.0,
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct PieceChangeLotusJson {
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub data: Cid,
+ #[schemars(with = "LotusJson")]
+ #[serde(with = "crate::lotus_json")]
+ pub size: PaddedPieceSize,
+ #[schemars(with = "LotusJson>")]
+ #[serde(with = "crate::lotus_json")]
+ pub payload: Vec,
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct SectorChangesLotusJson {
+ pub sector: u64,
+ pub minimum_commitment_epoch: ChainEpoch,
+ pub added: Vec,
+}
+
+#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
+#[serde(rename_all = "PascalCase")]
+pub struct SectorContentChangedParamsLotusJson {
+ pub sectors: Vec,
+}
+
+macro_rules! impl_lotus_json_for_sector_content_changed_params {
+ ($($version:literal),+) => {
+ $(
+ paste! {
+ impl HasLotusJson for fil_actor_market_state::[]::ext::miner::SectorContentChangedParams {
+ type LotusJson = SectorContentChangedParamsLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![
+ (
+ serde_json::json!({
+ "Sectors": []
+ }),
+ Self {
+ sectors: vec![],
+ }
+ ),
+ ]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ Self::LotusJson {
+ sectors: self.sectors.into_iter().map(|sector_changes| {
+ SectorChangesLotusJson {
+ sector: sector_changes.sector.into(),
+ minimum_commitment_epoch: sector_changes.minimum_commitment_epoch,
+ added: sector_changes.added.into_iter().map(|piece_change| {
+ PieceChangeLotusJson {
+ data: piece_change.data.into(),
+ size: piece_change.size.into(),
+ payload: piece_change.payload.into(),
+ }
+ }).collect(),
+ }
+ }).collect(),
+ }
+ }
+
+ fn from_lotus_json(json: Self::LotusJson) -> Self {
+ Self {
+ sectors: json.sectors.into_iter().map(|sector_changes_json| {
+ fil_actor_market_state::[]::ext::miner::SectorChanges {
+ sector: sector_changes_json.sector.into(),
+ minimum_commitment_epoch: sector_changes_json.minimum_commitment_epoch,
+ added: sector_changes_json.added.into_iter().map(|piece_change_json| {
+ fil_actor_market_state::[]::ext::miner::PieceChange {
+ data: piece_change_json.data.into(),
+ size: piece_change_json.size.into(),
+ payload: piece_change_json.payload.into(),
+ }
+ }).collect(),
+ }
+ }).collect(),
+ }
+ }
+ }
+ }
+ )+
+ };
+}
+
+impl_lotus_json_for_add_balance_params!(8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+impl_lotus_json_for_withdraw_balance_params!(8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+impl_lotus_json_for_label!(8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+impl_lotus_json_for_deal_proposal!(8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+impl_lotus_json_for_client_deal_proposal!(fvm_shared2::crypto::signature: ClientDealProposalV2LotusJson: 8, 9);
+impl_lotus_json_for_client_deal_proposal!(fvm_shared3::crypto::signature: ClientDealProposalV3LotusJson: 10, 11);
+impl_lotus_json_for_client_deal_proposal!(fvm_shared4::crypto::signature: ClientDealProposalV4LotusJson: 12, 13, 14, 15, 16, 17);
+impl_publish_storage_deals_params_snapshots_v2!(8, 9);
+impl_publish_storage_deals_params_snapshots_v3!(10, 11);
+impl_publish_storage_deals_params_snapshots_v4!(12, 13, 14, 15, 16, 17);
+impl_lotus_json_for_sector_deals!(fvm_shared2::sector: no_sector_type: no_sector_number: 8);
+impl_lotus_json_for_sector_deals!(fvm_shared3::sector: no_sector_number: 9, 10, 11, 12);
+impl_lotus_json_for_sector_deals!(fvm_shared4::sector: 13, 14, 15, 16, 17);
+impl_lotus_json_for_verify_deals_for_activation_params!(v8);
+impl_lotus_json_for_verify_deals_for_activation_params!(v9_to_v12: 9, 10, 11, 12);
+impl_lotus_json_for_verify_deals_for_activation_params!(v13_plus: 13, 14, 15, 16, 17);
+impl_lotus_json_for_activate_deals_params!(8, 9, 10, 11);
+impl_lotus_json_for_batch_activate_deals_params!(v12: 12);
+impl_lotus_json_for_batch_activate_deals_params!(v13_onwards: 13, 14, 15, 16, 17);
+impl_lotus_json_for_on_miner_sectors_terminate_params!(OnMinerSectorsTerminateParamsLotusJsonV8: 8, 9, 10, 11, 12);
+impl_lotus_json_for_on_miner_sectors_terminate_params!(OnMinerSectorsTerminateParamsLotusJsonV13: 13, 14, 15, 16, 17);
+impl_lotus_json_for_sector_data_spec!(8, 9, 10, 11);
+impl_lotus_json_for_compute_data_commitment_params!(8, 9, 10, 11);
+impl_lotus_json_for_deal_query_params!(10, 11, 12, 13, 14, 15, 16, 17);
+impl_lotus_json_for_settle_deal_payments_params!(13, 14, 15, 16, 17);
+impl_lotus_json_for_sector_content_changed_params!(13, 14, 15, 16, 17);
+
+test_snapshots!(fil_actor_market_state: AddBalanceParams: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: WithdrawBalanceParams: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: Label: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: DealProposal: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: ClientDealProposal: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: PublishStorageDealsParams: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: SectorDeals: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: VerifyDealsForActivationParams: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: ActivateDealsParams: 8, 9, 10, 11);
+test_snapshots!(fil_actor_market_state: BatchActivateDealsParams: 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: OnMinerSectorsTerminateParams: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: SectorDataSpec: 8, 9, 10, 11);
+test_snapshots!(fil_actor_market_state: ComputeDataCommitmentParams: 8, 9, 10, 11);
+test_snapshots!(fil_actor_market_state: DealQueryParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: SettleDealPaymentsParams: 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealActivationParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealClientCollateralParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealClientParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealDataCommitmentParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealLabelParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealProviderCollateralParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealProviderParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealTermParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealTotalPriceParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealVerifiedParams: 10, 11, 12, 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: GetDealSectorParams: 13, 14, 15, 16, 17);
+test_snapshots!(fil_actor_market_state: ext::miner: SectorContentChangedParams: 13, 14, 15, 16, 17);
diff --git a/src/lotus_json/actor_states/methods/mod.rs b/src/lotus_json/actor_states/methods/mod.rs
index 9ebd49368541..ae64614e81ad 100644
--- a/src/lotus_json/actor_states/methods/mod.rs
+++ b/src/lotus_json/actor_states/methods/mod.rs
@@ -11,6 +11,7 @@ mod evm_actor_params;
mod init_constructor_params;
mod init_exec4_params;
mod init_exec_params;
+mod market_actor_params;
mod miner_actor_params;
mod multisig_actor;
mod paych_params;
diff --git a/src/lotus_json/mod.rs b/src/lotus_json/mod.rs
index 5d1c971ddaa6..345bae794644 100644
--- a/src/lotus_json/mod.rs
+++ b/src/lotus_json/mod.rs
@@ -231,6 +231,7 @@ mod miner_info; // fil_actor_miner_state::v12::MinerInfo: !quickcheck::Arbitrary
mod miner_power; // actors::miner::MinerInfo: !quickcheck::Arbitrary
mod nonempty; // can't make snapshots of generic type
mod opt; // can't make snapshots of generic type
+mod padded_piece_size;
mod pending_beneficiary_change; // fil_actor_miner_state::v12::PendingBeneficiaryChange: !quickcheck::Arbitrary
mod power_claim; // actors::power::Claim: !quickcheck::Arbitrary
mod raw_bytes; // fvm_ipld_encoding::RawBytes: !quickcheck::Arbitrary
@@ -243,6 +244,33 @@ mod verifreg_claim;
pub use vec::*;
+#[macro_export]
+macro_rules! test_snapshots {
+ ($module:path: $ty:ident: $($version:literal),+ $(,)?) => {
+ $(
+ paste::paste! {
+ #[test]
+ fn []() {
+ use super::*;
+ assert_all_snapshots::<$module::[]::$ty>();
+ }
+ }
+ )+
+ };
+
+ ($module:path: $nested_path:path: $ty:ident: $($version:literal),+ $(,)?) => {
+ $(
+ paste::paste! {
+ #[test]
+ fn []() {
+ use super::*;
+ assert_all_snapshots::<$module::[]::$nested_path::$ty>();
+ }
+ }
+ )+
+ };
+}
+
#[cfg(any(test, doc))]
pub fn assert_all_snapshots()
where
diff --git a/src/lotus_json/padded_piece_size.rs b/src/lotus_json/padded_piece_size.rs
new file mode 100644
index 000000000000..ac6970d3834b
--- /dev/null
+++ b/src/lotus_json/padded_piece_size.rs
@@ -0,0 +1,26 @@
+// Copyright 2019-2025 ChainSafe Systems
+// SPDX-License-Identifier: Apache-2.0, MIT
+
+use super::*;
+use crate::shim::piece::PaddedPieceSize;
+
+#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
+#[schemars(rename = "PaddedPieceSize")]
+pub struct PaddedPieceSizeLotusJson(#[schemars(with = "u64")] PaddedPieceSize);
+
+impl HasLotusJson for PaddedPieceSize {
+ type LotusJson = PaddedPieceSizeLotusJson;
+
+ #[cfg(test)]
+ fn snapshots() -> Vec<(serde_json::Value, Self)> {
+ vec![]
+ }
+
+ fn into_lotus_json(self) -> Self::LotusJson {
+ PaddedPieceSizeLotusJson(self)
+ }
+
+ fn from_lotus_json(PaddedPieceSizeLotusJson(inner): Self::LotusJson) -> Self {
+ inner
+ }
+}
diff --git a/src/rpc/registry/actors/market.rs b/src/rpc/registry/actors/market.rs
new file mode 100644
index 000000000000..3a752849d525
--- /dev/null
+++ b/src/rpc/registry/actors/market.rs
@@ -0,0 +1,191 @@
+// 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::address::Address;
+use crate::shim::message::MethodNum;
+use cid::Cid;
+
+macro_rules! register_market_basic_methods {
+ ($registry:expr, $code_cid:expr, $state_version:path) => {{
+ use $state_version::{
+ AddBalanceParams, Method, OnMinerSectorsTerminateParams, PublishStorageDealsParams,
+ VerifyDealsForActivationParams, WithdrawBalanceParams,
+ };
+
+ register_actor_methods!(
+ $registry,
+ $code_cid,
+ [
+ (Method::AddBalance, AddBalanceParams),
+ (Method::WithdrawBalance, WithdrawBalanceParams),
+ (Method::PublishStorageDeals, PublishStorageDealsParams),
+ (
+ Method::VerifyDealsForActivation,
+ VerifyDealsForActivationParams
+ ),
+ (
+ Method::OnMinerSectorsTerminate,
+ OnMinerSectorsTerminateParams
+ )
+ ]
+ );
+
+ // Register methods without parameters
+ register_actor_methods!(
+ $registry,
+ $code_cid,
+ [(Method::Constructor, empty), (Method::CronTick, empty),]
+ );
+ }};
+}
+
+macro_rules! register_market_exported_methods_v10_onwards {
+ ($registry:expr, $code_cid:expr, $state_version:path) => {{
+ use $state_version::{
+ AddBalanceParams, GetDealActivationParams, GetDealClientCollateralParams,
+ GetDealClientParams, GetDealDataCommitmentParams, GetDealLabelParams,
+ GetDealProviderCollateralParams, GetDealProviderParams, GetDealTermParams,
+ GetDealTotalPriceParams, GetDealVerifiedParams, Method, PublishStorageDealsParams,
+ WithdrawBalanceParams,
+ };
+
+ // Register exported methods
+ register_actor_methods!(
+ $registry,
+ $code_cid,
+ [
+ (Method::AddBalanceExported, AddBalanceParams),
+ (Method::WithdrawBalanceExported, WithdrawBalanceParams),
+ (
+ Method::PublishStorageDealsExported,
+ PublishStorageDealsParams
+ ),
+ (Method::GetBalanceExported, Address),
+ (
+ Method::GetDealDataCommitmentExported,
+ GetDealDataCommitmentParams
+ ),
+ (Method::GetDealClientExported, GetDealClientParams),
+ (Method::GetDealProviderExported, GetDealProviderParams),
+ (Method::GetDealLabelExported, GetDealLabelParams),
+ (Method::GetDealTermExported, GetDealTermParams),
+ (Method::GetDealTotalPriceExported, GetDealTotalPriceParams),
+ (
+ Method::GetDealClientCollateralExported,
+ GetDealClientCollateralParams
+ ),
+ (
+ Method::GetDealProviderCollateralExported,
+ GetDealProviderCollateralParams
+ ),
+ (Method::GetDealVerifiedExported, GetDealVerifiedParams),
+ (Method::GetDealActivationExported, GetDealActivationParams),
+ ]
+ );
+ }};
+}
+
+macro_rules! register_market_exported_methods_v13_onwards {
+ ($registry:expr, $code_cid:expr, $market_state_version:path) => {{
+ use $market_state_version::{
+ GetDealSectorParams, Method, SettleDealPaymentsParams,
+ ext::miner::SectorContentChangedParams,
+ };
+
+ register_actor_methods!(
+ $registry,
+ $code_cid,
+ [
+ (Method::GetDealSectorExported, GetDealSectorParams),
+ (Method::SettleDealPaymentsExported, SettleDealPaymentsParams),
+ (
+ Method::SectorContentChangedExported,
+ SectorContentChangedParams
+ )
+ ]
+ );
+ }};
+}
+
+macro_rules! register_market_versions_8_to_9 {
+ ($registry:expr, $code_cid:expr, $state_version:path) => {{
+ register_market_basic_methods!($registry, $code_cid, $state_version);
+
+ use $state_version::{ActivateDealsParams, ComputeDataCommitmentParams, Method};
+
+ register_actor_methods!(
+ $registry,
+ $code_cid,
+ [
+ (Method::ActivateDeals, ActivateDealsParams),
+ (Method::ComputeDataCommitment, ComputeDataCommitmentParams)
+ ]
+ );
+ }};
+}
+
+macro_rules! register_market_versions_10_to_11 {
+ ($registry:expr, $code_cid:expr, $state_version:path) => {{
+ register_market_basic_methods!($registry, $code_cid, $state_version);
+ register_market_exported_methods_v10_onwards!($registry, $code_cid, $state_version);
+
+ use $state_version::{ActivateDealsParams, ComputeDataCommitmentParams, Method};
+
+ register_actor_methods!(
+ $registry,
+ $code_cid,
+ [
+ (Method::ActivateDeals, ActivateDealsParams),
+ (Method::ComputeDataCommitment, ComputeDataCommitmentParams)
+ ]
+ );
+ }};
+}
+
+macro_rules! register_market_versions_12 {
+ ($registry:expr, $code_cid:expr, $state_version:path) => {{
+ register_market_basic_methods!($registry, $code_cid, $state_version);
+ register_market_exported_methods_v10_onwards!($registry, $code_cid, $state_version);
+
+ use $state_version::{BatchActivateDealsParams, Method};
+
+ register_actor_methods!(
+ $registry,
+ $code_cid,
+ [(Method::BatchActivateDeals, BatchActivateDealsParams)]
+ );
+ }};
+}
+
+macro_rules! register_market_versions_onwards {
+ ($registry:expr, $code_cid:expr, $market_state_version:path) => {{
+ register_market_basic_methods!($registry, $code_cid, $market_state_version);
+ register_market_exported_methods_v10_onwards!($registry, $code_cid, $market_state_version);
+ register_market_exported_methods_v13_onwards!($registry, $code_cid, $market_state_version);
+
+ use $market_state_version::{BatchActivateDealsParams, Method};
+
+ register_actor_methods!(
+ $registry,
+ $code_cid,
+ [(Method::BatchActivateDeals, BatchActivateDealsParams),]
+ );
+ }};
+}
+
+pub(crate) fn register_actor_methods(registry: &mut MethodRegistry, cid: Cid, version: u64) {
+ match version {
+ 8 => register_market_versions_8_to_9!(registry, cid, fil_actor_market_state::v8),
+ 9 => register_market_versions_8_to_9!(registry, cid, fil_actor_market_state::v9),
+ 10 => register_market_versions_10_to_11!(registry, cid, fil_actor_market_state::v10),
+ 11 => register_market_versions_10_to_11!(registry, cid, fil_actor_market_state::v11),
+ 12 => register_market_versions_12!(registry, cid, fil_actor_market_state::v12),
+ 13 => register_market_versions_onwards!(registry, cid, fil_actor_market_state::v13),
+ 14 => register_market_versions_onwards!(registry, cid, fil_actor_market_state::v14),
+ 15 => register_market_versions_onwards!(registry, cid, fil_actor_market_state::v15),
+ 16 => register_market_versions_onwards!(registry, cid, fil_actor_market_state::v16),
+ 17 => register_market_versions_onwards!(registry, cid, fil_actor_market_state::v17),
+ _ => {}
+ }
+}
diff --git a/src/rpc/registry/actors/mod.rs b/src/rpc/registry/actors/mod.rs
index 66b4f62b320d..47b1b4017847 100644
--- a/src/rpc/registry/actors/mod.rs
+++ b/src/rpc/registry/actors/mod.rs
@@ -8,6 +8,7 @@ pub(crate) mod eam;
pub(crate) mod eth_account;
pub(crate) mod evm;
pub(crate) mod init;
+pub(crate) mod market;
pub(crate) mod miner;
pub(crate) mod multisig;
pub(crate) mod payment_channel;
diff --git a/src/rpc/registry/methods_reg.rs b/src/rpc/registry/methods_reg.rs
index 75b8ea34162f..f2587346db43 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, eam, eth_account, evm, init, miner, multisig, payment_channel,
- power, reward, system, verified_reg,
+ account, cron, datacap, eam, eth_account, evm, init, market, miner, multisig,
+ payment_channel, power, reward, system, verified_reg,
};
for (&cid, &(actor_type, version)) in ACTOR_REGISTRY.iter() {
@@ -94,6 +94,7 @@ impl MethodRegistry {
BuiltinActor::Reward => reward::register_actor_methods(self, cid, version),
BuiltinActor::Cron => cron::register_actor_methods(self, cid, version),
BuiltinActor::Multisig => multisig::register_actor_methods(self, cid, version),
+ BuiltinActor::Market => market::register_actor_methods(self, cid, version),
BuiltinActor::VerifiedRegistry => {
verified_reg::register_actor_methods(self, cid, version)
}
diff --git a/src/shim/sector.rs b/src/shim/sector.rs
index af354efbb6d3..e3056d1670d2 100644
--- a/src/shim/sector.rs
+++ b/src/shim/sector.rs
@@ -135,6 +135,12 @@ registered_seal_proof_conversion!(
RegisteredSealProofV4
);
+impl RegisteredSealProof {
+ pub fn invalid() -> Self {
+ RegisteredSealProof(RegisteredSealProofV4::Invalid(0))
+ }
+}
+
#[cfg(test)]
impl quickcheck::Arbitrary for RegisteredSealProof {
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
diff --git a/src/tool/subcommands/api_cmd/api_compare_tests.rs b/src/tool/subcommands/api_cmd/api_compare_tests.rs
index a250382dc28e..31a39d1fcfee 100644
--- a/src/tool/subcommands/api_cmd/api_compare_tests.rs
+++ b/src/tool/subcommands/api_cmd/api_compare_tests.rs
@@ -1902,6 +1902,7 @@ 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(market_actor_state_decode_params_tests(tipset)?);
tests.extend(paych_actor_state_decode_params_tests(tipset)?);
tests.extend(eam_actor_state_decode_params_tests(tipset)?);
@@ -3326,6 +3327,290 @@ fn verified_reg_actor_state_decode_params_tests(tipset: &Tipset) -> anyhow::Resu
])
}
+fn market_actor_state_decode_params_tests(tipset: &Tipset) -> anyhow::Result> {
+ fn create_deal_proposal(
+ client: fvm_shared4::address::Address,
+ provider: fvm_shared4::address::Address,
+ client_collateral: fvm_shared4::econ::TokenAmount,
+ provider_collateral: fvm_shared4::econ::TokenAmount,
+ start_epoch: fvm_shared4::clock::ChainEpoch,
+ end_epoch: fvm_shared4::clock::ChainEpoch,
+ ) -> fil_actor_market_state::v16::DealProposal {
+ let piece_cid = Cid::default();
+ let piece_size = fvm_shared4::piece::PaddedPieceSize(2048);
+ let storage_price_per_epoch = fvm_shared4::econ::TokenAmount::from_atto(10u8);
+
+ fil_actor_market_state::v16::DealProposal {
+ piece_cid,
+ piece_size,
+ verified_deal: false,
+ client,
+ provider,
+ label: fil_actor_market_state::v16::Label::String("label".to_string()),
+ start_epoch,
+ end_epoch,
+ storage_price_per_epoch,
+ provider_collateral,
+ client_collateral,
+ }
+ }
+
+ fn create_client_deal_proposal() -> fil_actor_market_state::v16::ClientDealProposal {
+ let proposal = create_deal_proposal(
+ fvm_shared4::address::Address::new_id(1000),
+ fvm_shared4::address::Address::new_id(1000),
+ fvm_shared4::econ::TokenAmount::from_atto(10u8),
+ fvm_shared4::econ::TokenAmount::from_atto(10u8),
+ 0,
+ 10,
+ );
+ fil_actor_market_state::v16::ClientDealProposal {
+ proposal,
+ client_signature: fvm_shared4::crypto::signature::Signature::new_bls(
+ b"test_signature".to_vec(),
+ ),
+ }
+ }
+
+ fn create_sector_deals() -> fil_actor_market_state::v16::SectorDeals {
+ fil_actor_market_state::v16::SectorDeals {
+ sector_number: 42,
+ sector_type: fvm_shared4::sector::RegisteredSealProof::StackedDRG2KiBV1,
+ sector_expiry: 100,
+ deal_ids: vec![0, 1],
+ }
+ }
+
+ fn create_sector_changes() -> fil_actor_miner_state::v16::SectorChanges {
+ let piece_change = fil_actor_miner_state::v16::PieceChange {
+ data: Cid::default(),
+ size: fvm_shared4::piece::PaddedPieceSize(2048),
+ payload: fvm_ipld_encoding::RawBytes::new(vec![0x12, 0x34, 0x56, 0x78]),
+ };
+
+ fil_actor_miner_state::v16::SectorChanges {
+ sector: 2,
+ minimum_commitment_epoch: 0,
+ added: vec![piece_change],
+ }
+ }
+
+ let market_actor_add_balance_params = fil_actor_market_state::v16::AddBalanceParams {
+ provider_or_client: fvm_shared4::address::Address::new_id(1000),
+ };
+ let market_actor_withdraw_balance_params = fil_actor_market_state::v16::WithdrawBalanceParams {
+ provider_or_client: Address::new_id(1000).into(),
+ amount: TokenAmount::default().into(),
+ };
+
+ let market_actor_publish_storage_deals_params =
+ fil_actor_market_state::v16::PublishStorageDealsParams {
+ deals: vec![create_client_deal_proposal()],
+ };
+
+ let _market_actor_verify_deals_for_activation_params =
+ fil_actor_market_state::v16::VerifyDealsForActivationParams {
+ sectors: vec![create_sector_deals()],
+ };
+
+ let _market_actor_batch_activate_deals_params =
+ fil_actor_market_state::v16::BatchActivateDealsParams {
+ sectors: vec![create_sector_deals()],
+ compute_cid: true,
+ };
+
+ let _market_actor_on_miner_sectors_terminate_params =
+ fil_actor_market_state::v16::OnMinerSectorsTerminateParams {
+ epoch: 123,
+ sectors: {
+ let mut bf = BitField::new();
+ bf.set(3);
+ bf
+ },
+ };
+
+ let market_actor_get_balance_exported_params = Address::new_id(1000);
+
+ let market_actor_settle_deal_payments_params =
+ fil_actor_market_state::v16::SettleDealPaymentsParams {
+ deal_ids: {
+ let mut bf = BitField::new();
+ bf.set(42);
+ bf
+ },
+ };
+
+ let market_actor_get_deal_data_commitment_params =
+ fil_actor_market_state::v16::DealQueryParams { id: 0 };
+
+ let _market_actor_sector_content_changed_params = {
+ fil_actor_miner_state::v16::SectorContentChangedParams {
+ sectors: vec![create_sector_changes()],
+ }
+ };
+
+ Ok(vec![
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::AddBalance as u64,
+ to_vec(&market_actor_add_balance_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::WithdrawBalance as u64,
+ to_vec(&market_actor_withdraw_balance_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::PublishStorageDeals as u64,
+ to_vec(&market_actor_publish_storage_deals_params)?,
+ tipset.key().into(),
+ ))?),
+ // TODO(go-state-types): https://github.com/filecoin-project/go-state-types/issues/409
+ // Enable this test when lotus supports this method
+ // RpcTest::identity(StateDecodeParams::request((
+ // Address::MARKET_ACTOR,
+ // fil_actor_market_state::v16::Method::BatchActivateDeals as u64,
+ // to_vec(&market_actor_batch_activate_deals_params)?,
+ // tipset.key().into(),
+ // ))?),
+ // TODO(go-state-types): https://github.com/filecoin-project/go-state-types/issues/408
+ // Enable this test once Lotus adds the `sector_number` field.
+ // RpcTest::identity(StateDecodeParams::request((
+ // Address::MARKET_ACTOR,
+ // fil_actor_market_state::v16::Method::VerifyDealsForActivation as u64,
+ // to_vec(&market_actor_verify_deals_for_activation_params)?,
+ // tipset.key().into(),
+ // ))?),
+ // TODO(go-state-types): https://github.com/filecoin-project/go-state-types/issues/408
+ // Enable this test when lotus supports correct types in go-state-types.
+ // RpcTest::identity(StateDecodeParams::request((
+ // Address::MARKET_ACTOR,
+ // fil_actor_market_state::v16::Method::OnMinerSectorsTerminate as u64,
+ // to_vec(&market_actor_on_miner_sectors_terminate_params)?,
+ // tipset.key().into(),
+ // ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::Constructor as u64,
+ vec![],
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::CronTick as u64,
+ vec![],
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::AddBalanceExported as u64,
+ to_vec(&market_actor_get_balance_exported_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::WithdrawBalanceExported as u64,
+ to_vec(&market_actor_withdraw_balance_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::PublishStorageDealsExported as u64,
+ to_vec(&market_actor_publish_storage_deals_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetBalanceExported as u64,
+ to_vec(&market_actor_get_balance_exported_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealDataCommitmentExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealClientExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealProviderExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealLabelExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealTermExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealTotalPriceExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealClientCollateralExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealProviderCollateralExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealVerifiedExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealActivationExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::GetDealSectorExported as u64,
+ to_vec(&market_actor_get_deal_data_commitment_params)?,
+ tipset.key().into(),
+ ))?),
+ RpcTest::identity(StateDecodeParams::request((
+ Address::MARKET_ACTOR,
+ fil_actor_market_state::v16::Method::SettleDealPaymentsExported as u64,
+ to_vec(&market_actor_settle_deal_payments_params)?,
+ tipset.key().into(),
+ ))?),
+ // TODO(lotus): https://github.com/filecoin-project/lotus/issues/13329
+ // Lotus panics while decoding this method.
+ // RpcTest::identity(StateDecodeParams::request((
+ // Address::MARKET_ACTOR,
+ // fil_actor_market_state::v16::Method::SectorContentChangedExported as u64,
+ // to_vec(&market_actor_sector_content_changed_params)?,
+ // tipset.key().into(),
+ // ))?),
+ ])
+}
+
fn read_state_api_tests(tipset: &Tipset) -> anyhow::Result> {
let tests = vec![
RpcTest::identity(StateReadState::request((
diff --git a/src/tool/subcommands/api_cmd/test_snapshots.txt b/src/tool/subcommands/api_cmd/test_snapshots.txt
index 39e9e1846fdb..a55294d47891 100644
--- a/src/tool/subcommands/api_cmd/test_snapshots.txt
+++ b/src/tool/subcommands/api_cmd/test_snapshots.txt
@@ -90,6 +90,27 @@ filecoin_evm_invokecontractdelegate_statedecodeparams_1755004924714578.rpcsnap.j
filecoin_evm_resurrect_statedecodeparams_1755004924714636.rpcsnap.json.zst
filecoin_gasestimategaslimit_1741782110512299.rpcsnap.json.zst
filecoin_getactoreventsraw_1741782590255476.rpcsnap.json.zst
+filecoin_market_addbalance_statedecodeparams_1757426002278914.rpcsnap.json.zst
+filecoin_market_addbalanceexported_statedecodeparams_1757426002338931.rpcsnap.json.zst
+filecoin_market_constructor_statedecodeparams_1757426002270973.rpcsnap.json.zst
+filecoin_market_crontick_statedecodeparams_1757426002327008.rpcsnap.json.zst
+filecoin_market_getbalanceexported_statedecodeparams_1757426002362902.rpcsnap.json.zst
+filecoin_market_getdealactivationexported_statedecodeparams_1757426002422988.rpcsnap.json.zst
+filecoin_market_getdealclientcollateralexported_statedecodeparams_1757426002407069.rpcsnap.json.zst
+filecoin_market_getdealclientexported_statedecodeparams_1757426002366899.rpcsnap.json.zst
+filecoin_market_getdealdatacommitmentexported_statedecodeparams_1757426002363106.rpcsnap.json.zst
+filecoin_market_getdeallabelexported_statedecodeparams_1757426002382966.rpcsnap.json.zst
+filecoin_market_getdealprovidercollateralexported_statedecodeparams_1757426002415167.rpcsnap.json.zst
+filecoin_market_getdealproviderexported_statedecodeparams_1757426002375082.rpcsnap.json.zst
+filecoin_market_getdealsectorexported_statedecodeparams_1757426002423094.rpcsnap.json.zst
+filecoin_market_getdealtermexported_statedecodeparams_1757426002394955.rpcsnap.json.zst
+filecoin_market_getdealtotalpriceexported_statedecodeparams_1757426002399187.rpcsnap.json.zst
+filecoin_market_getdealverifiedexported_statedecodeparams_1757426002419004.rpcsnap.json.zst
+filecoin_market_publishstoragedeals_statedecodeparams_1757426002306931.rpcsnap.json.zst
+filecoin_market_publishstoragedealsexported_statedecodeparams_1757426002358906.rpcsnap.json.zst
+filecoin_market_settledealpaymentsexported_statedecodeparams_1757426002430957.rpcsnap.json.zst
+filecoin_market_withdrawbalance_statedecodeparams_1757426002298895.rpcsnap.json.zst
+filecoin_market_withdrawbalanceexported_statedecodeparams_1757426002346995.rpcsnap.json.zst
filecoin_miner_statedecodeparams_1755027105570743.rpcsnap.json.zst
filecoin_miner_statedecodeparams_1755027105571288.rpcsnap.json.zst
filecoin_miner_statedecodeparams_1755027105571367.rpcsnap.json.zst