diff --git a/Cargo.lock b/Cargo.lock index 148e67d1ce..856b8c97b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3150,6 +3150,7 @@ dependencies = [ "aurora-engine-modexp", "blst", "c-kzg", + "cfg-if", "criterion", "eyre", "k256", diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index 0f12903a09..47b399b5b1 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -35,7 +35,7 @@ pub enum InstructionResult { OpcodeNotFound, CallNotAllowedInsideStatic, StateChangeDuringStaticCall, - InvalidEFOpcode, + InvalidFEOpcode, InvalidJump, NotActivated, StackUnderflow, @@ -89,7 +89,7 @@ impl From for InstructionResult { OutOfGasError::Precompile => Self::PrecompileOOG, }, HaltReason::OpcodeNotFound => Self::OpcodeNotFound, - HaltReason::InvalidEFOpcode => Self::InvalidEFOpcode, + HaltReason::InvalidFEOpcode => Self::InvalidFEOpcode, HaltReason::InvalidJump => Self::InvalidJump, HaltReason::NotActivated => Self::NotActivated, HaltReason::StackOverflow => Self::StackOverflow, @@ -149,7 +149,7 @@ macro_rules! return_error { | InstructionResult::OpcodeNotFound | InstructionResult::CallNotAllowedInsideStatic | InstructionResult::StateChangeDuringStaticCall - | InstructionResult::InvalidEFOpcode + | InstructionResult::InvalidFEOpcode | InstructionResult::InvalidJump | InstructionResult::NotActivated | InstructionResult::StackUnderflow @@ -286,7 +286,7 @@ impl From for SuccessOrHalt { InstructionResult::StateChangeDuringStaticCall => { Self::Halt(HaltReason::StateChangeDuringStaticCall) } - InstructionResult::InvalidEFOpcode => Self::Halt(HaltReason::InvalidEFOpcode), + InstructionResult::InvalidFEOpcode => Self::Halt(HaltReason::InvalidFEOpcode), InstructionResult::InvalidJump => Self::Halt(HaltReason::InvalidJump), InstructionResult::NotActivated => Self::Halt(HaltReason::NotActivated), InstructionResult::StackUnderflow => Self::Halt(HaltReason::StackUnderflow), @@ -373,7 +373,7 @@ mod tests { InstructionResult::OpcodeNotFound, InstructionResult::CallNotAllowedInsideStatic, InstructionResult::StateChangeDuringStaticCall, - InstructionResult::InvalidEFOpcode, + InstructionResult::InvalidFEOpcode, InstructionResult::InvalidJump, InstructionResult::NotActivated, InstructionResult::StackUnderflow, diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 3bf4e43514..4aacffd9e4 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -194,7 +194,7 @@ pub fn stop(interpreter: &mut Interpreter, _host: &mut H) { /// Invalid opcode. This opcode halts the execution. pub fn invalid(interpreter: &mut Interpreter, _host: &mut H) { - interpreter.instruction_result = InstructionResult::InvalidEFOpcode; + interpreter.instruction_result = InstructionResult::InvalidFEOpcode; } /// Unknown opcode. This opcode halts the execution. diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index b27ef6f3be..9d6ff02f10 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -7,6 +7,7 @@ license = "MIT" name = "revm-precompile" repository = "https://github.com/bluealloy/revm" version = "8.0.0" +readme = "../../README.md" [package.metadata.docs.rs] all-features = true @@ -54,6 +55,9 @@ p256 = { version = "0.13.2", optional = true, default-features = false, features "ecdsa", ] } +# utils +cfg-if = { version = "1.0", default-features = false } + [dev-dependencies] criterion = "0.5" rand = { version = "0.8", features = ["std"] } diff --git a/crates/precompile/src/fatal_precompile.rs b/crates/precompile/src/fatal_precompile.rs new file mode 100644 index 0000000000..4dfaee8db3 --- /dev/null +++ b/crates/precompile/src/fatal_precompile.rs @@ -0,0 +1,35 @@ +use crate::primitives::{ + Address, Bytes, Env, Precompile, PrecompileErrors, PrecompileResult, StatefulPrecompile, +}; +use crate::PrecompileWithAddress; +use std::{string::String, sync::Arc}; + +/// Disable kzg precompile. This will return Fatal error on precompile call +pub fn fatal_precompile(address: Address, msg: String) -> PrecompileWithAddress { + PrecompileWithAddress(address, FatalPrecompile::new_precompile(msg)) +} + +/// Fatal precompile that returns Fatal error on precompile call +pub struct FatalPrecompile { + msg: String, +} + +impl FatalPrecompile { + /// Create a new fatal precompile + pub fn new(msg: String) -> Self { + Self { msg } + } + + /// Create a new stateful fatal precompile + pub fn new_precompile(msg: String) -> Precompile { + Precompile::Stateful(Arc::new(Self::new(msg))) + } +} + +impl StatefulPrecompile for FatalPrecompile { + fn call(&self, _: &Bytes, _: u64, _: &Env) -> PrecompileResult { + Err(PrecompileErrors::Fatal { + msg: self.msg.clone(), + }) + } +} diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 1425f3421a..fbd8e69cbc 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -12,6 +12,7 @@ pub mod blake2; #[cfg(feature = "blst")] pub mod bls12_381; pub mod bn128; +pub mod fatal_precompile; pub mod hash; pub mod identity; #[cfg(feature = "c-kzg")] @@ -22,14 +23,18 @@ pub mod secp256k1; pub mod secp256r1; pub mod utilities; -use core::hash::Hash; -use once_cell::race::OnceBox; -#[doc(hidden)] -pub use revm_primitives as primitives; -pub use revm_primitives::{ +pub use fatal_precompile::fatal_precompile; + +pub use primitives::{ precompile::{PrecompileError as Error, *}, Address, Bytes, HashMap, HashSet, Log, B256, }; +#[doc(hidden)] +pub use revm_primitives as primitives; + +use cfg_if::cfg_if; +use core::hash::Hash; +use once_cell::race::OnceBox; use std::{boxed::Box, vec::Vec}; pub fn calc_linear_cost_u32(len: usize, base: u64, word: u64) -> u64 { @@ -133,18 +138,21 @@ impl Precompiles { pub fn cancun() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::berlin().clone(); + let mut precompiles = Self::berlin().clone(); + + // EIP-4844: Shard Blob Transactions + cfg_if! { + if #[cfg(feature = "c-kzg")] { + let precompile = kzg_point_evaluation::POINT_EVALUATION.clone(); + } else { + // TODO move constants to separate file. + let precompile = fatal_precompile(u64_to_address(0x0A), "c-kzg feature is not enabled".into()); + } + } - // Don't include KZG point evaluation precompile in no_std builds. - #[cfg(feature = "c-kzg")] - let precompiles = { - let mut precompiles = precompiles; - precompiles.extend([ - // EIP-4844: Shard Blob Transactions - kzg_point_evaluation::POINT_EVALUATION, - ]); - precompiles - }; + precompiles.extend([ + precompile, + ]); Box::new(precompiles) }) diff --git a/crates/primitives/src/result.rs b/crates/primitives/src/result.rs index 4d4886d6c1..f6c883da32 100644 --- a/crates/primitives/src/result.rs +++ b/crates/primitives/src/result.rs @@ -424,7 +424,7 @@ pub enum SuccessReason { pub enum HaltReason { OutOfGas(OutOfGasError), OpcodeNotFound, - InvalidEFOpcode, + InvalidFEOpcode, InvalidJump, NotActivated, StackUnderflow,