Skip to content

Commit

Permalink
wip: EXTCODECOPY, EXTCODEHASH, EXTCODESIZE integration
Browse files Browse the repository at this point in the history
  • Loading branch information
fborello-lambda committed Jan 14, 2025
1 parent 7085718 commit 985be97
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 33 deletions.
62 changes: 42 additions & 20 deletions crates/vm/levm/src/opcode_handlers/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,20 @@ impl VM {

let (account_info, address_was_cold) = self.access_account(address);

self.increase_consumed_gas(current_call_frame, gas_cost::extcodesize(address_was_cold)?)?;
let (is_delegation, eip7702_gas_consumed, _, _) = self.eip7702_get_code(address)?;

current_call_frame
.stack
.push(account_info.bytecode.len().into())?;
self.increase_consumed_gas(
current_call_frame,
gas_cost::extcodesize(address_was_cold)? + eip7702_gas_consumed,
)?;

if is_delegation {
current_call_frame.stack.push(b"ef01".len().into())?;
} else {
current_call_frame
.stack
.push(account_info.bytecode.len().into())?;
}

Ok(OpcodeSuccess::Continue)
}
Expand All @@ -306,32 +315,34 @@ impl VM {

let new_memory_size = calculate_memory_size(dest_offset, size)?;

let (is_delegation, eip7702_gas_consumed, _, _) = self.eip7702_get_code(address)?;

self.increase_consumed_gas(
current_call_frame,
gas_cost::extcodecopy(
size,
new_memory_size,
current_call_frame.memory.len(),
address_was_cold,
)?,
)? + eip7702_gas_consumed,
)?;

if size == 0 {
return Ok(OpcodeSuccess::Continue);
}

let bytecode = if is_delegation {
"ef01".into()
} else {
account_info.bytecode
};

let mut data = vec![0u8; size];
if offset < account_info.bytecode.len().into() {
if offset < bytecode.len().into() {
let offset: usize = offset
.try_into()
.map_err(|_| VMError::Internal(InternalError::ConversionError))?;
for (i, byte) in account_info
.bytecode
.iter()
.skip(offset)
.take(size)
.enumerate()
{
for (i, byte) in bytecode.iter().skip(offset).take(size).enumerate() {
if let Some(data_byte) = data.get_mut(i) {
*data_byte = *byte;
}
Expand Down Expand Up @@ -424,16 +435,27 @@ impl VM {

let (account_info, address_was_cold) = self.access_account(address);

self.increase_consumed_gas(current_call_frame, gas_cost::extcodehash(address_was_cold)?)?;
let (is_delegation, eip7702_gas_consumed, _, _) = self.eip7702_get_code(address)?;

// An account is considered empty when it has no code and zero nonce and zero balance. [EIP-161]
if account_info.is_empty() {
current_call_frame.stack.push(U256::zero())?;
return Ok(OpcodeSuccess::Continue);
self.increase_consumed_gas(
current_call_frame,
gas_cost::extcodehash(address_was_cold)? + eip7702_gas_consumed,
)?;

if is_delegation {
let hash = U256::from_big_endian(keccak(b"ef01").as_fixed_bytes());
current_call_frame.stack.push(hash)?;
} else {
// An account is considered empty when it has no code and zero nonce and zero balance. [EIP-161]
if account_info.is_empty() {
current_call_frame.stack.push(U256::zero())?;
return Ok(OpcodeSuccess::Continue);
}

let hash = U256::from_big_endian(keccak(account_info.bytecode).as_fixed_bytes());
current_call_frame.stack.push(hash)?;
}

let hash = U256::from_big_endian(keccak(account_info.bytecode).as_fixed_bytes());
current_call_frame.stack.push(hash)?;
Ok(OpcodeSuccess::Continue)
}
}
26 changes: 13 additions & 13 deletions crates/vm/levm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1428,19 +1428,19 @@ impl VM {
Ok(())
}

// Used for the opcodes
// The following reading instructions are impacted:
// EXTCODESIZE, EXTCODECOPY, EXTCODEHASH
// and the following executing instructions are impacted:
// CALL, CALLCODE, STATICCALL, DELEGATECALL
// In case a delegation designator points to another designator,
// creating a potential chain or loop of designators,
// clients must retrieve only the first code and then stop following the designator chain.

// For example,
// EXTCODESIZE would return 2 (the size of 0xef01) instead of 23 which would represent the delegation designation,
// EXTCODEHASH would return 0xeadcdba66a79ab5dce91622d1d75c8cff5cff0b96944c3bf1072cd08ce018329 (keccak256(0xef01)), and
// CALL would load the code from address and execute it in the context of authority.
/// Used for the opcodes
/// The following reading instructions are impacted:
/// EXTCODESIZE, EXTCODECOPY, EXTCODEHASH
/// and the following executing instructions are impacted:
/// CALL, CALLCODE, STATICCALL, DELEGATECALL
/// In case a delegation designator points to another designator,
/// creating a potential chain or loop of designators,
/// clients must retrieve only the first code and then stop following the designator chain.
///
/// For example,
/// EXTCODESIZE would return 2 (the size of 0xef01) instead of 23 which would represent the delegation designation,
/// EXTCODEHASH would return 0xeadcdba66a79ab5dce91622d1d75c8cff5cff0b96944c3bf1072cd08ce018329 (keccak256(0xef01)), and
/// CALL would load the code from address and execute it in the context of authority.
pub fn eip7702_get_code(
&mut self,
address: Address,
Expand Down

0 comments on commit 985be97

Please sign in to comment.