Skip to content

Commit

Permalink
feat(EOF): Bytecode::new_raw supports EOF, new_raw_checked added (#1607)
Browse files Browse the repository at this point in the history
* feat(EOF): Bytecode::new_raw supports EOF, new_raw_checked added

* Use from abbreviation
  • Loading branch information
rakita authored Jul 12, 2024
1 parent 441c105 commit 81acfe3
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 25 deletions.
18 changes: 7 additions & 11 deletions bins/revme/src/cmd/evmrunner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use revm::{
db::BenchmarkDB,
inspector_handle_register,
inspectors::TracerEip3155,
primitives::{Address, Bytecode, TxKind},
primitives::{eof::EofDecodeError, Address, Bytecode, TxKind},
Evm,
};
use std::io::Error as IoError;
Expand All @@ -24,13 +24,9 @@ pub enum Errors {
#[error("EVM Error")]
EVMError,
#[error(transparent)]
Io(IoError),
}

impl From<IoError> for Errors {
fn from(e: IoError) -> Self {
Errors::Io(e)
}
Io(#[from] IoError),
#[error(transparent)]
EofError(#[from] EofDecodeError),
}

/// Evm runner command allows running arbitrary evm bytecode.
Expand Down Expand Up @@ -59,7 +55,7 @@ pub struct Cmd {
}

impl Cmd {
/// Run statetest command.
/// Run evm runner command.
pub fn run(&self) -> Result<(), Errors> {
let bytecode_str: Cow<'_, str> = if let Some(path) = &self.path {
// check if path exists.
Expand All @@ -78,9 +74,9 @@ impl Cmd {
// BenchmarkDB is dummy state that implements Database trait.
// the bytecode is deployed at zero address.
let mut evm = Evm::builder()
.with_db(BenchmarkDB::new_bytecode(Bytecode::new_raw(
.with_db(BenchmarkDB::new_bytecode(Bytecode::new_raw_checked(
bytecode.into(),
)))
)?))
.modify_tx_env(|tx| {
// execution globals block hash/gas_limit/coinbase/timestamp..
tx.caller = "0x0000000000000000000000000000000000000001"
Expand Down
11 changes: 3 additions & 8 deletions bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use revm::{
inspector_handle_register,
inspectors::TracerEip3155,
primitives::{
calc_excess_blob_gas, keccak256, Bytecode, Bytes, EVMResultGeneric, Env, Eof,
ExecutionResult, SpecId, TxKind, B256, EOF_MAGIC_BYTES,
calc_excess_blob_gas, keccak256, Bytecode, Bytes, EVMResultGeneric, Env, ExecutionResult,
SpecId, TxKind, B256,
},
Evm, State,
};
Expand Down Expand Up @@ -258,12 +258,7 @@ pub fn execute_test_suite(
let mut cache_state = revm::CacheState::new(false);
for (address, info) in unit.pre {
let code_hash = keccak256(&info.code);
let bytecode = match info.code.get(..2) {
Some(magic) if magic == &EOF_MAGIC_BYTES => {
Bytecode::Eof(Eof::decode(info.code.clone()).unwrap().into())
}
_ => Bytecode::new_raw(info.code),
};
let bytecode = Bytecode::new_raw(info.code);
let acc_info = revm::primitives::AccountInfo {
balance: info.balance,
code_hash,
Expand Down
19 changes: 18 additions & 1 deletion crates/primitives/src/bytecode.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod eof;
pub mod legacy;

use eof::EofDecodeError;
pub use eof::{Eof, EOF_MAGIC, EOF_MAGIC_BYTES, EOF_MAGIC_HASH};
pub use legacy::{JumpTable, LegacyAnalyzedBytecode};
use std::sync::Arc;
Expand Down Expand Up @@ -68,9 +69,25 @@ impl Bytecode {
}

/// Creates a new raw [`Bytecode`].
///
/// # Panics
///
/// Panics if bytecode is EOF and has incorrect format.
#[inline]
pub fn new_raw(bytecode: Bytes) -> Self {
Self::LegacyRaw(bytecode)
Self::new_raw_checked(bytecode).expect("Expect correct EOF bytecode")
}

/// Creates a new raw [`Bytecode`].
///
/// Returns an error on incorrect EOF format.
#[inline]
pub fn new_raw_checked(bytecode: Bytes) -> Result<Self, EofDecodeError> {
if bytecode.get(..2) == Some(&[0xEF, 00]) {
Ok(Self::Eof(Arc::new(Eof::decode(bytecode)?)))
} else {
Ok(Self::LegacyRaw(bytecode))
}
}

/// Create new checked bytecode.
Expand Down
32 changes: 31 additions & 1 deletion crates/primitives/src/bytecode/eof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub use types_section::TypesSection;

use crate::{b256, bytes, Bytes, B256};
use core::cmp::min;
use std::{vec, vec::Vec};
use std::{fmt, vec, vec::Vec};

/// Hash of EF00 bytes that is used for EXTCODEHASH when called from legacy bytecode.
pub const EOF_MAGIC_HASH: B256 =
Expand Down Expand Up @@ -157,6 +157,36 @@ pub enum EofDecodeError {
TooManyContainerSections,
}

impl fmt::Display for EofDecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
EofDecodeError::MissingInput => "Short input while processing EOF",
EofDecodeError::MissingBodyWithoutData => "Short body while processing EOF",
EofDecodeError::DanglingData => "Body size is more than specified in the header",
EofDecodeError::InvalidTypesSection => "Invalid types section data",
EofDecodeError::InvalidTypesSectionSize => "Invalid types section size",
EofDecodeError::InvalidEOFMagicNumber => "Invalid EOF magic number",
EofDecodeError::InvalidEOFVersion => "Invalid EOF version",
EofDecodeError::InvalidTypesKind => "Invalid number for types kind",
EofDecodeError::InvalidCodeKind => "Invalid number for code kind",
EofDecodeError::InvalidTerminalByte => "Invalid terminal code",
EofDecodeError::InvalidDataKind => "Invalid data kind",
EofDecodeError::InvalidKindAfterCode => "Invalid kind after code",
EofDecodeError::MismatchCodeAndTypesSize => "Mismatch of code and types sizes",
EofDecodeError::NonSizes => "There should be at least one size",
EofDecodeError::ShortInputForSizes => "Missing size",
EofDecodeError::ZeroSize => "Size cant be zero",
EofDecodeError::TooManyCodeSections => "Invalid code number",
EofDecodeError::ZeroCodeSections => "Invalid number of code sections",
EofDecodeError::TooManyContainerSections => "Invalid container number",
};
f.write_str(s)
}
}

#[cfg(feature = "std")]
impl std::error::Error for EofDecodeError {}

#[cfg(test)]
mod test {

Expand Down
8 changes: 4 additions & 4 deletions crates/revm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ mod test {

#[test]
fn simple_add_stateful_instruction() {
let code = Bytecode::new_raw([0xEF, 0x00].into());
let code = Bytecode::new_raw([0xED, 0x00].into());
let code_hash = code.hash_slow();
let to_addr = address!("ffffffffffffffffffffffffffffffffffffffff");

Expand Down Expand Up @@ -493,7 +493,7 @@ mod test {
// can insert the custom instruction as a boxed instruction
handler
.instruction_table
.insert_boxed(0xEF, custom_instruction);
.insert_boxed(0xED, custom_instruction);
}))
.build();

Expand All @@ -514,7 +514,7 @@ mod test {
gas!(interp, CUSTOM_INSTRUCTION_COST);
}

let code = Bytecode::new_raw([0xEF, 0x00].into());
let code = Bytecode::new_raw([0xED, 0x00].into());
let code_hash = code.hash_slow();
let to_addr = address!("ffffffffffffffffffffffffffffffffffffffff");

Expand All @@ -525,7 +525,7 @@ mod test {
})
.modify_tx_env(|tx| tx.transact_to = TxKind::Call(to_addr))
.append_handler_register(|handler| {
handler.instruction_table.insert(0xEF, custom_instruction)
handler.instruction_table.insert(0xED, custom_instruction)
})
.build();

Expand Down

0 comments on commit 81acfe3

Please sign in to comment.