diff --git a/Cargo.lock b/Cargo.lock index a28fb4820ec4..6ab3f97dfd02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1060,9 +1060,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.53" +version = "1.2.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" +checksum = "6354c81bbfd62d9cfa9cb3c773c2b7b2a3a482d569de977fd0e961f6e7c00583" dependencies = [ "find-msvc-tools", "jobserver", @@ -1230,7 +1230,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -1470,6 +1470,15 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" +[[package]] +name = "convert_case" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "convert_case" version = "0.10.0" @@ -1950,7 +1959,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.11.1", "syn 2.0.114", ] @@ -1964,7 +1973,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.11.1", "syn 2.0.114", ] @@ -2016,6 +2025,47 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "deluxe" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed332aaf752b459088acf3dd4eca323e3ef4b83c70a84ca48fb0ec5305f1488" +dependencies = [ + "deluxe-core", + "deluxe-macros", + "once_cell", + "proc-macro2", + "syn 2.0.114", +] + +[[package]] +name = "deluxe-core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddada51c8576df9d6a8450c351ff63042b092c9458b8ac7d20f89cbd0ffd313" +dependencies = [ + "arrayvec 0.7.6", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.114", +] + +[[package]] +name = "deluxe-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87546d9c837f0b7557e47b8bd6eae52c3c223141b76aa233c345c9ab41d9117" +dependencies = [ + "deluxe-core", + "heck 0.4.1", + "if_chain", + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "deprecate-until" version = "0.1.1" @@ -2154,7 +2204,7 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ - "convert_case", + "convert_case 0.10.0", "proc-macro2", "quote", "rustc_version", @@ -3326,6 +3376,7 @@ dependencies = [ "slotmap", "smallvec", "smart-default", + "spire_enum", "sqlx", "stacker", "static_assertions", @@ -4682,6 +4733,12 @@ dependencies = [ "windows", ] +[[package]] +name = "if_chain" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" + [[package]] name = "igd-next" version = "0.16.2" @@ -6567,6 +6624,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + [[package]] name = "p256" version = "0.13.2" @@ -6695,6 +6761,31 @@ dependencies = [ "windows-link", ] +[[package]] +name = "parsel" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8219a08ce4ea85fdd7d3e5eb253e37f269f6c4eef469de547f25ebdb6abed6a4" +dependencies = [ + "ordered-float", + "parsel_derive", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "parsel_derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75d6402717274d0f4f095a02fe2edbef193a3a608e18aeb874baf26f5748515" +dependencies = [ + "deluxe", + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "password-hash" version = "0.5.0" @@ -8770,6 +8861,29 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spire_enum" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eefc28c56da4abd9ad64b8af32edcb8333b2597f8a863cdcd970ad3a9c2bb13" +dependencies = [ + "spire_enum_macros", +] + +[[package]] +name = "spire_enum_macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09cdc8fd3fa6696f64950aaa347b05c4f57aa3e0f03947b22cc0a1fad4bbe42" +dependencies = [ + "convert_case 0.8.0", + "itertools 0.14.0", + "parsel", + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "spki" version = "0.7.3" @@ -9055,6 +9169,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" diff --git a/Cargo.toml b/Cargo.toml index b6d0b215188d..5da114f1b2a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -196,6 +196,7 @@ similar = "2" slotmap = "1" smallvec = "1" smart-default = "0.7" +spire_enum = "1" stacker = "0.1" static_assertions = "1" statrs = "0.18" diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 6b622659bfe6..479b06587fe0 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -46,5 +46,5 @@ where let acc_st = account::State::load(store, act.code, act.state)?; - Ok(acc_st.pubkey_address().into()) + Ok(acc_st.pubkey_address()) } diff --git a/src/interpreter/vm.rs b/src/interpreter/vm.rs index 27046daa1372..6985c695577a 100644 --- a/src/interpreter/vm.rs +++ b/src/interpreter/vm.rs @@ -53,6 +53,7 @@ use fvm4::{ }, }; use num::Zero; +use spire_enum::prelude::delegated_enum; use std::time::{Duration, Instant}; pub(in crate::interpreter) type ForestMachineV2 = @@ -139,6 +140,7 @@ impl BlockMessages { /// Interpreter which handles execution of state transitioning messages and /// returns receipts from the VM execution. +#[delegated_enum(impl_conversions)] pub enum VM { VM2(ForestExecutorV2), VM3(ForestExecutorV3), @@ -272,11 +274,7 @@ where /// Flush stores in VM and return state root. pub fn flush(&mut self) -> anyhow::Result { - match self { - VM::VM2(fvm_executor) => Ok(fvm_executor.flush()?), - VM::VM3(fvm_executor) => Ok(fvm_executor.flush()?), - VM::VM4(fvm_executor) => Ok(fvm_executor.flush()?), - } + Ok(delegate_vm!(self.flush()?)) } /// Get actor state from an address. Will be resolved to ID address. diff --git a/src/lotus_json/actors/states/account_state.rs b/src/lotus_json/actors/states/account_state.rs index 5e3c441ab31d..0c23fdcd53ea 100644 --- a/src/lotus_json/actors/states/account_state.rs +++ b/src/lotus_json/actors/states/account_state.rs @@ -29,7 +29,7 @@ impl HasLotusJson for State { fn into_lotus_json(self) -> Self::LotusJson { AccountStateLotusJson { - address: self.pubkey_address().into(), + address: self.pubkey_address(), } } diff --git a/src/shim/actors/builtin/account/mod.rs b/src/shim/actors/builtin/account/mod.rs index edc783ea5a6f..2cc183f7d38c 100644 --- a/src/shim/actors/builtin/account/mod.rs +++ b/src/shim/actors/builtin/account/mod.rs @@ -2,8 +2,9 @@ // SPDX-License-Identifier: Apache-2.0, MIT use super::super::convert::{from_address_v3_to_v2, from_address_v4_to_v2}; -use crate::shim; +use crate::shim::{self, address::Address}; use serde::Serialize; +use spire_enum::prelude::delegated_enum; /// Account actor method. pub type Method = fil_actor_account_state::v8::Method; @@ -11,6 +12,7 @@ pub type Method = fil_actor_account_state::v8::Method; /// Account actor state. #[derive(Serialize, Debug)] #[serde(untagged)] +#[delegated_enum(impl_conversions)] pub enum State { V8(fil_actor_account_state::v8::State), V9(fil_actor_account_state::v9::State), @@ -25,19 +27,8 @@ pub enum State { } impl State { - pub fn pubkey_address(&self) -> fvm_shared2::address::Address { - match self { - State::V8(st) => st.address, - State::V9(st) => st.address, - State::V10(st) => from_address_v3_to_v2(st.address), - State::V11(st) => from_address_v3_to_v2(st.address), - State::V12(st) => from_address_v4_to_v2(st.address), - State::V13(st) => from_address_v4_to_v2(st.address), - State::V14(st) => from_address_v4_to_v2(st.address), - State::V15(st) => from_address_v4_to_v2(st.address), - State::V16(st) => from_address_v4_to_v2(st.address), - State::V17(st) => from_address_v4_to_v2(st.address), - } + pub fn pubkey_address(&self) -> Address { + delegate_state!(self.address.into()) } pub fn default_latest_version(address: fvm_shared4::address::Address) -> Self { diff --git a/src/shim/actors/builtin/miner/mod.rs b/src/shim/actors/builtin/miner/mod.rs index eddda173e79b..178c4de02803 100644 --- a/src/shim/actors/builtin/miner/mod.rs +++ b/src/shim/actors/builtin/miner/mod.rs @@ -5,6 +5,7 @@ pub mod ext; use crate::shim::actors::Policy; use crate::shim::actors::convert::*; +use crate::shim::actors::power::Claim; use cid::Cid; use fil_actor_miner_state::v12::{BeneficiaryTerm, PendingBeneficiaryChange}; use fil_actor_miner_state::v17::VestingFunds as VestingFundsV17; @@ -20,9 +21,9 @@ use fvm_shared2::{ }; use num::BigInt; use serde::{Deserialize, Serialize}; -use std::borrow::Cow; +use spire_enum::prelude::delegated_enum; +use std::borrow::{Borrow as _, Cow}; -use crate::shim::actors::power::Claim; /// Miner actor method. pub type Method = fil_actor_miner_state::v8::Method; @@ -107,41 +108,41 @@ impl State { State::V8(st) => st.load_deadlines(&store)?.for_each( &from_policy_v13_to_v9(policy), &store, - |idx, dl| f(idx, Deadline::V8(dl)), + |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, Deadline::V9(dl)), + |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, Deadline::V10(dl)), + |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, Deadline::V11(dl)), + |idx, dl| f(idx, dl.into()), ), State::V12(st) => st .load_deadlines(store)? - .for_each(store, |idx, dl| f(idx, Deadline::V12(dl))), + .for_each(store, |idx, dl| f(idx, dl.into())), State::V13(st) => st .load_deadlines(store)? - .for_each(store, |idx, dl| f(idx, Deadline::V13(dl))), + .for_each(store, |idx, dl| f(idx, dl.into())), State::V14(st) => st .load_deadlines(store)? - .for_each(store, |idx, dl| f(idx, Deadline::V14(dl))), + .for_each(store, |idx, dl| f(idx, dl.into())), State::V15(st) => st .load_deadlines(store)? - .for_each(store, |idx, dl| f(idx, Deadline::V15(dl))), + .for_each(store, |idx, dl| f(idx, dl.into())), State::V16(st) => st .load_deadlines(store)? - .for_each(store, |idx, dl| f(idx, Deadline::V16(dl))), + .for_each(store, |idx, dl| f(idx, dl.into())), State::V17(st) => st .load_deadlines(store)? - .for_each(store, |idx, dl| f(idx, Deadline::V17(dl))), + .for_each(store, |idx, dl| f(idx, dl.into())), } } @@ -156,43 +157,43 @@ impl State { State::V8(st) => Ok(st .load_deadlines(store)? .load_deadline(&from_policy_v13_to_v9(policy), store, idx) - .map(Deadline::V8)?), + .map(From::from)?), State::V9(st) => Ok(st .load_deadlines(store)? .load_deadline(&from_policy_v13_to_v9(policy), store, idx) - .map(Deadline::V9)?), + .map(From::from)?), State::V10(st) => Ok(st .load_deadlines(store)? .load_deadline(&from_policy_v13_to_v10(policy), store, idx) - .map(Deadline::V10)?), + .map(From::from)?), State::V11(st) => Ok(st .load_deadlines(store)? .load_deadline(&from_policy_v13_to_v11(policy), store, idx) - .map(Deadline::V11)?), + .map(From::from)?), State::V12(st) => Ok(st .load_deadlines(store)? .load_deadline(store, idx) - .map(Deadline::V12)?), + .map(From::from)?), State::V13(st) => Ok(st .load_deadlines(store)? .load_deadline(store, idx) - .map(Deadline::V13)?), + .map(From::from)?), State::V14(st) => Ok(st .load_deadlines(store)? .load_deadline(store, idx) - .map(Deadline::V14)?), + .map(From::from)?), State::V15(st) => Ok(st .load_deadlines(store)? .load_deadline(store, idx) - .map(Deadline::V15)?), + .map(From::from)?), State::V16(st) => Ok(st .load_deadlines(store)? .load_deadline(store, idx) - .map(Deadline::V16)?), + .map(From::from)?), State::V17(st) => Ok(st .load_deadlines(store)? .load_deadline(store, idx) - .map(Deadline::V17)?), + .map(From::from)?), } } @@ -910,6 +911,7 @@ pub struct MinerPower { } /// Deadline holds the state for all sectors due at a specific deadline. +#[delegated_enum(impl_conversions)] pub enum Deadline { V8(fil_actor_miner_state::v8::Deadline), V9(fil_actor_miner_state::v9::Deadline), @@ -930,76 +932,24 @@ impl Deadline { store: &BS, mut f: impl FnMut(u64, Partition) -> Result<(), anyhow::Error>, ) -> anyhow::Result<()> { - match self { - Deadline::V8(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V8(Cow::Borrowed(part))) - }), - Deadline::V9(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V9(Cow::Borrowed(part))) - }), - Deadline::V10(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V10(Cow::Borrowed(part))) - }), - Deadline::V11(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V11(Cow::Borrowed(part))) - }), - Deadline::V12(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V12(Cow::Borrowed(part))) - }), - Deadline::V13(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V13(Cow::Borrowed(part))) - }), - Deadline::V14(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V14(Cow::Borrowed(part))) - }), - Deadline::V15(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V15(Cow::Borrowed(part))) - }), - Deadline::V16(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V16(Cow::Borrowed(part))) - }), - Deadline::V17(dl) => dl.for_each(&store, |idx, part| { - f(idx, Partition::V17(Cow::Borrowed(part))) - }), - } + delegate_deadline!(self.for_each(&store, |idx, part| f(idx, Cow::Borrowed(part).into()))) } /// Returns number of partitions posted pub fn partitions_posted(&self) -> BitField { - match self { - Deadline::V8(dl) => dl.partitions_posted.clone(), - Deadline::V9(dl) => dl.partitions_posted.clone(), - Deadline::V10(dl) => dl.partitions_posted.clone(), - Deadline::V11(dl) => dl.partitions_posted.clone(), - Deadline::V12(dl) => dl.partitions_posted.clone(), - Deadline::V13(dl) => dl.partitions_posted.clone(), - Deadline::V14(dl) => dl.partitions_posted.clone(), - Deadline::V15(dl) => dl.partitions_posted.clone(), - Deadline::V16(dl) => dl.partitions_posted.clone(), - Deadline::V17(dl) => dl.partitions_posted.clone(), - } + delegate_deadline!(self.partitions_posted.clone()) } /// Returns disputable proof count of the deadline pub fn disputable_proof_count(&self, store: &BS) -> anyhow::Result { - match self { - Deadline::V8(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - Deadline::V9(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - Deadline::V10(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - Deadline::V11(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - Deadline::V12(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - Deadline::V13(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - Deadline::V14(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - Deadline::V15(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - Deadline::V16(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - Deadline::V17(dl) => Ok(dl.optimistic_proofs_snapshot_amt(store)?.count()), - } + Ok(delegate_deadline!( + self.optimistic_proofs_snapshot_amt(store)?.count() + )) } } -#[allow(clippy::large_enum_variant)] +#[delegated_enum(impl_conversions)] pub enum Partition<'a> { - // V7(Cow<'a, fil_actor_miner_state::v7::Partition>), V8(Cow<'a, fil_actor_miner_state::v8::Partition>), V9(Cow<'a, fil_actor_miner_state::v9::Partition>), V10(Cow<'a, fil_actor_miner_state::v10::Partition>), @@ -1014,74 +964,19 @@ pub enum Partition<'a> { impl Partition<'_> { pub fn all_sectors(&self) -> &BitField { - match self { - Partition::V8(dl) => &dl.sectors, - Partition::V9(dl) => &dl.sectors, - Partition::V10(dl) => &dl.sectors, - Partition::V11(dl) => &dl.sectors, - Partition::V12(dl) => &dl.sectors, - Partition::V13(dl) => &dl.sectors, - Partition::V14(dl) => &dl.sectors, - Partition::V15(dl) => &dl.sectors, - Partition::V16(dl) => &dl.sectors, - Partition::V17(dl) => &dl.sectors, - } + delegate_partition!(self.sectors.borrow()) } pub fn faulty_sectors(&self) -> &BitField { - match self { - Partition::V8(dl) => &dl.faults, - Partition::V9(dl) => &dl.faults, - Partition::V10(dl) => &dl.faults, - Partition::V11(dl) => &dl.faults, - Partition::V12(dl) => &dl.faults, - Partition::V13(dl) => &dl.faults, - Partition::V14(dl) => &dl.faults, - Partition::V15(dl) => &dl.faults, - Partition::V16(dl) => &dl.faults, - Partition::V17(dl) => &dl.faults, - } + delegate_partition!(self.faults.borrow()) } pub fn live_sectors(&self) -> BitField { - match self { - Partition::V8(dl) => dl.live_sectors(), - Partition::V9(dl) => dl.live_sectors(), - Partition::V10(dl) => dl.live_sectors(), - Partition::V11(dl) => dl.live_sectors(), - Partition::V12(dl) => dl.live_sectors(), - Partition::V13(dl) => dl.live_sectors(), - Partition::V14(dl) => dl.live_sectors(), - Partition::V15(dl) => dl.live_sectors(), - Partition::V16(dl) => dl.live_sectors(), - Partition::V17(dl) => dl.live_sectors(), - } + delegate_partition!(self.live_sectors()) } pub fn active_sectors(&self) -> BitField { - match self { - Partition::V8(dl) => dl.active_sectors(), - Partition::V9(dl) => dl.active_sectors(), - Partition::V10(dl) => dl.active_sectors(), - Partition::V11(dl) => dl.active_sectors(), - Partition::V12(dl) => dl.active_sectors(), - Partition::V13(dl) => dl.active_sectors(), - Partition::V14(dl) => dl.active_sectors(), - Partition::V15(dl) => dl.active_sectors(), - Partition::V16(dl) => dl.active_sectors(), - Partition::V17(dl) => dl.active_sectors(), - } + delegate_partition!(self.active_sectors()) } pub fn recovering_sectors(&self) -> &BitField { - match self { - Partition::V8(dl) => &dl.recoveries, - Partition::V9(dl) => &dl.recoveries, - Partition::V10(dl) => &dl.recoveries, - Partition::V11(dl) => &dl.recoveries, - Partition::V12(dl) => &dl.recoveries, - Partition::V13(dl) => &dl.recoveries, - Partition::V14(dl) => &dl.recoveries, - Partition::V15(dl) => &dl.recoveries, - Partition::V16(dl) => &dl.recoveries, - Partition::V17(dl) => &dl.recoveries, - } + delegate_partition!(self.recoveries.borrow()) } } diff --git a/src/shim/state_tree.rs b/src/shim/state_tree.rs index 39c1f73eee67..d0a8270070ad 100644 --- a/src/shim/state_tree.rs +++ b/src/shim/state_tree.rs @@ -385,7 +385,7 @@ where } let account_state = account::State::load(store, actor.code, actor.state)?; - Ok(account_state.pubkey_address().into()) + Ok(account_state.pubkey_address()) } } }