Skip to content

Commit

Permalink
Add Canyon hardfork behind optimism feature flag
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Nov 20, 2023
1 parent b0a18c9 commit 513862b
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 41 deletions.
5 changes: 5 additions & 0 deletions crates/interpreter/src/instructions/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,11 @@ pub const fn spec_opcode_gas(spec_id: SpecId) -> &'static [OpInfo; 256] {
const TABLE: &[OpInfo;256] = &make_gas_table(SpecId::REGOLITH);
TABLE
}
#[cfg(feature = "optimism")]
SpecId::CANYON => {
const TABLE: &[OpInfo;256] = &make_gas_table(SpecId::CANYON);
TABLE
}
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion crates/precompile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ impl SpecId {
CANCUN => Self::CANCUN,
LATEST => Self::LATEST,
#[cfg(feature = "optimism")]
BEDROCK | REGOLITH => Self::BERLIN,
BEDROCK | REGOLITH | CANYON => Self::BERLIN,
}
}
}
Expand Down
118 changes: 78 additions & 40 deletions crates/primitives/src/specification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,32 @@

pub use SpecId::*;

/// Specification IDs and their activation block.
///
/// Information was obtained from: <https://github.com/ethereum/execution-specs>
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, enumn::N)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum SpecId {
macro_rules! define_spec_id {
($($name:ident = $value:expr),* $(,)?) => {
#[doc = "Specification IDs and their activation block. See: [Ethereum Execution Specs](https://github.com/ethereum/execution-specs)"]
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, enumn::N)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum SpecId {
$($name = $value,)*
}

impl SpecId {
#[inline]
pub fn try_from_u8(spec_id: u8) -> Option<Self> {
Self::n(spec_id)
}

#[inline]
pub const fn enabled(our: SpecId, other: SpecId) -> bool {
our as u8 >= other as u8
}
}
};
}

#[cfg(not(feature = "optimism"))]
define_spec_id!(
FRONTIER = 0, // Frontier 0
FRONTIER_THAWING = 1, // Frontier Thawing 200000
HOMESTEAD = 2, // Homestead 1150000
Expand All @@ -27,41 +46,34 @@ pub enum SpecId {
MERGE = 15, // Paris/Merge 15537394 (TTD: 58750000000000000000000)
SHANGHAI = 16, // Shanghai 17034870 (TS: 1681338455)
CANCUN = 17, // Cancun TBD
#[cfg(feature = "optimism")]
BEDROCK = 128,
#[cfg(feature = "optimism")]
REGOLITH = 129,
LATEST = u8::MAX,
}
);

impl SpecId {
#[inline]
pub fn try_from_u8(spec_id: u8) -> Option<Self> {
Self::n(spec_id)
}

#[inline]
pub const fn enabled(our: SpecId, other: SpecId) -> bool {
#[cfg(feature = "optimism")]
{
let (our, other) = (our as u8, other as u8);
let (merge, bedrock, regolith) =
(Self::MERGE as u8, Self::BEDROCK as u8, Self::REGOLITH as u8);
// If the Spec is Bedrock or Regolith, and the input is not Bedrock or Regolith,
// then no hardforks should be enabled after the merge. This is because Optimism's
// Bedrock and Regolith hardforks implement changes on top of the Merge hardfork.
let is_self_optimism = our == bedrock || our == regolith;
let input_not_optimism = other != bedrock && other != regolith;
let after_merge = other > merge;

if is_self_optimism && input_not_optimism && after_merge {
return false;
}
}

our as u8 >= other as u8
}
}
#[cfg(feature = "optimism")]
define_spec_id!(
FRONTIER = 0,
FRONTIER_THAWING = 1,
HOMESTEAD = 2,
DAO_FORK = 3,
TANGERINE = 4,
SPURIOUS_DRAGON = 5,
BYZANTIUM = 6,
CONSTANTINOPLE = 7,
PETERSBURG = 8,
ISTANBUL = 9,
MUIR_GLACIER = 10,
BERLIN = 11,
LONDON = 12,
ARROW_GLACIER = 13,
GRAY_GLACIER = 14,
MERGE = 15,
BEDROCK = 16,
REGOLITH = 17,
SHANGHAI = 18,
CANYON = 19,
CANCUN = 20,
LATEST = u8::MAX,
);

impl From<&str> for SpecId {
fn from(name: &str) -> Self {
Expand All @@ -84,6 +96,8 @@ impl From<&str> for SpecId {
"Bedrock" => SpecId::BEDROCK,
#[cfg(feature = "optimism")]
"Regolith" => SpecId::REGOLITH,
#[cfg(feature = "optimism")]
"Canyon" => SpecId::CANYON,
_ => Self::LATEST,
}
}
Expand Down Expand Up @@ -137,6 +151,8 @@ spec!(LATEST, LatestSpec);
spec!(BEDROCK, BedrockSpec);
#[cfg(feature = "optimism")]
spec!(REGOLITH, RegolithSpec);
#[cfg(feature = "optimism")]
spec!(CANYON, CanyonSpec);

#[cfg(feature = "optimism")]
#[cfg(test)]
Expand Down Expand Up @@ -182,4 +198,26 @@ mod tests {
assert!(SpecId::enabled(SpecId::REGOLITH, SpecId::BEDROCK));
assert!(SpecId::enabled(SpecId::REGOLITH, SpecId::REGOLITH));
}

#[test]
fn test_canyon_post_merge_hardforks() {
assert!(CanyonSpec::enabled(SpecId::MERGE));
assert!(CanyonSpec::enabled(SpecId::SHANGHAI));
assert!(!CanyonSpec::enabled(SpecId::CANCUN));
assert!(!CanyonSpec::enabled(SpecId::LATEST));
assert!(CanyonSpec::enabled(SpecId::BEDROCK));
assert!(CanyonSpec::enabled(SpecId::REGOLITH));
assert!(CanyonSpec::enabled(SpecId::CANYON));
}

#[test]
fn test_canyon_post_merge_hardforks_spec_id() {
assert!(SpecId::enabled(SpecId::CANYON, SpecId::MERGE));
assert!(SpecId::enabled(SpecId::CANYON, SpecId::SHANGHAI));
assert!(!SpecId::enabled(SpecId::CANYON, SpecId::CANCUN));
assert!(!SpecId::enabled(SpecId::CANYON, SpecId::LATEST));
assert!(SpecId::enabled(SpecId::CANYON, SpecId::BEDROCK));
assert!(SpecId::enabled(SpecId::CANYON, SpecId::REGOLITH));
assert!(SpecId::enabled(SpecId::CANYON, SpecId::CANYON));
}
}
2 changes: 2 additions & 0 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,8 @@ pub fn new_evm<'a, DB: Database>(
SpecId::BEDROCK => create_evm!(BedrockSpec),
#[cfg(feature = "optimism")]
SpecId::REGOLITH => create_evm!(RegolithSpec),
#[cfg(feature = "optimism")]
SpecId::CANYON => create_evm!(CanyonSpec),
}
}

Expand Down

0 comments on commit 513862b

Please sign in to comment.