diff --git a/src/cli/main.rs b/src/cli/main.rs index ecbea08b52c8..b46831dd235e 100644 --- a/src/cli/main.rs +++ b/src/cli/main.rs @@ -1,7 +1,6 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use super::subcommands::Subcommand; use crate::cli::subcommands::Cli; use crate::cli_shared::logger; use crate::networks::NetworkChain; @@ -31,20 +30,5 @@ where let (_bg_tasks, _guards) = logger::setup_logger(&crate::cli_shared::cli::CliOpts::default()); - // Run command - match cmd { - Subcommand::Chain(cmd) => cmd.run(client).await, - Subcommand::Auth(cmd) => cmd.run(client).await, - Subcommand::Net(cmd) => cmd.run(client).await, - Subcommand::Sync(cmd) => cmd.run(client).await, - Subcommand::Mpool(cmd) => cmd.run(client).await, - Subcommand::State(cmd) => cmd.run(client).await, - Subcommand::Config(cmd) => cmd.run(&mut std::io::stdout()), - Subcommand::Info(cmd) => cmd.run(client).await, - Subcommand::Snapshot(cmd) => cmd.run(client).await, - Subcommand::Shutdown(cmd) => cmd.run(client).await, - Subcommand::Healthcheck(cmd) => cmd.run(client).await, - Subcommand::F3(cmd) => cmd.run(client).await, - Subcommand::WaitApi(cmd) => cmd.run(client).await, - } + cmd.run(client).await } diff --git a/src/cli/subcommands/config_cmd.rs b/src/cli/subcommands/config_cmd.rs index cb2422f290fb..764953f76ade 100644 --- a/src/cli/subcommands/config_cmd.rs +++ b/src/cli/subcommands/config_cmd.rs @@ -6,7 +6,7 @@ use std::io::Write; use anyhow::Context as _; use clap::Subcommand; -use crate::cli::subcommands::Config; +use crate::{cli::subcommands::Config, rpc}; #[derive(Debug, Subcommand)] pub enum ConfigCommands { @@ -15,7 +15,11 @@ pub enum ConfigCommands { } impl ConfigCommands { - pub fn run(self, sink: &mut W) -> anyhow::Result<()> { + pub async fn run(self, _: rpc::Client) -> anyhow::Result<()> { + self.run_internal(&mut std::io::stdout()) + } + + fn run_internal(self, sink: &mut W) -> anyhow::Result<()> { match self { Self::Dump => writeln!( sink, @@ -37,7 +41,7 @@ mod tests { let expected_config = Config::default(); let mut sink = std::io::BufWriter::new(Vec::new()); - ConfigCommands::Dump.run(&mut sink).unwrap(); + ConfigCommands::Dump.run_internal(&mut sink).unwrap(); let actual_config: Config = toml::from_str(std::str::from_utf8(sink.buffer()).unwrap()) .expect("Invalid configuration!"); diff --git a/src/cli/subcommands/mod.rs b/src/cli/subcommands/mod.rs index c74eeb709062..29546f14b625 100644 --- a/src/cli/subcommands/mod.rs +++ b/src/cli/subcommands/mod.rs @@ -20,13 +20,6 @@ mod state_cmd; mod sync_cmd; mod wait_api_cmd; -pub(crate) use crate::cli_shared::cli::Config; -use crate::cli_shared::cli::HELP_MESSAGE; -use crate::lotus_json::HasLotusJson; -use crate::utils::version::FOREST_VERSION_STRING; -use clap::Parser; -use tracing::error; - pub(super) use self::{ auth_cmd::AuthCommands, chain_cmd::ChainCommands, config_cmd::ConfigCommands, f3_cmd::F3Commands, healthcheck_cmd::HealthcheckCommand, mpool_cmd::MpoolCommands, @@ -34,6 +27,13 @@ pub(super) use self::{ state_cmd::StateCommands, sync_cmd::SyncCommands, wait_api_cmd::WaitApiCommand, }; use crate::cli::subcommands::info_cmd::InfoCommand; +pub(crate) use crate::cli_shared::cli::Config; +use crate::cli_shared::cli::HELP_MESSAGE; +use crate::lotus_json::HasLotusJson; +use crate::utils::version::FOREST_VERSION_STRING; +use clap::Parser; +use spire_enum::prelude::delegated_enum; +use tracing::error; /// CLI structure generated when interacting with Forest binary #[derive(Parser)] @@ -49,6 +49,7 @@ pub struct Cli { } /// Forest binary sub-commands available. +#[delegated_enum] #[derive(clap::Subcommand, Debug)] pub enum Subcommand { /// Interact with Filecoin blockchain @@ -102,6 +103,12 @@ pub enum Subcommand { WaitApi(WaitApiCommand), } +impl Subcommand { + pub async fn run(self, client: crate::rpc::Client) -> anyhow::Result<()> { + delegate_subcommand!(self.run(client).await) + } +} + /// Print an error message and exit the program with an error code /// Used for handling high level errors such as invalid parameters pub fn cli_error_and_die(msg: impl AsRef, code: i32) -> ! { diff --git a/src/networks/mod.rs b/src/networks/mod.rs index 84194ad43d7b..5379d76a1e2d 100644 --- a/src/networks/mod.rs +++ b/src/networks/mod.rs @@ -6,7 +6,6 @@ use std::sync::LazyLock; use ahash::HashMap; use cid::Cid; -use fil_actors_shared::v13::runtime::Policy; use fvm_ipld_blockstore::Blockstore; use itertools::Itertools; use libp2p::Multiaddr; @@ -20,11 +19,14 @@ use tracing::warn; use crate::beacon::{BeaconPoint, BeaconSchedule, DrandBeacon, DrandConfig}; use crate::db::SettingsStore; use crate::eth::EthChainId; -use crate::shim::clock::{ChainEpoch, EPOCH_DURATION_SECONDS, EPOCHS_IN_DAY}; -use crate::shim::econ::TokenAmount; -use crate::shim::machine::BuiltinActorManifest; -use crate::shim::sector::{RegisteredPoStProofV3, RegisteredSealProofV3}; -use crate::shim::version::NetworkVersion; +use crate::shim::{ + clock::{ChainEpoch, EPOCH_DURATION_SECONDS, EPOCHS_IN_DAY}, + econ::TokenAmount, + machine::BuiltinActorManifest, + runtime::Policy, + sector::{RegisteredPoStProofV3, RegisteredSealProofV3}, + version::NetworkVersion, +}; use crate::utils::misc::env::env_or_default; use crate::{make_butterfly_policy, make_calibnet_policy, make_devnet_policy, make_mainnet_policy}; @@ -297,7 +299,7 @@ impl ChainConfig { propagation_delay_secs: env_or_default(ENV_FOREST_PROPAGATION_DELAY_SECS, 10), genesis_network: GENESIS_NETWORK_VERSION, height_infos: HEIGHT_INFOS.clone(), - policy: make_mainnet_policy!(v13), + policy: make_mainnet_policy!(v13).into(), eth_chain_id: ETH_CHAIN_ID, breeze_gas_tamping_duration: BREEZE_GAS_TAMPING_DURATION, // 1 year on mainnet @@ -331,7 +333,7 @@ impl ChainConfig { propagation_delay_secs: env_or_default(ENV_FOREST_PROPAGATION_DELAY_SECS, 10), genesis_network: GENESIS_NETWORK_VERSION, height_infos: HEIGHT_INFOS.clone(), - policy: make_calibnet_policy!(v13), + policy: make_calibnet_policy!(v13).into(), eth_chain_id: ETH_CHAIN_ID, breeze_gas_tamping_duration: BREEZE_GAS_TAMPING_DURATION, // 3 days on calibnet @@ -365,7 +367,7 @@ impl ChainConfig { propagation_delay_secs: env_or_default(ENV_FOREST_PROPAGATION_DELAY_SECS, 1), genesis_network: *GENESIS_NETWORK_VERSION, height_infos: HEIGHT_INFOS.clone(), - policy: make_devnet_policy!(v13), + policy: make_devnet_policy!(v13).into(), eth_chain_id: ETH_CHAIN_ID, breeze_gas_tamping_duration: BREEZE_GAS_TAMPING_DURATION, // Devnet ramp is 200 epochs in Lotus (subject to change). @@ -395,7 +397,7 @@ impl ChainConfig { propagation_delay_secs: env_or_default(ENV_FOREST_PROPAGATION_DELAY_SECS, 6), genesis_network: GENESIS_NETWORK_VERSION, height_infos: HEIGHT_INFOS.clone(), - policy: make_butterfly_policy!(v13), + policy: make_butterfly_policy!(v13).into(), eth_chain_id: ETH_CHAIN_ID, breeze_gas_tamping_duration: BREEZE_GAS_TAMPING_DURATION, // Butterflynet ramp is current set to 365 days in Lotus but this may change. diff --git a/src/rpc/methods/f3.rs b/src/rpc/methods/f3.rs index 238c563c4e5d..65db2989580e 100644 --- a/src/rpc/methods/f3.rs +++ b/src/rpc/methods/f3.rs @@ -15,14 +15,7 @@ pub use self::types::{ }; use self::{types::*, util::*}; use super::wallet::WalletSign; -use crate::shim::actors::{ - convert::{ - from_policy_v13_to_v9, from_policy_v13_to_v10, from_policy_v13_to_v11, - from_policy_v13_to_v12, from_policy_v13_to_v14, from_policy_v13_to_v15, - from_policy_v13_to_v16, from_policy_v13_to_v17, - }, - miner, power, -}; +use crate::shim::actors::{miner, power}; use crate::{ blocks::Tipset, chain::index::ResolveNullTipset, @@ -216,6 +209,7 @@ impl GetPowerTable { let state: power::State = ctx.state_manager.get_actor_state(ts)?; let mut id_power_worker_mappings = vec![]; + let policy = &ctx.chain_config().policy; match &state { power::State::V8(s) => { fn map_err(e: E) -> fil_actors_shared::v8::ActorError { @@ -234,7 +228,7 @@ impl GetPowerTable { let id = miner.id().map_err(map_err)?; let ok = s.miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v9(&ctx.chain_config().policy), + &policy.into(), &db, &miner.into(), )?; @@ -277,7 +271,7 @@ impl GetPowerTable { let id = miner.id().map_err(map_err)?; let ok = s.miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v9(&ctx.chain_config().policy), + &policy.into(), &db, &miner.into(), )?; @@ -319,11 +313,8 @@ impl GetPowerTable { } let id = miner.id().map_err(map_err)?; - let (_, ok) = s.miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v10(&ctx.chain_config().policy), - &db, - id, - )?; + let (_, ok) = + s.miner_nominal_power_meets_consensus_minimum(&policy.into(), &db, id)?; if !ok { return Ok(()); } @@ -362,11 +353,8 @@ impl GetPowerTable { } let id = miner.id().map_err(map_err)?; - let (_, ok) = s.miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v11(&ctx.chain_config().policy), - &db, - id, - )?; + let (_, ok) = + s.miner_nominal_power_meets_consensus_minimum(&policy.into(), &db, id)?; if !ok { return Ok(()); } @@ -390,58 +378,22 @@ impl GetPowerTable { })?; } power::State::V12(s) => { - handle_miner_state_v12_on!( - v12, - id_power_worker_mappings, - &ts, - s, - &from_policy_v13_to_v12(&ctx.chain_config().policy) - ); + handle_miner_state_v12_on!(v12, id_power_worker_mappings, &ts, s, &policy.into()); } power::State::V13(s) => { - handle_miner_state_v12_on!( - v13, - id_power_worker_mappings, - &ts, - s, - &ctx.chain_config().policy - ); + handle_miner_state_v12_on!(v13, id_power_worker_mappings, &ts, s, &policy.into()); } power::State::V14(s) => { - handle_miner_state_v12_on!( - v14, - id_power_worker_mappings, - &ts, - s, - &from_policy_v13_to_v14(&ctx.chain_config().policy) - ); + handle_miner_state_v12_on!(v14, id_power_worker_mappings, &ts, s, &policy.into()); } power::State::V15(s) => { - handle_miner_state_v12_on!( - v15, - id_power_worker_mappings, - &ts, - s, - &from_policy_v13_to_v15(&ctx.chain_config().policy) - ); + handle_miner_state_v12_on!(v15, id_power_worker_mappings, &ts, s, &policy.into()); } power::State::V16(s) => { - handle_miner_state_v12_on!( - v16, - id_power_worker_mappings, - &ts, - s, - &from_policy_v13_to_v16(&ctx.chain_config().policy) - ); + handle_miner_state_v12_on!(v16, id_power_worker_mappings, &ts, s, &policy.into()); } power::State::V17(s) => { - handle_miner_state_v12_on!( - v17, - id_power_worker_mappings, - &ts, - s, - &from_policy_v13_to_v17(&ctx.chain_config().policy) - ); + handle_miner_state_v12_on!(v17, id_power_worker_mappings, &ts, s, &policy.into()); } } let mut power_entries = vec![]; diff --git a/src/rpc/methods/msig.rs b/src/rpc/methods/msig.rs index 1c6fae5a700e..a9d97f5a68fb 100644 --- a/src/rpc/methods/msig.rs +++ b/src/rpc/methods/msig.rs @@ -7,7 +7,6 @@ use crate::rpc::types::*; use crate::rpc::{ApiPaths, Ctx, Permission, RpcMethod}; use crate::shim::actors::MultisigActorStateLoad as _; use crate::shim::actors::multisig; -use crate::shim::actors::multisig::ext::MultisigExt; use crate::shim::{address::Address, econ::TokenAmount}; use enumflags2::BitFlags; use fvm_ipld_blockstore::Blockstore; @@ -35,7 +34,7 @@ impl RpcMethod<2> for MsigGetAvailableBalance { .get_required_actor(&address, *ts.parent_state())?; let actor_balance = TokenAmount::from(&actor.balance); let ms = multisig::State::load(ctx.store(), actor.code, actor.state)?; - let locked_balance: TokenAmount = ms.locked_balance(height)?.into(); + let locked_balance = ms.locked_balance(height)?; let avail_balance = &actor_balance - locked_balance; Ok(avail_balance) } @@ -62,14 +61,14 @@ impl RpcMethod<2> for MsigGetPending { .get_actor_state_from_address(&ts, &address)?; let txns = ms .get_pending_txn(ctx.store())? - .iter() + .into_iter() .map(|txn| Transaction { id: txn.id, - to: txn.to.into(), - value: txn.value.clone().into(), + to: txn.to, + value: txn.value, method: txn.method, - params: txn.params.clone(), - approved: txn.approved.iter().map(|item| item.into()).collect(), + params: txn.params, + approved: txn.approved, }) .collect(); Ok(txns) @@ -107,8 +106,8 @@ impl RpcMethod<3> for MsigGetVested { let ms: multisig::State = ctx .state_manager .get_actor_state_from_address(&end_ts, &addr)?; - let start_lb: TokenAmount = ms.locked_balance(start_ts.epoch())?.into(); - let end_lb: TokenAmount = ms.locked_balance(end_ts.epoch())?.into(); + let start_lb = ms.locked_balance(start_ts.epoch())?; + let end_lb = ms.locked_balance(end_ts.epoch())?; Ok(start_lb.atto() - end_lb.atto()) } } diff --git a/src/rpc/methods/state.rs b/src/rpc/methods/state.rs index 8cf78199056e..5b27db5121e5 100644 --- a/src/rpc/methods/state.rs +++ b/src/rpc/methods/state.rs @@ -28,8 +28,7 @@ use crate::shim::actors::{ power, reward, verifreg, }; use crate::shim::actors::{ - market::ext::BalanceTableExt as _, - miner::ext::{MinerStateExt as _, PartitionExt as _}, + market::ext::BalanceTableExt as _, miner::ext::MinerStateExt as _, power::ext::PowerStateExt as _, }; use crate::shim::address::Payload; @@ -274,7 +273,7 @@ impl RpcMethod<2> for StateVerifierStatus { let ts = ctx.chain_store().load_required_tipset_or_heaviest(&tsk)?; let aid = ctx.state_manager.lookup_required_id(&address, &ts)?; let verifreg_state: verifreg::State = ctx.state_manager.get_actor_state(&ts)?; - Ok(verifreg_state.verifier_data_cap(ctx.store(), aid.into())?) + Ok(verifreg_state.verifier_data_cap(ctx.store(), aid)?) } } diff --git a/src/shim/actors/builtin/account/mod.rs b/src/shim/actors/builtin/account/mod.rs index 2cc183f7d38c..3cf5b84af483 100644 --- a/src/shim/actors/builtin/account/mod.rs +++ b/src/shim/actors/builtin/account/mod.rs @@ -1,7 +1,6 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use super::super::convert::{from_address_v3_to_v2, from_address_v4_to_v2}; use crate::shim::{self, address::Address}; use serde::Serialize; use spire_enum::prelude::delegated_enum; diff --git a/src/shim/actors/builtin/datacap/mod.rs b/src/shim/actors/builtin/datacap/mod.rs index 84339c5c2d6e..76223f8d5c6b 100644 --- a/src/shim/actors/builtin/datacap/mod.rs +++ b/src/shim/actors/builtin/datacap/mod.rs @@ -1,15 +1,16 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT +use crate::shim::address::{Address, Payload}; use anyhow::anyhow; use fil_actor_datacap_state::v12::DATACAP_GRANULARITY; use fil_actors_shared::ext::TokenStateExt; use fil_actors_shared::frc46_token::token::state::TokenState; use fvm_ipld_blockstore::Blockstore; -use fvm_shared2::address::{Address, Payload}; use num::BigInt; use num::traits::Euclid; use serde::Serialize; +use spire_enum::prelude::delegated_enum; /// Datacap actor method. pub type Method = fil_actor_datacap_state::v10::Method; @@ -18,6 +19,7 @@ pub type Method = fil_actor_datacap_state::v10::Method; pub const ADDRESS: Address = Address::new_id(7); /// Datacap actor state. +#[delegated_enum(impl_conversions)] #[derive(Serialize, Debug)] #[serde(untagged)] pub enum State { @@ -53,18 +55,7 @@ impl State { Payload::ID(id) => Ok(*id), _ => Err(anyhow!("can only look up ID addresses")), }?; - - let int = match self { - State::V9(state) => state.token.get_balance_opt(store, id), - State::V11(state) => state.token.get_balance_opt(store, id), - State::V12(state) => state.token.get_balance_opt(store, id), - State::V13(state) => state.token.get_balance_opt(store, id), - State::V14(state) => state.token.get_balance_opt(store, id), - State::V15(state) => state.token.get_balance_opt(store, id), - State::V16(state) => state.token.get_balance_opt(store, id), - State::V17(state) => state.token.get_balance_opt(store, id), - _ => return Err(anyhow!("not supported in actors > v8")), - }?; + let int = delegate_state!(self.token.get_balance_opt(store, id)?); Ok(int .map(|amount| amount.atto().to_owned()) .map(|opt| opt.div_euclid(&BigInt::from(DATACAP_GRANULARITY)))) diff --git a/src/shim/actors/builtin/evm/mod.rs b/src/shim/actors/builtin/evm/mod.rs index 52a26c692fe0..a8cca3e8309a 100644 --- a/src/shim/actors/builtin/evm/mod.rs +++ b/src/shim/actors/builtin/evm/mod.rs @@ -6,11 +6,13 @@ use ::cid::Cid; use fil_actor_evm_state::v17::{BytecodeHash, Tombstone, TransientData}; use fvm_shared2::address::Address; use serde::Serialize; +use spire_enum::prelude::delegated_enum; /// EVM actor method. pub type Method = fil_actor_evm_state::v10::Method; /// EVM actor state. +#[delegated_enum(impl_conversions)] #[derive(Serialize, Debug)] #[serde(untagged)] pub enum State { @@ -44,32 +46,15 @@ impl State { } pub fn nonce(&self) -> u64 { - match self { - State::V10(st) => st.nonce, - State::V11(st) => st.nonce, - State::V12(st) => st.nonce, - State::V13(st) => st.nonce, - State::V14(st) => st.nonce, - State::V15(st) => st.nonce, - State::V16(st) => st.nonce, - State::V17(st) => st.nonce, - } + delegate_state!(self.nonce) } pub fn is_alive(&self) -> bool { - match self { - State::V10(st) => st.tombstone.is_none(), - State::V11(st) => st.tombstone.is_none(), - State::V12(st) => st.tombstone.is_none(), - State::V13(st) => st.tombstone.is_none(), - State::V14(st) => st.tombstone.is_none(), - State::V15(st) => st.tombstone.is_none(), - State::V16(st) => st.tombstone.is_none(), - State::V17(st) => st.tombstone.is_none(), - } + delegate_state!(self.tombstone.is_none()) } } +#[delegated_enum(impl_conversions)] #[derive(Serialize, Debug, Clone)] #[serde(untagged)] pub enum TombstoneState { diff --git a/src/shim/actors/builtin/init/mod.rs b/src/shim/actors/builtin/init/mod.rs index f6ae9814a8f6..eb9d3e72e819 100644 --- a/src/shim/actors/builtin/init/mod.rs +++ b/src/shim/actors/builtin/init/mod.rs @@ -3,6 +3,7 @@ use fvm_shared2::address::Address; use serde::Serialize; +use spire_enum::prelude::delegated_enum; /// Init actor address. pub const ADDRESS: Address = Address::new_id(1); @@ -11,6 +12,7 @@ pub const ADDRESS: Address = Address::new_id(1); pub type Method = fil_actor_init_state::v8::Method; /// Init actor state. +#[delegated_enum(impl_conversions)] #[derive(Serialize, Debug)] #[serde(untagged)] pub enum State { @@ -41,18 +43,6 @@ impl State { } pub fn into_network_name(self) -> String { - match self { - State::V0(st) => st.network_name, - State::V8(st) => st.network_name, - State::V9(st) => st.network_name, - State::V10(st) => st.network_name, - State::V11(st) => st.network_name, - State::V12(st) => st.network_name, - State::V13(st) => st.network_name, - State::V14(st) => st.network_name, - State::V15(st) => st.network_name, - State::V16(st) => st.network_name, - State::V17(st) => st.network_name, - } + delegate_state!(self.network_name) } } diff --git a/src/shim/actors/builtin/market/mod.rs b/src/shim/actors/builtin/market/mod.rs index a1d3402ca091..fc827e3bf771 100644 --- a/src/shim/actors/builtin/market/mod.rs +++ b/src/shim/actors/builtin/market/mod.rs @@ -3,17 +3,7 @@ pub mod ext; -use crate::shim::{ - actors::convert::{ - from_address_v2_to_v3, from_address_v2_to_v4, from_address_v3_to_v2, from_address_v4_to_v2, - from_padded_piece_size_v3_to_v2, from_padded_piece_size_v4_to_v2, from_token_v3_to_v2, - from_token_v4_to_v2, - }, - address::Address, - clock::ChainEpoch, - econ::TokenAmount, - piece::PaddedPieceSize, -}; +use crate::shim::{address::Address, clock::ChainEpoch, econ::TokenAmount, piece::PaddedPieceSize}; use cid::Cid; use fil_actor_market_state::v8::balance_table::BalanceTable as V8BalanceTable; use fil_actor_market_state::v9::DealArray as V9DealArray; @@ -185,10 +175,8 @@ impl State { BS: Blockstore, { match self { - // `get_proposal_array` does not exist for V8 - State::V8(_st) => anyhow::bail!("unimplemented"), - // `get_proposal_array` does not exist for V9 - State::V9(_st) => anyhow::bail!("unimplemented"), + // `get_proposal_array` does not exist for V8 and V9 + State::V8(_) | State::V9(_) => anyhow::bail!("unimplemented"), State::V10(st) => Ok(DealProposals::V10(st.get_proposal_array(store)?)), State::V11(st) => Ok(DealProposals::V11(st.get_proposal_array(store)?)), State::V12(st) => Ok(DealProposals::V12(st.get_proposal_array(store)?)), diff --git a/src/shim/actors/builtin/miner/ext/mod.rs b/src/shim/actors/builtin/miner/ext/mod.rs index 88563491568c..df78b929a76d 100644 --- a/src/shim/actors/builtin/miner/ext/mod.rs +++ b/src/shim/actors/builtin/miner/ext/mod.rs @@ -2,24 +2,20 @@ // SPDX-License-Identifier: Apache-2.0, MIT mod deadline; -mod partition; mod state; +use crate::rpc::types::SectorOnChainInfo; use crate::shim::{ - actors::{ - Policy, - miner::{Deadline, DeadlineInfo, State}, - }, + actors::miner::{Deadline, DeadlineInfo, State}, + clock::ChainEpoch, econ::TokenAmount, + runtime::Policy, }; +use crate::utils::db::CborStoreExt as _; use cid::Cid; use fil_actors_shared::fvm_ipld_bitfield::BitField; use fvm_ipld_blockstore::Blockstore; -use crate::rpc::types::{SectorOnChainInfo, SectorPreCommitOnChainInfo}; -use crate::shim::clock::ChainEpoch; -use crate::utils::db::CborStoreExt as _; - pub trait MinerStateExt { /// Loads sectors corresponding to the bitfield. If no bitfield is passed /// in, return all. @@ -28,29 +24,6 @@ pub trait MinerStateExt { store: &BS, sectors: Option<&BitField>, ) -> anyhow::Result>; - - /// Loads the allocated sector numbers - fn load_allocated_sector_numbers(&self, store: &BS) - -> anyhow::Result; - - /// Loads the precommit-on-chain info - fn load_precommit_on_chain_info( - &self, - store: &BS, - sector_number: u64, - ) -> anyhow::Result>; - - fn recorded_deadline_info(&self, policy: &Policy, current_epoch: ChainEpoch) -> DeadlineInfo; -} - -pub trait PartitionExt { - /// Terminated sectors - fn terminated(&self) -> &BitField; - - // Maps epochs sectors that expire in or before that epoch. - // An expiration may be an "on-time" scheduled expiration, or early "faulty" expiration. - // Keys are quantized to last-in-deadline epochs. - fn expirations_epochs(&self) -> Cid; } pub trait DeadlineExt { diff --git a/src/shim/actors/builtin/miner/ext/partition.rs b/src/shim/actors/builtin/miner/ext/partition.rs deleted file mode 100644 index 852da7a08e50..000000000000 --- a/src/shim/actors/builtin/miner/ext/partition.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2019-2026 ChainSafe Systems -// SPDX-License-Identifier: Apache-2.0, MIT - -use super::*; -use crate::shim::actors::miner::Partition; - -impl PartitionExt for Partition<'_> { - fn terminated(&self) -> &BitField { - match self { - Partition::V8(dl) => &dl.terminated, - Partition::V9(dl) => &dl.terminated, - Partition::V10(dl) => &dl.terminated, - Partition::V11(dl) => &dl.terminated, - Partition::V12(dl) => &dl.terminated, - Partition::V13(dl) => &dl.terminated, - Partition::V14(dl) => &dl.terminated, - Partition::V15(dl) => &dl.terminated, - Partition::V16(dl) => &dl.terminated, - Partition::V17(dl) => &dl.terminated, - } - } - - fn expirations_epochs(&self) -> Cid { - match self { - Partition::V8(dl) => dl.expirations_epochs, - Partition::V9(dl) => dl.expirations_epochs, - Partition::V10(dl) => dl.expirations_epochs, - Partition::V11(dl) => dl.expirations_epochs, - Partition::V12(dl) => dl.expirations_epochs, - Partition::V13(dl) => dl.expirations_epochs, - Partition::V14(dl) => dl.expirations_epochs, - Partition::V15(dl) => dl.expirations_epochs, - Partition::V16(dl) => dl.expirations_epochs, - Partition::V17(dl) => dl.expirations_epochs, - } - } -} diff --git a/src/shim/actors/builtin/miner/ext/state.rs b/src/shim/actors/builtin/miner/ext/state.rs index b311399cb7a3..f60bb97bf31d 100644 --- a/src/shim/actors/builtin/miner/ext/state.rs +++ b/src/shim/actors/builtin/miner/ext/state.rs @@ -1,12 +1,9 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use crate::shim::actors::{Policy, convert::*}; -use anyhow::Context as _; - -use crate::shim::clock::ChainEpoch; - use super::*; +use crate::shim::{actors::convert::*, clock::ChainEpoch, runtime::Policy}; +use anyhow::Context as _; impl MinerStateExt for State { fn load_sectors_ext( @@ -187,101 +184,4 @@ impl MinerStateExt for State { } } } - - fn load_allocated_sector_numbers( - &self, - store: &BS, - ) -> anyhow::Result { - let allocated_sectors = match self { - Self::V8(s) => s.allocated_sectors, - Self::V9(s) => s.allocated_sectors, - Self::V10(s) => s.allocated_sectors, - Self::V11(s) => s.allocated_sectors, - Self::V12(s) => s.allocated_sectors, - Self::V13(s) => s.allocated_sectors, - Self::V14(s) => s.allocated_sectors, - Self::V15(s) => s.allocated_sectors, - Self::V16(s) => s.allocated_sectors, - Self::V17(s) => s.allocated_sectors, - }; - store.get_cbor_required(&allocated_sectors) - } - - fn load_precommit_on_chain_info( - &self, - store: &BS, - sector_number: u64, - ) -> anyhow::Result> { - Ok(match self { - Self::V8(s) => s - .get_precommitted_sector(store, sector_number)? - .map(SectorPreCommitOnChainInfo::from), - Self::V9(s) => s - .get_precommitted_sector(store, sector_number)? - .map(SectorPreCommitOnChainInfo::from), - Self::V10(s) => s - .get_precommitted_sector(store, sector_number)? - .map(SectorPreCommitOnChainInfo::from), - Self::V11(s) => s - .get_precommitted_sector(store, sector_number)? - .map(SectorPreCommitOnChainInfo::from), - Self::V12(s) => s - .get_precommitted_sector(store, sector_number)? - .map(SectorPreCommitOnChainInfo::from), - Self::V13(s) => s - .get_precommitted_sector(store, sector_number)? - .map(SectorPreCommitOnChainInfo::from), - Self::V14(s) => s - .get_precommitted_sector(store, sector_number) - .context("precommit info does not exist")? - .map(SectorPreCommitOnChainInfo::from), - Self::V15(s) => s - .get_precommitted_sector(store, sector_number) - .context("precommit info does not exist")? - .map(SectorPreCommitOnChainInfo::from), - Self::V16(s) => s - .get_precommitted_sector(store, sector_number) - .context("precommit info does not exist")? - .map(SectorPreCommitOnChainInfo::from), - Self::V17(s) => s - .get_precommitted_sector(store, sector_number) - .context("precommit info does not exist")? - .map(SectorPreCommitOnChainInfo::from), - }) - } - - /// Returns deadline calculations for the state recorded proving period and deadline. - /// This is out of date if the a miner does not have an active miner cron - fn recorded_deadline_info(&self, policy: &Policy, current_epoch: ChainEpoch) -> DeadlineInfo { - match self { - State::V8(st) => st - .recorded_deadline_info(&from_policy_v13_to_v9(policy), current_epoch) - .into(), - State::V9(st) => st - .recorded_deadline_info(&from_policy_v13_to_v9(policy), current_epoch) - .into(), - State::V10(st) => st - .recorded_deadline_info(&from_policy_v13_to_v10(policy), current_epoch) - .into(), - State::V11(st) => st - .recorded_deadline_info(&from_policy_v13_to_v11(policy), current_epoch) - .into(), - State::V12(st) => st - .recorded_deadline_info(&from_policy_v13_to_v12(policy), current_epoch) - .into(), - State::V13(st) => st.recorded_deadline_info(policy, current_epoch).into(), - State::V14(st) => st - .recorded_deadline_info(&from_policy_v13_to_v14(policy), current_epoch) - .into(), - State::V15(st) => st - .recorded_deadline_info(&from_policy_v13_to_v15(policy), current_epoch) - .into(), - State::V16(st) => st - .recorded_deadline_info(&from_policy_v13_to_v16(policy), current_epoch) - .into(), - State::V17(st) => st - .recorded_deadline_info(&from_policy_v13_to_v17(policy), current_epoch) - .into(), - } - } } diff --git a/src/shim/actors/builtin/miner/mod.rs b/src/shim/actors/builtin/miner/mod.rs index 284448ce8557..1293069f7691 100644 --- a/src/shim/actors/builtin/miner/mod.rs +++ b/src/shim/actors/builtin/miner/mod.rs @@ -3,13 +3,18 @@ pub mod ext; -use crate::shim::{ - actors::{Policy, convert::*, power::Claim}, - address::Address, - clock::ChainEpoch, - deal::DealID, - econ::TokenAmount, - sector::SectorSize, +use crate::{ + rpc::types::SectorPreCommitOnChainInfo, + shim::{ + actors::{convert::*, power::Claim}, + address::Address, + clock::ChainEpoch, + deal::DealID, + econ::TokenAmount, + runtime::Policy, + sector::SectorSize, + }, + utils::db::CborStoreExt as _, }; use cid::Cid; use fil_actor_miner_state::v12::{BeneficiaryTerm, PendingBeneficiaryChange}; @@ -97,26 +102,22 @@ impl State { mut f: impl FnMut(u64, Deadline) -> Result<(), anyhow::Error>, ) -> anyhow::Result<()> { match self { - State::V8(st) => st.load_deadlines(&store)?.for_each( - &from_policy_v13_to_v9(policy), - &store, - |idx, dl| f(idx, dl.into()), - ), - State::V9(st) => st.load_deadlines(&store)?.for_each( - &from_policy_v13_to_v9(policy), - &store, - |idx, dl| f(idx, dl.into()), - ), - State::V10(st) => st.load_deadlines(&store)?.for_each( - &from_policy_v13_to_v10(policy), - &store, - |idx, dl| f(idx, dl.into()), - ), - State::V11(st) => st.load_deadlines(&store)?.for_each( - &from_policy_v13_to_v11(policy), - &store, - |idx, dl| f(idx, dl.into()), - ), + State::V8(st) => { + st.load_deadlines(&store)? + .for_each(&policy.into(), &store, |idx, dl| f(idx, dl.into())) + } + State::V9(st) => { + st.load_deadlines(&store)? + .for_each(&policy.into(), &store, |idx, dl| f(idx, dl.into())) + } + State::V10(st) => { + st.load_deadlines(&store)? + .for_each(&policy.into(), &store, |idx, dl| f(idx, dl.into())) + } + State::V11(st) => { + st.load_deadlines(&store)? + .for_each(&policy.into(), &store, |idx, dl| f(idx, dl.into())) + } State::V12(st) => st .load_deadlines(store)? .for_each(store, |idx, dl| f(idx, dl.into())), @@ -148,19 +149,19 @@ impl State { match self { State::V8(st) => Ok(st .load_deadlines(store)? - .load_deadline(&from_policy_v13_to_v9(policy), store, idx) + .load_deadline(&policy.into(), store, idx) .map(From::from)?), State::V9(st) => Ok(st .load_deadlines(store)? - .load_deadline(&from_policy_v13_to_v9(policy), store, idx) + .load_deadline(&policy.into(), store, idx) .map(From::from)?), State::V10(st) => Ok(st .load_deadlines(store)? - .load_deadline(&from_policy_v13_to_v10(policy), store, idx) + .load_deadline(&policy.into(), store, idx) .map(From::from)?), State::V11(st) => Ok(st .load_deadlines(store)? - .load_deadline(&from_policy_v13_to_v11(policy), store, idx) + .load_deadline(&policy.into(), store, idx) .map(From::from)?), State::V12(st) => Ok(st .load_deadlines(store)? @@ -378,10 +379,10 @@ impl State { policy: &Policy, ) -> anyhow::Result<(u64, u64)> { match self { - State::V8(st) => st.find_sector(&from_policy_v13_to_v9(policy), store, sector_number), - State::V9(st) => st.find_sector(&from_policy_v13_to_v9(policy), store, sector_number), - State::V10(st) => st.find_sector(&from_policy_v13_to_v10(policy), store, sector_number), - State::V11(st) => st.find_sector(&from_policy_v13_to_v11(policy), store, sector_number), + State::V8(st) => st.find_sector(&policy.into(), store, sector_number), + State::V9(st) => st.find_sector(&policy.into(), store, sector_number), + State::V10(st) => st.find_sector(&policy.into(), store, sector_number), + State::V11(st) => st.find_sector(&policy.into(), store, sector_number), State::V12(st) => st.find_sector(store, sector_number), State::V13(st) => st.find_sector(store, sector_number), State::V14(st) => st.find_sector(store, sector_number), @@ -406,36 +407,44 @@ impl State { /// Returns deadline calculations for the current (according to state) proving period. pub fn deadline_info(&self, policy: &Policy, current_epoch: ChainEpoch) -> DeadlineInfo { - match self { - State::V8(st) => st - .deadline_info(&from_policy_v13_to_v9(policy), current_epoch) - .into(), - State::V9(st) => st - .deadline_info(&from_policy_v13_to_v9(policy), current_epoch) - .into(), - State::V10(st) => st - .deadline_info(&from_policy_v13_to_v10(policy), current_epoch) - .into(), - State::V11(st) => st - .deadline_info(&from_policy_v13_to_v11(policy), current_epoch) - .into(), - State::V12(st) => st - .deadline_info(&from_policy_v13_to_v12(policy), current_epoch) - .into(), - State::V13(st) => st.deadline_info(policy, current_epoch).into(), - State::V14(st) => st - .deadline_info(&from_policy_v13_to_v14(policy), current_epoch) - .into(), - State::V15(st) => st - .deadline_info(&from_policy_v13_to_v15(policy), current_epoch) - .into(), - State::V16(st) => st - .deadline_info(&from_policy_v13_to_v16(policy), current_epoch) - .into(), - State::V17(st) => st - .deadline_info(&from_policy_v13_to_v17(policy), current_epoch) - .into(), - } + delegate_state!(self.deadline_info(&policy.into(), current_epoch).into()) + } + + pub fn allocated_sectors(&self) -> Cid { + delegate_state!(self.allocated_sectors) + } + + /// Loads the allocated sector numbers + pub fn load_allocated_sector_numbers( + &self, + store: &BS, + ) -> anyhow::Result { + store.get_cbor_required(&self.allocated_sectors()) + } + + /// Loads the precommit-on-chain info + pub fn load_precommit_on_chain_info( + &self, + store: &BS, + sector_number: u64, + ) -> anyhow::Result> { + Ok(delegate_state!( + self.get_precommitted_sector(store, sector_number)? + .map(From::from) + )) + } + + /// Returns deadline calculations for the state recorded proving period and deadline. + /// This is out of date if the a miner does not have an active miner cron + pub fn recorded_deadline_info( + &self, + policy: &Policy, + current_epoch: ChainEpoch, + ) -> DeadlineInfo { + delegate_state!( + self.recorded_deadline_info(&policy.into(), current_epoch) + .into() + ) } } @@ -922,6 +931,18 @@ impl Partition<'_> { pub fn recovering_sectors(&self) -> &BitField { delegate_partition!(self.recoveries.borrow()) } + + /// Terminated sectors + pub fn terminated(&self) -> &BitField { + delegate_partition!(self.terminated.borrow()) + } + + // Maps epochs sectors that expire in or before that epoch. + // An expiration may be an "on-time" scheduled expiration, or early "faulty" expiration. + // Keys are quantized to last-in-deadline epochs. + pub fn expirations_epochs(&self) -> Cid { + delegate_partition!(self.expirations_epochs) + } } #[derive(Serialize)] diff --git a/src/shim/actors/builtin/multisig/ext/mod.rs b/src/shim/actors/builtin/multisig/ext/mod.rs deleted file mode 100644 index bd508258f579..000000000000 --- a/src/shim/actors/builtin/multisig/ext/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2019-2026 ChainSafe Systems -// SPDX-License-Identifier: Apache-2.0, MIT - -mod state; - -use crate::rpc::types::MsigVesting; -use crate::shim::actors::multisig::State; - -pub trait MultisigExt { - fn get_vesting_schedule(&self) -> anyhow::Result; -} diff --git a/src/shim/actors/builtin/multisig/ext/state.rs b/src/shim/actors/builtin/multisig/ext/state.rs deleted file mode 100644 index 9b04ad4fe44a..000000000000 --- a/src/shim/actors/builtin/multisig/ext/state.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2019-2026 ChainSafe Systems -// SPDX-License-Identifier: Apache-2.0, MIT - -use super::*; - -impl MultisigExt for State { - fn get_vesting_schedule(&self) -> anyhow::Result { - match self { - State::V8(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - State::V9(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - State::V10(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - State::V11(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - State::V12(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - State::V13(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - State::V14(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - State::V15(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - State::V16(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - State::V17(st) => Ok(MsigVesting { - initial_balance: st.initial_balance.atto().clone(), - start_epoch: st.start_epoch, - unlock_duration: st.unlock_duration, - }), - } - } -} diff --git a/src/shim/actors/builtin/multisig/mod.rs b/src/shim/actors/builtin/multisig/mod.rs index d6281f043904..ad60302056c1 100644 --- a/src/shim/actors/builtin/multisig/mod.rs +++ b/src/shim/actors/builtin/multisig/mod.rs @@ -1,20 +1,23 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -pub mod ext; - -use crate::shim::actors::convert::{ - from_address_v3_to_v2, from_address_v4_to_v2, from_token_v3_to_v2, from_token_v4_to_v2, +use super::super::macros::{ + parse_pending_transactions, parse_pending_transactions_v3, parse_pending_transactions_v4, +}; +use crate::{ + rpc::types::MsigVesting, + shim::{MethodNum, address::Address, clock::ChainEpoch, econ::TokenAmount}, }; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::RawBytes; -use fvm_shared2::{MethodNum, address::Address, clock::ChainEpoch, econ::TokenAmount}; use serde::{Deserialize, Serialize}; +use spire_enum::prelude::delegated_enum; /// Multisig actor method. pub type Method = fil_actor_multisig_state::v8::Method; /// Multisig actor state. +#[delegated_enum(impl_conversions)] #[derive(Serialize, Debug)] #[serde(untagged)] pub enum State { @@ -64,18 +67,7 @@ impl State { /// Returns amount locked in multisig contract pub fn locked_balance(&self, height: ChainEpoch) -> anyhow::Result { - Ok(match self { - State::V8(st) => st.amount_locked(height - st.start_epoch), - State::V9(st) => st.amount_locked(height - st.start_epoch), - State::V10(st) => from_token_v3_to_v2(&st.amount_locked(height - st.start_epoch)), - State::V11(st) => from_token_v3_to_v2(&st.amount_locked(height - st.start_epoch)), - State::V12(st) => from_token_v4_to_v2(&st.amount_locked(height - st.start_epoch)), - State::V13(st) => from_token_v4_to_v2(&st.amount_locked(height - st.start_epoch)), - State::V14(st) => from_token_v4_to_v2(&st.amount_locked(height - st.start_epoch)), - State::V15(st) => from_token_v4_to_v2(&st.amount_locked(height - st.start_epoch)), - State::V16(st) => from_token_v4_to_v2(&st.amount_locked(height - st.start_epoch)), - State::V17(st) => from_token_v4_to_v2(&st.amount_locked(height - st.start_epoch)), - }) + Ok(delegate_state!(self => |st| st.amount_locked(height - st.start_epoch).into())) } /// Returns pending transactions for the given multisig wallet @@ -87,7 +79,7 @@ impl State { BS, fil_actor_multisig_state::v8::Transaction, >(&st.pending_txs, store)?; - crate::parse_pending_transactions!(res, txns); + parse_pending_transactions!(res, txns); Ok(res) } State::V9(st) => { @@ -95,7 +87,7 @@ impl State { BS, fil_actor_multisig_state::v9::Transaction, >(&st.pending_txs, store)?; - crate::parse_pending_transactions!(res, txns); + parse_pending_transactions!(res, txns); Ok(res) } State::V10(st) => { @@ -103,7 +95,7 @@ impl State { BS, fil_actor_multisig_state::v10::Transaction, >(&st.pending_txs, store)?; - crate::parse_pending_transactions_v3!(res, txns); + parse_pending_transactions_v3!(res, txns); Ok(res) } State::V11(st) => { @@ -111,7 +103,7 @@ impl State { BS, fil_actor_multisig_state::v11::Transaction, >(&st.pending_txs, store)?; - crate::parse_pending_transactions_v3!(res, txns); + parse_pending_transactions_v3!(res, txns); Ok(res) } State::V12(st) => { @@ -122,7 +114,7 @@ impl State { "pending txns", ) .expect("Could not load pending transactions"); - crate::parse_pending_transactions_v4!(res, txns); + parse_pending_transactions_v4!(res, txns); Ok(res) } State::V13(st) => { @@ -133,7 +125,7 @@ impl State { "pending txns", ) .expect("Could not load pending transactions"); - crate::parse_pending_transactions_v4!(res, txns); + parse_pending_transactions_v4!(res, txns); Ok(res) } State::V14(st) => { @@ -144,7 +136,7 @@ impl State { "pending txns", ) .expect("Could not load pending transactions"); - crate::parse_pending_transactions_v4!(res, txns); + parse_pending_transactions_v4!(res, txns); Ok(res) } State::V15(st) => { @@ -155,7 +147,7 @@ impl State { "pending txns", ) .expect("Could not load pending transactions"); - crate::parse_pending_transactions_v4!(res, txns); + parse_pending_transactions_v4!(res, txns); Ok(res) } State::V16(st) => { @@ -166,7 +158,7 @@ impl State { "pending txns", ) .expect("Could not load pending transactions"); - crate::parse_pending_transactions_v4!(res, txns); + parse_pending_transactions_v4!(res, txns); Ok(res) } State::V17(st) => { @@ -177,9 +169,18 @@ impl State { "pending txns", ) .expect("Could not load pending transactions"); - crate::parse_pending_transactions_v4!(res, txns); + parse_pending_transactions_v4!(res, txns); Ok(res) } } } + + /// Returns the vesting schedule for this multisig state. + pub fn get_vesting_schedule(&self) -> anyhow::Result { + Ok(delegate_state!(self => |st| MsigVesting { + initial_balance: st.initial_balance.atto().clone(), + start_epoch: st.start_epoch, + unlock_duration: st.unlock_duration, + })) + } } diff --git a/src/shim/actors/builtin/power/mod.rs b/src/shim/actors/builtin/power/mod.rs index 7dac8dbbf257..8de745f65627 100644 --- a/src/shim/actors/builtin/power/mod.rs +++ b/src/shim/actors/builtin/power/mod.rs @@ -5,9 +5,10 @@ pub mod ext; use crate::list_miners_for_state; use crate::shim::{ - actors::{FilterEstimate, Policy, convert::*}, + actors::{FilterEstimate, convert::*}, address::Address, econ::TokenAmount, + runtime::Policy, sector::StoragePower, }; use fvm_ipld_blockstore::Blockstore; @@ -160,18 +161,7 @@ impl State { /// Consume state to return total locked funds pub fn into_total_locked(self) -> TokenAmount { - match self { - State::V8(st) => st.into_total_locked().into(), - State::V9(st) => st.into_total_locked().into(), - State::V10(st) => st.into_total_locked().into(), - State::V11(st) => st.into_total_locked().into(), - State::V12(st) => st.into_total_locked().into(), - State::V13(st) => st.into_total_locked().into(), - State::V14(st) => st.into_total_locked().into(), - State::V15(st) => st.into_total_locked().into(), - State::V16(st) => st.into_total_locked().into(), - State::V17(st) => st.into_total_locked().into(), - } + delegate_state!(self.into_total_locked().into()) } /// Loads power for a given miner, if exists. @@ -191,74 +181,42 @@ impl State { miner: &Address, ) -> anyhow::Result { match self { - State::V8(st) => st.miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v9(policy), - &s, - &miner.into(), - ), - State::V9(st) => st.miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v9(policy), - &s, - &miner.into(), - ), + State::V8(st) => { + st.miner_nominal_power_meets_consensus_minimum(&policy.into(), &s, &miner.into()) + } + State::V9(st) => { + st.miner_nominal_power_meets_consensus_minimum(&policy.into(), &s, &miner.into()) + } State::V10(st) => st - .miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v10(policy), - &s, - miner.id()?, - ) + .miner_nominal_power_meets_consensus_minimum(&policy.into(), &s, miner.id()?) .map(|(_, bool_val)| bool_val) .map_err(|e| anyhow::anyhow!("{}", e)), State::V11(st) => st - .miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v11(policy), - &s, - miner.id()?, - ) + .miner_nominal_power_meets_consensus_minimum(&policy.into(), &s, miner.id()?) .map(|(_, bool_val)| bool_val) .map_err(|e| anyhow::anyhow!("{}", e)), State::V12(st) => st - .miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v12(policy), - &s, - miner.id()?, - ) + .miner_nominal_power_meets_consensus_minimum(&policy.into(), &s, miner.id()?) .map(|(_, bool_val)| bool_val) .map_err(|e| anyhow::anyhow!("{}", e)), State::V13(st) => st - .miner_nominal_power_meets_consensus_minimum(policy, &s, miner.id()?) + .miner_nominal_power_meets_consensus_minimum(&policy.0, &s, miner.id()?) .map(|(_, bool_val)| bool_val) .map_err(|e| anyhow::anyhow!("{}", e)), State::V14(st) => st - .miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v14(policy), - &s, - miner.id()?, - ) + .miner_nominal_power_meets_consensus_minimum(&policy.into(), &s, miner.id()?) .map(|(_, bool_val)| bool_val) .map_err(|e| anyhow::anyhow!("{}", e)), State::V15(st) => st - .miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v15(policy), - &s, - miner.id()?, - ) + .miner_nominal_power_meets_consensus_minimum(&policy.into(), &s, miner.id()?) .map(|(_, bool_val)| bool_val) .map_err(|e| anyhow::anyhow!("{}", e)), State::V16(st) => st - .miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v16(policy), - &s, - miner.id()?, - ) + .miner_nominal_power_meets_consensus_minimum(&policy.into(), &s, miner.id()?) .map(|(_, bool_val)| bool_val) .map_err(|e| anyhow::anyhow!("{}", e)), State::V17(st) => st - .miner_nominal_power_meets_consensus_minimum( - &from_policy_v13_to_v17(policy), - &s, - miner.id()?, - ) + .miner_nominal_power_meets_consensus_minimum(&policy.into(), &s, miner.id()?) .map(|(_, bool_val)| bool_val) .map_err(|e| anyhow::anyhow!("{}", e)), } @@ -302,18 +260,7 @@ impl State { /// Returns total locked funds pub fn total_locked(&self) -> TokenAmount { - match self { - State::V8(st) => st.total_pledge_collateral.clone().into(), - State::V9(st) => st.total_pledge_collateral.clone().into(), - State::V10(st) => st.total_pledge_collateral.clone().into(), - State::V11(st) => st.total_pledge_collateral.clone().into(), - State::V12(st) => st.total_pledge_collateral.clone().into(), - State::V13(st) => st.total_pledge_collateral.clone().into(), - State::V14(st) => st.total_pledge_collateral.clone().into(), - State::V15(st) => st.total_pledge_collateral.clone().into(), - State::V16(st) => st.total_pledge_collateral.clone().into(), - State::V17(st) => st.total_pledge_collateral.clone().into(), - } + delegate_state!(self.total_pledge_collateral.clone().into()) } } diff --git a/src/shim/actors/builtin/reward/mod.rs b/src/shim/actors/builtin/reward/mod.rs index aec86ddaec69..d824a7f9effa 100644 --- a/src/shim/actors/builtin/reward/mod.rs +++ b/src/shim/actors/builtin/reward/mod.rs @@ -2,14 +2,8 @@ // SPDX-License-Identifier: Apache-2.0, MIT use crate::shim::{ - actors::convert::{ - from_padded_piece_size_v2_to_v3, from_padded_piece_size_v2_to_v4, from_policy_v13_to_v11, - from_policy_v13_to_v12, from_policy_v13_to_v14, from_policy_v13_to_v15, - from_policy_v13_to_v16, from_policy_v13_to_v17, from_token_v2_to_v3, from_token_v2_to_v4, - from_token_v3_to_v2, from_token_v4_to_v2, - }, - econ::TokenAmount, - piece::PaddedPieceSize, + address::Address, econ::TokenAmount, piece::PaddedPieceSize, runtime::Policy, + sector::StoragePower, }; use fil_actor_market_state::v11::policy::deal_provider_collateral_bounds as deal_provider_collateral_bounds_v11; use fil_actor_market_state::v12::policy::deal_provider_collateral_bounds as deal_provider_collateral_bounds_v12; @@ -26,16 +20,14 @@ use fil_actor_miner_state::v15::initial_pledge_for_power as initial_pledge_for_p use fil_actor_miner_state::v16::initial_pledge_for_power as initial_pledge_for_power_v16; use fil_actor_miner_state::v17::initial_pledge_for_power as initial_pledge_for_power_v17; use fvm_shared2::TOTAL_FILECOIN; -use fvm_shared2::address::Address; use fvm_shared2::bigint::Integer; -use fvm_shared2::sector::StoragePower; use fvm_shared2::smooth::FilterEstimate; use num::BigInt; use serde::Serialize; +use spire_enum::prelude::delegated_enum; +use std::borrow::Borrow as _; use std::cmp::max; -use crate::shim::actors::Policy; - /// Reward actor address pub const ADDRESS: Address = Address::new_id(2); @@ -43,6 +35,7 @@ pub const ADDRESS: Address = Address::new_id(2); pub type Method = fil_actor_reward_state::v8::Method; /// Reward actor state. +#[delegated_enum(impl_conversions)] #[derive(Serialize, Debug)] #[serde(untagged)] pub enum State { @@ -90,34 +83,12 @@ impl State { /// Consume state to return just storage power reward pub fn into_total_storage_power_reward(self) -> TokenAmount { - match self { - State::V8(st) => st.into_total_storage_power_reward().into(), - State::V9(st) => st.into_total_storage_power_reward().into(), - State::V10(st) => st.into_total_storage_power_reward().into(), - State::V11(st) => st.into_total_storage_power_reward().into(), - State::V12(st) => st.into_total_storage_power_reward().into(), - State::V13(st) => st.into_total_storage_power_reward().into(), - State::V14(st) => st.into_total_storage_power_reward().into(), - State::V15(st) => st.into_total_storage_power_reward().into(), - State::V16(st) => st.into_total_storage_power_reward().into(), - State::V17(st) => st.into_total_storage_power_reward().into(), - } + delegate_state!(self.into_total_storage_power_reward().into()) } /// The baseline power the network is targeting at this state's epoch. pub fn this_epoch_baseline_power(&self) -> &StoragePower { - match self { - State::V8(st) => &st.this_epoch_baseline_power, - State::V9(st) => &st.this_epoch_baseline_power, - State::V10(st) => &st.this_epoch_baseline_power, - State::V11(st) => &st.this_epoch_baseline_power, - State::V12(st) => &st.this_epoch_baseline_power, - State::V13(st) => &st.this_epoch_baseline_power, - State::V14(st) => &st.this_epoch_baseline_power, - State::V15(st) => &st.this_epoch_baseline_power, - State::V16(st) => &st.this_epoch_baseline_power, - State::V17(st) => &st.this_epoch_baseline_power, - } + delegate_state!(self.this_epoch_baseline_power.borrow()) } pub fn pre_commit_deposit_for_power( @@ -256,7 +227,7 @@ impl State { ), State::V11(_) => { let (min, max) = deal_provider_collateral_bounds_v11( - &from_policy_v13_to_v11(policy), + &policy.into(), size.into(), raw_byte_power, baseline_power, @@ -266,7 +237,7 @@ impl State { } State::V12(_) => { let (min, max) = deal_provider_collateral_bounds_v12( - &from_policy_v13_to_v12(policy), + &policy.into(), size.into(), raw_byte_power, baseline_power, @@ -276,7 +247,7 @@ impl State { } State::V13(_) => { let (min, max) = deal_provider_collateral_bounds_v13( - policy, + &policy.0, size.into(), raw_byte_power, baseline_power, @@ -286,7 +257,7 @@ impl State { } State::V14(_) => { let (min, max) = deal_provider_collateral_bounds_v14( - &from_policy_v13_to_v14(policy), + &policy.into(), size.into(), raw_byte_power, baseline_power, @@ -296,7 +267,7 @@ impl State { } State::V15(_) => { let (min, max) = deal_provider_collateral_bounds_v15( - &from_policy_v13_to_v15(policy), + &policy.into(), size.into(), raw_byte_power, baseline_power, @@ -306,7 +277,7 @@ impl State { } State::V16(_) => { let (min, max) = deal_provider_collateral_bounds_v16( - &from_policy_v13_to_v16(policy), + &policy.into(), size.into(), raw_byte_power, baseline_power, @@ -316,7 +287,7 @@ impl State { } State::V17(_) => { let (min, max) = deal_provider_collateral_bounds_v17( - &from_policy_v13_to_v17(policy), + &policy.into(), size.into(), raw_byte_power, baseline_power, diff --git a/src/shim/actors/builtin/system/mod.rs b/src/shim/actors/builtin/system/mod.rs index fee1d28d561a..d77e63bea674 100644 --- a/src/shim/actors/builtin/system/mod.rs +++ b/src/shim/actors/builtin/system/mod.rs @@ -4,6 +4,8 @@ use cid::Cid; use fvm_shared2::address::Address; use serde::Serialize; +use spire_enum::prelude::delegated_enum; +use std::borrow::Borrow as _; /// System actor address. pub const ADDRESS: Address = Address::new_id(0); @@ -12,6 +14,7 @@ pub const ADDRESS: Address = Address::new_id(0); pub type Method = fil_actor_system_state::v8::Method; /// System actor state. +#[delegated_enum(impl_conversions)] #[derive(Serialize, Debug)] #[serde(untagged)] pub enum State { @@ -34,17 +37,6 @@ impl State { /// Returns the builtin actors Cid. pub fn builtin_actors_cid(&self) -> &Cid { - match self { - State::V8(s) => &s.builtin_actors, - State::V9(s) => &s.builtin_actors, - State::V10(s) => &s.builtin_actors, - State::V11(s) => &s.builtin_actors, - State::V12(s) => &s.builtin_actors, - State::V13(s) => &s.builtin_actors, - State::V14(s) => &s.builtin_actors, - State::V15(s) => &s.builtin_actors, - State::V16(s) => &s.builtin_actors, - State::V17(s) => &s.builtin_actors, - } + delegate_state!(self.builtin_actors.borrow()) } } diff --git a/src/shim/actors/builtin/verifreg/ext/mod.rs b/src/shim/actors/builtin/verifreg/ext/mod.rs index 956df2827e46..be7142c78626 100644 --- a/src/shim/actors/builtin/verifreg/ext/mod.rs +++ b/src/shim/actors/builtin/verifreg/ext/mod.rs @@ -29,6 +29,4 @@ pub trait VerifiedRegistryStateExt { fn get_all_claims(&self, store: &BS) -> anyhow::Result>; - - fn root_key(&self) -> Address; } diff --git a/src/shim/actors/builtin/verifreg/ext/state.rs b/src/shim/actors/builtin/verifreg/ext/state.rs index 3858c8e21474..94e315cd7cdb 100644 --- a/src/shim/actors/builtin/verifreg/ext/state.rs +++ b/src/shim/actors/builtin/verifreg/ext/state.rs @@ -255,19 +255,4 @@ impl VerifiedRegistryStateExt for State { }; Ok(result) } - - fn root_key(&self) -> Address { - match self { - State::V8(s) => s.root_key.into(), - State::V9(s) => s.root_key.into(), - State::V10(s) => s.root_key.into(), - State::V11(s) => s.root_key.into(), - State::V12(s) => s.root_key.into(), - State::V13(s) => s.root_key.into(), - State::V14(s) => s.root_key.into(), - State::V15(s) => s.root_key.into(), - State::V16(s) => s.root_key.into(), - State::V17(s) => s.root_key.into(), - } - } } diff --git a/src/shim/actors/builtin/verifreg/mod.rs b/src/shim/actors/builtin/verifreg/mod.rs index 2065ef4f2a48..5ed3f47965d5 100644 --- a/src/shim/actors/builtin/verifreg/mod.rs +++ b/src/shim/actors/builtin/verifreg/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0, MIT pub mod ext; +use crate::shim::address::{Address, Protocol}; use anyhow::anyhow; use cid::Cid; use fil_actor_verifreg_state::v13::ClaimID; @@ -16,7 +17,6 @@ use fil_actors_shared::v8::{HAMT_BIT_WIDTH, make_map_with_root_and_bitwidth}; use fil_actors_shared::v9::Keyer; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::tuple::*; -use fvm_shared2::address::{Address, Protocol}; use fvm_shared4::ActorID; use fvm_shared4::bigint::bigint_ser::BigIntDe; use fvm_shared4::clock::ChainEpoch; @@ -24,11 +24,13 @@ use fvm_shared4::piece::PaddedPieceSize; use fvm_shared4::sector::SectorNumber; use num::BigInt; use serde::{Deserialize, Serialize}; +use spire_enum::prelude::delegated_enum; /// verifreg actor address. pub const ADDRESS: Address = Address::new_id(6); /// Verifreg actor state. +#[delegated_enum(impl_conversions)] #[derive(Serialize, Debug)] #[serde(untagged)] pub enum State { @@ -82,7 +84,9 @@ impl State { store, HAMT_BIT_WIDTH, )?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) + Ok(vh + .get(&fvm_shared2::address::Address::from(addr).key())? + .map(|int: &BigIntDe| int.0.to_owned())) } _ => Err(anyhow!("not supported in actors > v8")), } @@ -96,48 +100,11 @@ impl State { return Err(anyhow!("can only look up ID addresses")); } - match self { - State::V8(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - State::V9(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - State::V10(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - State::V11(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - State::V12(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - State::V13(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - State::V14(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - State::V15(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - State::V16(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - State::V17(state) => { - let vh = make_map_with_root_and_bitwidth(&state.verifiers, store, HAMT_BIT_WIDTH)?; - Ok(vh.get(&addr.key())?.map(|int: &BigIntDe| int.0.to_owned())) - } - } + let key = fvm_shared2::address::Address::from(addr).key(); + delegate_state!(self => |st| { + let vh = make_map_with_root_and_bitwidth(&st.verifiers, store, HAMT_BIT_WIDTH)?; + Ok(vh.get(&key)?.map(|int: &BigIntDe| int.0.to_owned())) + }) } pub fn get_allocation( @@ -304,6 +271,11 @@ impl State { } } } + + /// Returns the root key address for this verifreg state. + pub fn root_key(&self) -> Address { + delegate_state!(self.root_key.into()) + } } #[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug, PartialEq, Eq)] diff --git a/src/shim/actors/convert.rs b/src/shim/actors/convert.rs index fa910a731d4a..bbd203bce4c6 100644 --- a/src/shim/actors/convert.rs +++ b/src/shim/actors/convert.rs @@ -39,27 +39,11 @@ use fvm_shared4::sector::SectorSize as SectorSizeV4; use num_bigint::BigInt; use num_traits::FromPrimitive; -pub fn from_padded_piece_size_v4_to_v2(size: PaddedPieceSizeV4) -> PaddedPieceSizeV2 { - PaddedPieceSizeV2(size.0) -} - -pub fn from_padded_piece_size_v3_to_v2(size: PaddedPieceSizeV3) -> PaddedPieceSizeV2 { - PaddedPieceSizeV2(size.0) -} - pub fn from_reg_seal_proof_v3_to_v2(proof: RegisteredSealProofV3) -> RegisteredSealProofV2 { let num_id: i64 = proof.into(); RegisteredSealProofV2::from(num_id) } -pub fn from_padded_piece_size_v2_to_v3(size: PaddedPieceSizeV2) -> PaddedPieceSizeV3 { - PaddedPieceSizeV3(size.0) -} - -pub fn from_padded_piece_size_v2_to_v4(size: PaddedPieceSizeV2) -> PaddedPieceSizeV4 { - PaddedPieceSizeV4(size.0) -} - pub fn from_reg_seal_proof_v4_to_v2(proof: RegisteredSealProofV4) -> RegisteredSealProofV2 { let num_id: i64 = proof.into(); RegisteredSealProofV2::from(num_id) diff --git a/src/shim/actors/macros.rs b/src/shim/actors/macros.rs index 6ba6a6f0cd50..636be43a68f7 100644 --- a/src/shim/actors/macros.rs +++ b/src/shim/actors/macros.rs @@ -7,7 +7,6 @@ /// Parameters: /// - `$res`: A mutable reference to a collection where the parsed transactions will be stored. /// - `$txns`: A collection of transaction data to be parsed. -#[macro_export] macro_rules! parse_pending_transactions { ($res:ident, $txns:expr) => { $txns.for_each(|tx_key, txn| { @@ -15,11 +14,11 @@ macro_rules! parse_pending_transactions { Some((tx_id, _)) => { $res.push(Transaction { id: tx_id, - to: txn.to, - value: txn.value.clone(), + to: txn.to.into(), + value: txn.value.clone().into(), method: txn.method, params: txn.params.clone(), - approved: txn.approved.clone(), + approved: txn.approved.clone().into_iter().map(From::from).collect(), }); } None => anyhow::bail!("Error decoding varint"), @@ -29,13 +28,11 @@ macro_rules! parse_pending_transactions { }; } -/// This macro iterates over each transaction, decodes the transaction key, and constructs a Transaction object -/// with additional processing for address and token formats using `from_address_v3_to_v2` and `from_token_v3_to_v2`. +/// This macro iterates over each transaction, decodes the transaction key, and constructs a Transaction object. /// /// Parameters: /// - `$res`: A mutable reference to a collection where the parsed transactions will be stored. /// - `$txns`: A collection of transaction data to be parsed. -#[macro_export] macro_rules! parse_pending_transactions_v3 { ($res:ident, $txns:expr) => { $txns.for_each(|tx_key, txn| { @@ -43,15 +40,11 @@ macro_rules! parse_pending_transactions_v3 { Some((tx_id, _)) => { $res.push(Transaction { id: tx_id, - to: from_address_v3_to_v2(txn.to), - value: from_token_v3_to_v2(&txn.value), + to: txn.to.into(), + value: txn.value.clone().into(), method: txn.method, params: txn.params.clone(), - approved: txn - .approved - .iter() - .map(|&addr| from_address_v3_to_v2(addr)) - .collect(), + approved: txn.approved.clone().into_iter().map(From::from).collect(), }); } None => anyhow::bail!("Error decoding varint"), @@ -62,29 +55,26 @@ macro_rules! parse_pending_transactions_v3 { } /// This macro iterates over each transaction, assumes that transaction id's are directly available and not encoded. -/// It constructs Transaction objects with transformations for address and token data from version 4 to version 2 -/// using `from_address_v4_to_v2` and `from_token_v4_to_v2`. /// /// Parameters: /// - `$res`: A mutable reference to a collection where the parsed transactions will be stored. /// - `$txns`: A collection of transaction data to be parsed. -#[macro_export] macro_rules! parse_pending_transactions_v4 { ($res:ident, $txns:expr) => { $txns.for_each(|tx_id, txn| { $res.push(Transaction { id: tx_id.0, - to: from_address_v4_to_v2(txn.to), - value: from_token_v4_to_v2(&txn.value), + to: txn.to.into(), + value: txn.value.clone().into(), method: txn.method, params: txn.params.clone(), - approved: txn - .approved - .iter() - .map(|&addr| from_address_v4_to_v2(addr)) - .collect(), + approved: txn.approved.clone().into_iter().map(From::from).collect(), }); Ok(()) })?; }; } + +pub(crate) use parse_pending_transactions; +pub(crate) use parse_pending_transactions_v3; +pub(crate) use parse_pending_transactions_v4; diff --git a/src/shim/actors/mod.rs b/src/shim/actors/mod.rs index 360682dc6a62..1bae7fbb0c6b 100644 --- a/src/shim/actors/mod.rs +++ b/src/shim/actors/mod.rs @@ -6,13 +6,12 @@ mod builtin; pub mod convert; mod macros; -pub use self::builtin::*; -pub use fil_actors_shared::v9::builtin::singletons::{BURNT_FUNDS_ACTOR_ADDR, CHAOS_ACTOR_ADDR}; -pub use fil_actors_shared::v13::runtime::Policy; - pub mod common; pub use common::*; pub mod state_load; pub use state_load::*; mod version; pub use version::*; + +pub use self::builtin::*; +pub use fil_actors_shared::v9::builtin::singletons::{BURNT_FUNDS_ACTOR_ADDR, CHAOS_ACTOR_ADDR}; diff --git a/src/shim/gas.rs b/src/shim/gas.rs index 87c706447eab..e3de4d163be7 100644 --- a/src/shim/gas.rs +++ b/src/shim/gas.rs @@ -1,11 +1,11 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use std::fmt::{Debug, Display}; - pub use super::fvm_latest::gas::{ Gas as Gas_latest, GasCharge as GasCharge_latest, GasDuration as GasDuration_latest, GasOutputs as GasOutputs_latest, }; +use crate::shim::econ::TokenAmount; +use crate::shim::version::NetworkVersion; use fvm2::gas::{ Gas as GasV2, GasCharge as GasChargeV2, PriceList as PriceListV2, price_list_by_network_version as price_list_by_network_version_v2, @@ -19,9 +19,8 @@ use fvm4::gas::price_list_by_network_version as price_list_by_network_version_v4 pub use fvm4::gas::{ Gas as GasV4, GasCharge as GasChargeV4, GasOutputs as GasOutputsV4, PriceList as PriceListV4, }; - -use crate::shim::econ::TokenAmount; -use crate::shim::version::NetworkVersion; +use spire_enum::prelude::delegated_enum; +use std::fmt::{Debug, Display}; #[derive(Hash, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Default, derive_more::From)] pub struct Gas(Gas_latest); @@ -193,6 +192,7 @@ impl GasOutputs { } } +#[delegated_enum(impl_conversions)] pub enum PriceList { V2(&'static PriceListV2), V3(&'static PriceListV3), @@ -201,11 +201,7 @@ pub enum PriceList { impl PriceList { pub fn on_block_open_base(&self) -> GasCharge { - match self { - PriceList::V2(list) => list.on_block_open_base().into(), - PriceList::V3(list) => list.on_block_open_base().into(), - PriceList::V4(list) => list.on_block_open_base().into(), - } + delegate_price_list!(self.on_block_open_base().into()) } pub fn on_block_link(&self, data_size: usize) -> GasCharge { @@ -221,29 +217,7 @@ impl PriceList { } pub fn on_chain_message(&self, msg_size: usize) -> GasCharge { - match self { - PriceList::V2(list) => list.on_chain_message(msg_size).into(), - PriceList::V3(list) => list.on_chain_message(msg_size).into(), - PriceList::V4(list) => list.on_chain_message(msg_size).into(), - } - } -} - -impl From<&'static PriceListV2> for PriceList { - fn from(value: &'static PriceListV2) -> Self { - PriceList::V2(value) - } -} - -impl From<&'static PriceListV3> for PriceList { - fn from(value: &'static PriceListV3) -> Self { - PriceList::V3(value) - } -} - -impl From<&'static PriceListV4> for PriceList { - fn from(value: &'static PriceListV4) -> Self { - PriceList::V4(value) + delegate_price_list!(self.on_chain_message(msg_size).into()) } } diff --git a/src/shim/mod.rs b/src/shim/mod.rs index 1dff700ad94f..346bfb8b5572 100644 --- a/src/shim/mod.rs +++ b/src/shim/mod.rs @@ -18,6 +18,7 @@ pub mod message; pub mod piece; pub mod policy; pub mod randomness; +pub mod runtime; pub mod sector; pub mod state_tree; pub mod state_tree_v0; @@ -34,3 +35,5 @@ pub mod fvm_shared_latest { pub mod fvm_latest { pub use fvm4::*; } + +pub type MethodNum = fvm_shared_latest::MethodNum; diff --git a/src/shim/runtime.rs b/src/shim/runtime.rs new file mode 100644 index 000000000000..36c586aae4bf --- /dev/null +++ b/src/shim/runtime.rs @@ -0,0 +1,83 @@ +// Copyright 2019-2026 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +use super::actors::convert::*; +use fil_actors_shared::{ + v9::runtime::Policy as PolicyV9, v10::runtime::Policy as PolicyV10, + v11::runtime::Policy as PolicyV11, v12::runtime::Policy as PolicyV12, + v13::runtime::Policy as PolicyV13, v14::runtime::Policy as PolicyV14, + v15::runtime::Policy as PolicyV15, v16::runtime::Policy as PolicyV16, + v17::runtime::Policy as PolicyV17, +}; +use serde::{Deserialize, Serialize}; + +/// Shim wrapper around the latest policy version with cross-version conversions. +#[derive( + Debug, + Clone, + Default, + Eq, + PartialEq, + Serialize, + Deserialize, + derive_more::Deref, + derive_more::DerefMut, + derive_more::From, + derive_more::Into, +)] +#[serde(transparent)] +pub struct Policy(pub PolicyV13); + +impl From<&Policy> for PolicyV9 { + fn from(Policy(policy): &Policy) -> Self { + from_policy_v13_to_v9(policy) + } +} + +impl From<&Policy> for PolicyV10 { + fn from(Policy(policy): &Policy) -> Self { + from_policy_v13_to_v10(policy) + } +} + +impl From<&Policy> for PolicyV11 { + fn from(Policy(policy): &Policy) -> Self { + from_policy_v13_to_v11(policy) + } +} + +impl From<&Policy> for PolicyV12 { + fn from(Policy(policy): &Policy) -> Self { + from_policy_v13_to_v12(policy) + } +} + +impl From<&Policy> for PolicyV13 { + fn from(Policy(policy): &Policy) -> Self { + policy.clone() + } +} + +impl From<&Policy> for PolicyV14 { + fn from(Policy(policy): &Policy) -> Self { + from_policy_v13_to_v14(policy) + } +} + +impl From<&Policy> for PolicyV15 { + fn from(Policy(policy): &Policy) -> Self { + from_policy_v13_to_v15(policy) + } +} + +impl From<&Policy> for PolicyV16 { + fn from(Policy(policy): &Policy) -> Self { + from_policy_v13_to_v16(policy) + } +} + +impl From<&Policy> for PolicyV17 { + fn from(Policy(policy): &Policy) -> Self { + from_policy_v13_to_v17(policy) + } +} diff --git a/src/shim/state_tree.rs b/src/shim/state_tree.rs index d0a8270070ad..5b31dfa203af 100644 --- a/src/shim/state_tree.rs +++ b/src/shim/state_tree.rs @@ -1,7 +1,11 @@ // Copyright 2019-2026 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use std::sync::Arc; - +use super::actors::LoadActorStateFromBlockstore; +pub use super::fvm_shared_latest::{ActorID, state::StateRoot}; +use crate::{ + blocks::Tipset, + shim::{actors::AccountActorStateLoad as _, address::Address, econ::TokenAmount}, +}; use crate::{ networks::{ACTOR_BUNDLES_METADATA, ActorBundleMetadata}, shim::actors::account, @@ -24,13 +28,8 @@ pub use fvm4::state_tree::{ use num::FromPrimitive; use num_derive::FromPrimitive; use serde::{Deserialize, Serialize}; - -use super::actors::LoadActorStateFromBlockstore; -pub use super::fvm_shared_latest::{ActorID, state::StateRoot}; -use crate::{ - blocks::Tipset, - shim::{actors::AccountActorStateLoad as _, address::Address, econ::TokenAmount}, -}; +use spire_enum::prelude::delegated_enum; +use std::sync::Arc; #[derive( Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Serialize_repr, Deserialize_repr, FromPrimitive, @@ -134,6 +133,7 @@ impl TryFrom for StateTreeVersionV4 { /// /// Not all the inner methods are implemented, only those that are needed. Feel /// free to add those when necessary. +#[delegated_enum(impl_conversions)] pub enum StateTree { // Version 0 is used to parse the genesis block. V0(super::state_tree_v0::StateTreeV0>), @@ -275,12 +275,7 @@ where /// Retrieve store reference to modify db. pub fn store(&self) -> &S { - match self { - StateTree::FvmV2(st) => st.store(), - StateTree::FvmV3(st) => st.store(), - StateTree::FvmV4(st) => st.store(), - StateTree::V0(st) => st.store(), - } + delegate_state_tree!(self.store()) } /// Get an ID address from any Address @@ -305,22 +300,13 @@ where { match self { StateTree::FvmV2(st) => { - let inner = |address: fvm_shared2::address::Address, actor_state: &ActorStateV2| { - f(address.into(), &actor_state.into()) - }; - st.for_each(inner) + st.for_each(|address, actor_state| f(address.into(), &actor_state.into())) } StateTree::FvmV3(st) => { - let inner = |address: fvm_shared3::address::Address, actor_state: &ActorStateV3| { - f(address.into(), &actor_state.into()) - }; - st.for_each(inner) + st.for_each(|address, actor_state| f(address.into(), &actor_state.into())) } StateTree::FvmV4(st) => { - let inner = |address: fvm_shared4::address::Address, actor_state: &ActorStateV4| { - f(address.into(), &actor_state.into()) - }; - st.for_each(inner) + st.for_each(|address, actor_state| f(address.into(), &actor_state.into())) } StateTree::V0(_) => bail!("StateTree::for_each not supported on old state trees"), } diff --git a/src/state_manager/circulating_supply.rs b/src/state_manager/circulating_supply.rs index cf1641e558d2..d32c3171492b 100644 --- a/src/state_manager/circulating_supply.rs +++ b/src/state_manager/circulating_supply.rs @@ -180,7 +180,7 @@ impl GenesisInfo { _ if is_multisig_actor(&actor.code) => { let ms = multisig::State::load(&db, actor.code, actor.state)?; - let locked_balance: TokenAmount = ms.locked_balance(height)?.into(); + let locked_balance = ms.locked_balance(height)?; let avail_balance = actor_balance.clone() - &locked_balance; circ += avail_balance.max(TokenAmount::zero()); un_circ += actor_balance.min(locked_balance); diff --git a/src/state_manager/mod.rs b/src/state_manager/mod.rs index 8578625406d0..e2463c688235 100644 --- a/src/state_manager/mod.rs +++ b/src/state_manager/mod.rs @@ -48,6 +48,7 @@ use crate::shim::{ machine::{GLOBAL_MULTI_ENGINE, MultiEngine}, message::Message, randomness::Randomness, + runtime::Policy, state_tree::{ActorState, StateTree}, version::NetworkVersion, }; @@ -71,7 +72,6 @@ use fil_actor_verifreg_state::v13::ClaimID; use fil_actors_shared::fvm_ipld_amt::{Amt, Amtv0}; use fil_actors_shared::fvm_ipld_bitfield::BitField; use fil_actors_shared::v12::runtime::DomainSeparationTag; -use fil_actors_shared::v13::runtime::Policy; use futures::{FutureExt, channel::oneshot, select}; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::to_vec; @@ -1617,7 +1617,7 @@ where ) -> anyhow::Result> { let id_address = self.lookup_required_id(addr, ts)?; let state = self.get_verified_registry_actor_state(ts)?; - state.get_claim(self.blockstore(), id_address.into(), claim_id) + state.get_claim(self.blockstore(), id_address, claim_id) } pub fn get_all_claims(&self, ts: &Tipset) -> anyhow::Result> { @@ -1657,7 +1657,7 @@ where // Original: https://github.com/filecoin-project/lotus/blob/5e76b05b17771da6939c7b0bf65127c3dc70ee23/node/impl/full/state.go#L1627-L1664. if (u32::from(network_version.0)) < 17 { let state = self.get_verified_registry_actor_state(ts)?; - return state.verified_client_data_cap(self.blockstore(), id.into()); + return state.verified_client_data_cap(self.blockstore(), id); } let act = self @@ -1667,7 +1667,7 @@ where let state = datacap::State::load(self.blockstore(), act.code, act.state)?; - state.verified_client_data_cap(self.blockstore(), id.into()) + state.verified_client_data_cap(self.blockstore(), id) } pub async fn resolve_to_deterministic_address( diff --git a/src/state_migration/nv17/miner.rs b/src/state_migration/nv17/miner.rs index d83ebdc9559e..f4fc39fc0ba5 100644 --- a/src/state_migration/nv17/miner.rs +++ b/src/state_migration/nv17/miner.rs @@ -710,7 +710,7 @@ mod tests { &mut tree, reward_state_cid, reward_cid, - &reward::ADDRESS.into(), + &reward::ADDRESS, TokenAmount::from_whole(1_100_000_000), );