diff --git a/types/src/version.rs b/types/src/version.rs index b64782f75ebf..f0a7074f8e73 100644 --- a/types/src/version.rs +++ b/types/src/version.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0, MIT use encoding::repr::Serialize_repr; +use std::fmt::{self, Display, Formatter}; /// Specifies the network version #[derive(Debug, PartialEq, Clone, Copy, PartialOrd, Serialize_repr)] @@ -15,9 +16,9 @@ pub enum NetworkVersion { V2, /// ignition (specs-actors v0.9.11) V3, - /// actors v2 (specs-actors v2.0.x) + /// actors v2 (specs-actors v2.0.3) V4, - /// tape (increases max prove commit size by 10x) + /// tape (specs-actors v2.1.0) V5, /// kumquat (specs-actors v2.2.0) V6, @@ -25,16 +26,38 @@ pub enum NetworkVersion { V7, /// persian (post-2.3.2 behaviour transition) V8, - /// orange + /// orange (post-2.3.2 behaviour transition) V9, - /// actors v3 (specs-actors v3.0.x) + /// trust (specs-actors v3.0.1) V10, - /// norwegian (specs-actor v3.1.x) + /// norwegian (specs-actors v3.1.0) V11, - /// actors v3 (specs-actor v4.0.x) + /// turbo (specs-actors v4.0.0) V12, - /// reserved + /// hyperdrive (specs-actors v5.0.1) V13, - /// actors v6 + /// chocolate (specs-actors v6.0.0) V14, } + +impl Display for NetworkVersion { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::V0 => write!(f, "V0"), + Self::V1 => write!(f, "V1"), + Self::V2 => write!(f, "V2"), + Self::V3 => write!(f, "V3"), + Self::V4 => write!(f, "V4"), + Self::V5 => write!(f, "V5"), + Self::V6 => write!(f, "V6"), + Self::V7 => write!(f, "V7"), + Self::V8 => write!(f, "V8"), + Self::V9 => write!(f, "V9"), + Self::V10 => write!(f, "V10"), + Self::V11 => write!(f, "V11"), + Self::V12 => write!(f, "V12"), + Self::V13 => write!(f, "V13"), + Self::V14 => write!(f, "V14"), + } + } +} diff --git a/vm/actor_interface/src/builtin/mod.rs b/vm/actor_interface/src/builtin/mod.rs index 6f2c582044fb..0e701b4d4d5c 100644 --- a/vm/actor_interface/src/builtin/mod.rs +++ b/vm/actor_interface/src/builtin/mod.rs @@ -11,6 +11,8 @@ pub mod power; pub mod reward; pub mod system; +use crate::ActorVersion; + use cid::Cid; use num_bigint::BigInt; @@ -63,15 +65,24 @@ pub fn is_miner_actor(code: &Cid) -> bool { || code == &*actorv6::MINER_ACTOR_CODE_ID } -// pub fn actor_name_by_code(code: &Cid) -> String { -// if actorv0::is_builtin_actor(code) { -// } else if actorv2::is_builtin_actor(code) { -// } else if actorv3::is_builtin_actor(code) { -// } else if actorv4::is_builtin_actor(code) { -// } else { -// String::from("") -// } -// } +/// Returns an actor's version or None if it was not a builtin +pub fn actor_version(code: &Cid) -> Option { + if actorv6::is_builtin_actor(code) { + Some(ActorVersion::V6) + } else if actorv5::is_builtin_actor(code) { + Some(ActorVersion::V5) + } else if actorv4::is_builtin_actor(code) { + Some(ActorVersion::V4) + } else if actorv3::is_builtin_actor(code) { + Some(ActorVersion::V3) + } else if actorv2::is_builtin_actor(code) { + Some(ActorVersion::V2) + } else if actorv0::is_builtin_actor(code) { + Some(ActorVersion::V0) + } else { + None + } +} #[derive(Default, Clone, Debug, PartialEq)] pub struct FilterEstimate { diff --git a/vm/actor_interface/src/lib.rs b/vm/actor_interface/src/lib.rs index 112b22fa3109..903b57ec206f 100644 --- a/vm/actor_interface/src/lib.rs +++ b/vm/actor_interface/src/lib.rs @@ -17,6 +17,7 @@ pub use actorv6; use fil_types::{NetworkVersion, StateTreeVersion}; use std::fmt::{self, Display, Formatter}; +#[derive(PartialEq)] pub enum ActorVersion { V0, V2, diff --git a/vm/interpreter/src/default_runtime.rs b/vm/interpreter/src/default_runtime.rs index 10d7d99ba0ae..b655abbfd927 100644 --- a/vm/interpreter/src/default_runtime.rs +++ b/vm/interpreter/src/default_runtime.rs @@ -827,6 +827,17 @@ where ); } + // Unwrapping is safe because we are priorly testing if it's a builtin + let version = actor::actor_version(&code_id).unwrap(); + let support = ActorVersion::from(self.network_version()); + if version != support { + let msg = format!( + "actor {} is a version {} actor; chain only supports actor version {} at height {} and nver {}", + &code_id, version, support, self.curr_epoch(), self.network_version() + ); + return Err(actor_error!(SysErrIllegalArgument; "Cannot create actor: {}", msg)); + } + if actor::is_singleton_actor(&code_id) { return Err(actor_error!(SysErrIllegalArgument; "Can only have one instance of singleton actors."));