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