diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 232d61f66d..f0c9b1ae19 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -1,10 +1,10 @@ pub mod eof; pub mod legacy; -pub use eof::Eof; +pub use eof::{Eof, EofDecodeError}; pub use legacy::{JumpTable, LegacyAnalyzedBytecode}; -use crate::{keccak256, Bytes, B256, KECCAK_EMPTY}; +use crate::{keccak256, Bytes, B256, EOF_PREFIX, EOF_VERSION, KECCAK_EMPTY}; /// State of the [`Bytecode`] analysis. #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -66,10 +66,35 @@ impl Bytecode { matches!(self, Self::Eof(_)) } + /// Create a new legacy raw [`Bytecode`]. + pub fn new_legacy(bytecode: Bytes) -> Self { + Self::LegacyRaw(bytecode) + } + + /// Checks if the bytecode starts with the EOF prefix followed by the correct version. + #[inline] + pub fn is_eof_format(bytes: &Bytes) -> bool { + if bytes.len() >= 3 { + let prefix = u16::from_be_bytes([bytes[0], bytes[1]]); + let version = bytes[2]; + + prefix == EOF_PREFIX && version == EOF_VERSION + } else { + false + } + } + /// Creates a new raw [`Bytecode`]. #[inline] pub fn new_raw(bytecode: Bytes) -> Self { - Self::LegacyRaw(bytecode) + if Self::is_eof_format(&bytecode) { + Eof::decode(bytecode.clone()) + .map(Self::Eof) + .unwrap_or_else(|_| Self::LegacyRaw(bytecode)) + } else { + // If not EOF format, use as legacy raw bytecode + Self::LegacyRaw(bytecode) + } } /// Create new checked bytecode. diff --git a/crates/primitives/src/constants.rs b/crates/primitives/src/constants.rs index c8223300bf..c3aa551ac8 100644 --- a/crates/primitives/src/constants.rs +++ b/crates/primitives/src/constants.rs @@ -60,3 +60,10 @@ pub const BLOB_GASPRICE_UPDATE_FRACTION: u64 = 3338477; /// First version of the blob. pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01; + +/// EOF prefix as per EIP-3540. +pub const EOF_PREFIX: u16 = 0xEF00; + +/// Version byte that immediately follows the EOF prefix in EIP-3540. +// See https://github.com/bluealloy/revm/issues/1464 +pub const EOF_VERSION: u8 = 0x01;