Skip to content

Commit

Permalink
feat(EOF): EXTCODECOPY,EXTCODESIZE,EXTCODEHASH eof support (#1504)
Browse files Browse the repository at this point in the history
* feat(EOF): EXTCODECOPY,EXTCODESIZE,EXTCODEHASH eof support

* eof magic bytes from array

* clippy
  • Loading branch information
rakita authored Jun 10, 2024
1 parent e244ac4 commit 649b7c5
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 15 deletions.
4 changes: 2 additions & 2 deletions crates/interpreter/src/host.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::primitives::{Address, Bytecode, Env, Log, B256, U256};
use crate::primitives::{Address, Bytes, Env, Log, B256, U256};

mod dummy;
pub use dummy::DummyHost;
Expand All @@ -23,7 +23,7 @@ pub trait Host {
fn balance(&mut self, address: Address) -> Option<(U256, bool)>;

/// Get code of `address` and if the account is cold.
fn code(&mut self, address: Address) -> Option<(Bytecode, bool)>;
fn code(&mut self, address: Address) -> Option<(Bytes, bool)>;

/// Get code hash of `address` and if the account is cold.
fn code_hash(&mut self, address: Address) -> Option<(B256, bool)>;
Expand Down
7 changes: 3 additions & 4 deletions crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::primitives::{hash_map::Entry, Bytecode, HashMap, U256};
use crate::{
primitives::{Address, Env, Log, B256, KECCAK_EMPTY},
primitives::{hash_map::Entry, Address, Bytes, Env, HashMap, Log, B256, KECCAK_EMPTY, U256},
Host, SStoreResult, SelfDestructResult,
};
use std::vec::Vec;
Expand Down Expand Up @@ -61,8 +60,8 @@ impl Host for DummyHost {
}

#[inline]
fn code(&mut self, _address: Address) -> Option<(Bytecode, bool)> {
Some((Bytecode::default(), false))
fn code(&mut self, _address: Address) -> Option<(Bytes, bool)> {
Some((Bytes::default(), false))
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion crates/interpreter/src/instructions/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub fn extcodecopy<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter,
// Note: this can't panic because we resized memory to fit.
interpreter
.shared_memory
.set_data(memory_offset, code_offset, len, &code.original_bytes());
.set_data(memory_offset, code_offset, len, &code);
}

pub fn blockhash<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
Expand Down
2 changes: 1 addition & 1 deletion crates/primitives/src/bytecode.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub mod eof;
pub mod legacy;

pub use eof::Eof;
pub use eof::{Eof, EOF_MAGIC, EOF_MAGIC_BYTES, EOF_MAGIC_HASH};
pub use legacy::{JumpTable, LegacyAnalyzedBytecode};

use crate::{keccak256, Bytes, B256, KECCAK_EMPTY};
Expand Down
12 changes: 11 additions & 1 deletion crates/primitives/src/bytecode/eof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@ pub use body::EofBody;
pub use header::EofHeader;
pub use types_section::TypesSection;

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

/// Hash of EF00 bytes that is used for EXTCODEHASH when called from legacy bytecode.
pub const EOF_MAGIC_HASH: B256 =
b256!("9dbf3648db8210552e9c4f75c6a1c3057c0ca432043bd648be15fe7be05646f5");

/// EOF Magic in u16 form.
pub const EOF_MAGIC: u16 = 0xEF00;

/// EOF magic number in array form.
pub static EOF_MAGIC_BYTES: Bytes = bytes!("ef00");

/// EOF - Ethereum Object Format.
///
/// It consist of a header, body and raw original bytes Specified in EIP.
Expand Down
4 changes: 2 additions & 2 deletions crates/revm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use revm_interpreter::as_usize_saturated;
use crate::{
db::{Database, EmptyDB},
interpreter::{Host, LoadAccountResult, SStoreResult, SelfDestructResult},
primitives::{Address, Bytecode, Env, HandlerCfg, Log, B256, BLOCK_HASH_HISTORY, U256},
primitives::{Address, Bytes, Env, HandlerCfg, Log, B256, BLOCK_HASH_HISTORY, U256},
};
use std::boxed::Box;

Expand Down Expand Up @@ -146,7 +146,7 @@ impl<EXT, DB: Database> Host for Context<EXT, DB> {
.ok()
}

fn code(&mut self, address: Address) -> Option<(Bytecode, bool)> {
fn code(&mut self, address: Address) -> Option<(Bytes, bool)> {
self.evm
.code(address)
.map_err(|e| self.evm.error = Err(e))
Expand Down
24 changes: 20 additions & 4 deletions crates/revm/src/context/inner_evm_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
keccak256, Account, Address, AnalysisKind, Bytecode, Bytes, CreateScheme, EVMError, Env,
Eof, HashSet, Spec,
SpecId::{self, *},
B256, U256,
B256, EOF_MAGIC_BYTES, EOF_MAGIC_HASH, U256,
},
FrameOrResult, JournalCheckpoint, CALL_STACK_LIMIT,
};
Expand Down Expand Up @@ -160,21 +160,37 @@ impl<DB: Database> InnerEvmContext<DB> {
.map(|(acc, is_cold)| (acc.info.balance, is_cold))
}

/// Return account code and if address is cold loaded.
/// Return account code bytes and if address is cold loaded.
///
/// In case of EOF account it will return `EOF_MAGIC` (0xEF00) as code.
#[inline]
pub fn code(&mut self, address: Address) -> Result<(Bytecode, bool), EVMError<DB::Error>> {
pub fn code(&mut self, address: Address) -> Result<(Bytes, bool), EVMError<DB::Error>> {
self.journaled_state
.load_code(address, &mut self.db)
.map(|(a, is_cold)| (a.info.code.clone().unwrap(), is_cold))
.map(|(a, is_cold)| {
// SAFETY: safe to unwrap as load_code will insert code if it is empty.
let code = a.info.code.as_ref().unwrap();
if code.is_eof() {
(EOF_MAGIC_BYTES.clone(), is_cold)
} else {
(code.original_bytes().clone(), is_cold)
}
})
}

/// Get code hash of address.
///
/// In case of EOF account it will return `EOF_MAGIC_HASH`
/// (the hash of `0xEF00`).
#[inline]
pub fn code_hash(&mut self, address: Address) -> Result<(B256, bool), EVMError<DB::Error>> {
let (acc, is_cold) = self.journaled_state.load_code(address, &mut self.db)?;
if acc.is_empty() {
return Ok((B256::ZERO, is_cold));
}
if let Some(true) = acc.info.code.as_ref().map(|code| code.is_eof()) {
return Ok((EOF_MAGIC_HASH, is_cold));
}
Ok((acc.info.code_hash, is_cold))
}

Expand Down

0 comments on commit 649b7c5

Please sign in to comment.