diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 828e6112f8..dd434fcd27 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,7 +1,7 @@ use super::constants::*; use crate::{ num_words, - primitives::{Address, Bytes, SpecId, U256}, + primitives::{Address, SpecId, U256}, SelfDestructResult, }; use std::vec::Vec; @@ -358,18 +358,10 @@ pub fn validate_initial_tx_gas( input: &[u8], is_create: bool, access_list: &[(Address, Vec)], - initcodes: &[Bytes], ) -> u64 { let mut initial_gas = 0; - let mut zero_data_len = input.iter().filter(|v| **v == 0).count() as u64; - let mut non_zero_data_len = input.len() as u64 - zero_data_len; - - // Enabling of initcode is checked in `validate_env` handler. - for initcode in initcodes { - let zeros = initcode.iter().filter(|v| **v == 0).count() as u64; - zero_data_len += zeros; - non_zero_data_len += initcode.len() as u64 - zeros; - } + let zero_data_len = input.iter().filter(|v| **v == 0).count() as u64; + let non_zero_data_len = input.len() as u64 - zero_data_len; // initdate stipend initial_gas += zero_data_len * TRANSACTION_ZERO_DATA; @@ -403,7 +395,7 @@ pub fn validate_initial_tx_gas( }; // EIP-3860: Limit and meter initcode - // Initcode stipend for bytecode analysis + // Init code stipend for bytecode analysis if spec_id.is_enabled_in(SpecId::SHANGHAI) && is_create { initial_gas += initcode_cost(input.len() as u64) } diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index c3f701f28a..c0cc0cf0bd 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -6,11 +6,10 @@ pub use call_helpers::{ use revm_primitives::{keccak256, BerlinSpec}; use crate::{ - analysis::validate_eof, - gas::{self, cost_per_word, BASE, EOF_CREATE_GAS, KECCAK256WORD}, + gas::{self, cost_per_word, EOF_CREATE_GAS, KECCAK256WORD}, instructions::utility::read_u16, interpreter::Interpreter, - primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, + primitives::{Address, Bytes, Eof, Spec, SpecId::*, U256}, CallInputs, CallScheme, CallValue, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, InterpreterAction, InterpreterResult, LoadAccountResult, MAX_INITCODE_SIZE, }; @@ -91,85 +90,6 @@ pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; } -pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { - require_eof!(interpreter); - gas!(interpreter, EOF_CREATE_GAS); - pop!( - interpreter, - tx_initcode_hash, - value, - salt, - data_offset, - data_size - ); - let tx_initcode_hash = B256::from(tx_initcode_hash); - - // resize memory and get return range. - let Some(return_range) = resize_memory(interpreter, data_offset, data_size) else { - return; - }; - - // fetch initcode, if not found push ZERO. - let Some(initcode) = host - .env() - .tx - .eof_initcodes_hashed - .get(&tx_initcode_hash) - .cloned() - else { - push!(interpreter, U256::ZERO); - return; - }; - - // deduct gas for validation - gas_or_fail!(interpreter, cost_per_word(initcode.len() as u64, BASE)); - - // deduct gas for hash. TODO check order of actions. - gas_or_fail!( - interpreter, - cost_per_word(initcode.len() as u64, KECCAK256WORD) - ); - - let Ok(eof) = Eof::decode(initcode.clone()) else { - push!(interpreter, U256::ZERO); - return; - }; - - // Data section should be full, push zero to stack and return if not. - if !eof.body.is_data_filled { - push!(interpreter, U256::ZERO); - return; - } - - // Validate initcode - if validate_eof(&eof).is_err() { - push!(interpreter, U256::ZERO); - return; - } - - // Create new address. Gas for it is already deducted. - let created_address = interpreter - .contract - .caller - .create2(salt.to_be_bytes(), tx_initcode_hash); - - let gas_limit = interpreter.gas().remaining(); - // spend all gas. It will be reimbursed after frame returns. - gas!(interpreter, gas_limit); - - interpreter.next_action = InterpreterAction::EOFCreate { - inputs: Box::new(EOFCreateInput::new( - interpreter.contract.target_address, - created_address, - value, - eof, - gas_limit, - return_range, - )), - }; - interpreter.instruction_result = InstructionResult::CallOrCreate; -} - pub fn return_contract(interpreter: &mut Interpreter, _host: &mut H) { require_init_eof!(interpreter); let deploy_container_index = unsafe { read_u16(interpreter.instruction_pointer) }; diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 5114c2ae19..1bed9cb415 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -759,7 +759,7 @@ opcodes! { // 0xEA // 0xEB 0xEC => EOFCREATE => contract::eofcreate => stack_io(4, 1), immediate_size(1); - 0xED => TXCREATE => contract::txcreate => stack_io(5, 1); + // 0xED 0xEE => RETURNCONTRACT => contract::return_contract => stack_io(2, 0), immediate_size(1), terminating; // 0xEF 0xF0 => CREATE => contract::create:: => stack_io(3, 1), not_eof; diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index 99b5557149..44b0736977 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -3,8 +3,8 @@ pub mod handler_cfg; pub use handler_cfg::{CfgEnvWithHandlerCfg, EnvWithHandlerCfg, HandlerCfg}; use crate::{ - calc_blob_gasprice, Account, Address, Bytes, HashMap, InvalidHeader, InvalidTransaction, Spec, - SpecId, B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_BLOB_NUMBER_PER_BLOCK, MAX_INITCODE_SIZE, U256, + calc_blob_gasprice, Account, Address, Bytes, InvalidHeader, InvalidTransaction, Spec, SpecId, + B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_BLOB_NUMBER_PER_BLOCK, MAX_INITCODE_SIZE, U256, VERSIONED_HASH_VERSION_KZG, }; use core::cmp::{min, Ordering}; @@ -189,41 +189,6 @@ impl Env { } } - if SPEC::enabled(SpecId::PRAGUE) { - if !self.tx.eof_initcodes.is_empty() { - // If initcode is set other fields must be empty - if !self.tx.blob_hashes.is_empty() { - return Err(InvalidTransaction::BlobVersionedHashesNotSupported); - } - // EOF Create tx extends EIP-1559 tx. It must have max_fee_per_blob_gas - if self.tx.max_fee_per_blob_gas.is_some() { - return Err(InvalidTransaction::MaxFeePerBlobGasNotSupported); - } - // EOF Create must have a to address - if matches!(self.tx.transact_to, TransactTo::Call(_)) { - return Err(InvalidTransaction::EofCrateShouldHaveToAddress); - } - } else { - // If initcode is set check its bounds. - if self.tx.eof_initcodes.len() > 256 { - return Err(InvalidTransaction::EofInitcodesNumberLimit); - } - if self - .tx - .eof_initcodes_hashed - .iter() - .any(|(_, i)| i.len() >= MAX_INITCODE_SIZE) - { - return Err(InvalidTransaction::EofInitcodesSizeLimit); - } - } - } else { - // Initcode set when not supported. - if !self.tx.eof_initcodes.is_empty() { - return Err(InvalidTransaction::EofInitcodesNotSupported); - } - } - Ok(()) } @@ -584,20 +549,6 @@ pub struct TxEnv { /// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844 pub max_fee_per_blob_gas: Option, - /// EOF Initcodes for EOF CREATE transaction - /// - /// Incorporated as part of the Prague upgrade via [EOF] - /// - /// [EOF]: https://eips.ethereum.org/EIPS/eip-4844 - pub eof_initcodes: Vec, - - /// Internal Temporary field that stores the hashes of the EOF initcodes. - /// - /// Those are always cleared after the transaction is executed. - /// And calculated/overwritten every time transaction starts. - /// They are calculated from the [`Self::eof_initcodes`] field. - pub eof_initcodes_hashed: HashMap, - #[cfg_attr(feature = "serde", serde(flatten))] #[cfg(feature = "optimism")] /// Optimism fields. @@ -642,8 +593,6 @@ impl Default for TxEnv { access_list: Vec::new(), blob_hashes: Vec::new(), max_fee_per_blob_gas: None, - eof_initcodes: Vec::new(), - eof_initcodes_hashed: HashMap::new(), #[cfg(feature = "optimism")] optimism: OptimismFields::default(), } diff --git a/crates/primitives/src/result.rs b/crates/primitives/src/result.rs index 659c4fe357..d5a0f90fa9 100644 --- a/crates/primitives/src/result.rs +++ b/crates/primitives/src/result.rs @@ -248,12 +248,6 @@ pub enum InvalidTransaction { }, /// Blob transaction contains a versioned hash with an incorrect version BlobVersionNotSupported, - /// EOF TxCreate transaction is not supported before Prague hardfork. - EofInitcodesNotSupported, - /// EOF TxCreate transaction max initcode number reached. - EofInitcodesNumberLimit, - /// EOF initcode in TXCreate is too large. - EofInitcodesSizeLimit, /// EOF crate should have `to` address EofCrateShouldHaveToAddress, /// System transactions are not supported post-regolith hardfork. @@ -346,10 +340,7 @@ impl fmt::Display for InvalidTransaction { write!(f, "too many blobs, have {have}, max {max}") } Self::BlobVersionNotSupported => write!(f, "blob version not supported"), - Self::EofInitcodesNotSupported => write!(f, "EOF initcodes not supported"), Self::EofCrateShouldHaveToAddress => write!(f, "EOF crate should have `to` address"), - Self::EofInitcodesSizeLimit => write!(f, "EOF initcodes size limit"), - Self::EofInitcodesNumberLimit => write!(f, "EOF initcodes number limit"), #[cfg(feature = "optimism")] Self::DepositSystemTxPostRegolith => { write!( diff --git a/crates/revm/src/handler/mainnet/validation.rs b/crates/revm/src/handler/mainnet/validation.rs index 22dfb5f4bc..176e0e8282 100644 --- a/crates/revm/src/handler/mainnet/validation.rs +++ b/crates/revm/src/handler/mainnet/validation.rs @@ -42,10 +42,9 @@ pub fn validate_initial_tx_gas( let input = &env.tx.data; let is_create = env.tx.transact_to.is_create(); let access_list = &env.tx.access_list; - let initcodes = &env.tx.eof_initcodes; let initial_gas_spend = - gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list, initcodes); + gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list); // Additional check to see if limit is big enough to cover initial gas. if initial_gas_spend > env.tx.gas_limit {