From 1b04c9a2b2cd5ff7320e1835f9ef75dca6b78540 Mon Sep 17 00:00:00 2001 From: Emma Turner Date: Fri, 12 Jan 2024 10:35:00 +0000 Subject: [PATCH] Kernel/EVM: gas price should be of tx, not block --- etherlink/CHANGES_KERNEL.md | 2 + etherlink/kernel_evm/Cargo.lock | 1 + etherlink/kernel_evm/ethereum/Cargo.toml | 1 + etherlink/kernel_evm/ethereum/src/block.rs | 8 +- .../kernel_evm/ethereum/src/tx_common.rs | 18 ++++ .../kernel_evm/evm_evaluation/src/runner.rs | 3 +- .../kernel_evm/evm_execution/src/handler.rs | 67 +++++++++++- etherlink/kernel_evm/evm_execution/src/lib.rs | 102 +++++++++++++++--- .../evm_execution/src/precompiles.rs | 10 +- etherlink/kernel_evm/kernel/src/apply.rs | 84 +++++++++------ etherlink/kernel_evm/kernel/src/block.rs | 11 +- .../kernel/src/block_in_progress.rs | 9 +- etherlink/kernel_evm/kernel/src/simulation.rs | 12 ++- ...pha- Regression test for L2 block hash.out | 2 +- 14 files changed, 255 insertions(+), 75 deletions(-) diff --git a/etherlink/CHANGES_KERNEL.md b/etherlink/CHANGES_KERNEL.md index 9a63739ad69b..8b31c9767518 100644 --- a/etherlink/CHANGES_KERNEL.md +++ b/etherlink/CHANGES_KERNEL.md @@ -6,6 +6,8 @@ ### Bug fixes +- Fix minimum gas price used for charging fees: should be `base_fee_per_gas`, instead of `1 wei`. (!11509) + ### Breaking changes ### Internal diff --git a/etherlink/kernel_evm/Cargo.lock b/etherlink/kernel_evm/Cargo.lock index 601e953b519f..afb920e30914 100644 --- a/etherlink/kernel_evm/Cargo.lock +++ b/etherlink/kernel_evm/Cargo.lock @@ -1776,6 +1776,7 @@ dependencies = [ name = "tezos_ethereum" version = "0.1.0" dependencies = [ + "anyhow", "ethbloom", "ethereum", "hex", diff --git a/etherlink/kernel_evm/ethereum/Cargo.toml b/etherlink/kernel_evm/ethereum/Cargo.toml index 589dacd0c19c..e66988aff386 100644 --- a/etherlink/kernel_evm/ethereum/Cargo.toml +++ b/etherlink/kernel_evm/ethereum/Cargo.toml @@ -12,6 +12,7 @@ license = "MIT" [dependencies] thiserror.workspace = true +anyhow.workspace = true primitive-types.workspace = true ethereum.workspace = true diff --git a/etherlink/kernel_evm/ethereum/src/block.rs b/etherlink/kernel_evm/ethereum/src/block.rs index ae4a1073f93a..bedfc68382af 100644 --- a/etherlink/kernel_evm/ethereum/src/block.rs +++ b/etherlink/kernel_evm/ethereum/src/block.rs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022-2023 TriliTech +// SPDX-FileCopyrightText: 2022-2024 TriliTech // SPDX-FileCopyrightText: 2023 Nomadic Labs // // SPDX-License-Identifier: MIT @@ -19,11 +19,9 @@ use tezos_smart_rollup_encoding::timestamp::Timestamp; /// All data for an Ethereum block. /// -/// This data does not change for the duration of the block. All balues are +/// This data does not change for the duration of the block. All values are /// updated when the block is finalized and may change for the next block. pub struct BlockConstants { - /// Price of one unit of gas in Wei - pub gas_price: U256, /// The number of the current block pub number: U256, /// Who is the beneficiary of the current block @@ -46,7 +44,6 @@ impl BlockConstants { /// To be done in . pub fn first_block(timestamp: U256, chain_id: U256, base_fee_per_gas: U256) -> Self { Self { - gas_price: U256::one(), number: U256::zero(), coinbase: H160::zero(), timestamp, @@ -136,7 +133,6 @@ impl L2Block { pub fn constants(&self, chain_id: U256, base_fee_per_gas: U256) -> BlockConstants { let timestamp = U256::from(self.timestamp.as_u64()); BlockConstants { - gas_price: U256::one(), number: self.number, coinbase: H160::zero(), timestamp, diff --git a/etherlink/kernel_evm/ethereum/src/tx_common.rs b/etherlink/kernel_evm/ethereum/src/tx_common.rs index b176c1c6ff69..419fcf64d688 100644 --- a/etherlink/kernel_evm/ethereum/src/tx_common.rs +++ b/etherlink/kernel_evm/ethereum/src/tx_common.rs @@ -519,6 +519,24 @@ impl EthereumTransactionCommon { } } } + + /// Returns effective_gas_price of the transaction. + /// + /// For more details see [eip-1559](https://eips.ethereum.org/EIPS/eip-1559#specification). + pub fn effective_gas_price( + &self, + block_base_fee_per_gas: U256, + ) -> Result { + let priority_fee_per_gas = U256::min( + self.max_priority_fee_per_gas, + self.max_fee_per_gas + .checked_sub(block_base_fee_per_gas) + .ok_or_else(|| anyhow::anyhow!("Underflow when calculating gas price"))?, + ); + priority_fee_per_gas + .checked_add(block_base_fee_per_gas) + .ok_or_else(|| anyhow::anyhow!("Overflow")) + } } impl From for EthereumTransactionCommon { diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index e87f3c480aa2..a8ca910740cf 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: 2023 Functori // SPDX-FileCopyrightText: 2021-2023 draganrakita +// SPDX-FileCopyrightText: 2024 Trilitech // // SPDX-License-Identifier: MIT @@ -193,7 +194,6 @@ fn execute_transaction( env.tx.transact_to = unit.transaction.to; let block_constants = BlockConstants { - gas_price: env.tx.gas_price, number: env.block.number, coinbase: env.block.coinbase.to_fixed_bytes().into(), timestamp: env.block.timestamp, @@ -218,6 +218,7 @@ fn execute_transaction( caller, call_data, gas_limit, + env.tx.gas_price, transaction_value, pay_for_gas, u64::MAX, // don't account for ticks during the test diff --git a/etherlink/kernel_evm/evm_execution/src/handler.rs b/etherlink/kernel_evm/evm_execution/src/handler.rs index 59fda174cf99..e5924afe90c7 100644 --- a/etherlink/kernel_evm/evm_execution/src/handler.rs +++ b/etherlink/kernel_evm/evm_execution/src/handler.rs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022-2023 TriliTech +// SPDX-FileCopyrightText: 2022-2024 TriliTech // SPDX-FileCopyrightText: 2023 Functori // // SPDX-License-Identifier: MIT @@ -268,10 +268,13 @@ pub struct EvmHandler<'a, Host: Runtime> { /// Estimated ticks spent for the execution of the current transaction, /// according to the ticks per gas per opcode model pub estimated_ticks_used: u64, + /// The effective gas price of the current transaction + effective_gas_price: U256, } impl<'a, Host: Runtime> EvmHandler<'a, Host> { /// Create a new handler to suit a new, initial EVM call context + #[allow(clippy::too_many_arguments)] pub fn new( host: &'a mut Host, evm_account_storage: &'a mut EthereumAccountStorage, @@ -280,6 +283,7 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { config: &'a Config, precompiles: &'a dyn PrecompileSet, ticks_allocated: u64, + effective_gas_price: U256, ) -> Self { Self { host, @@ -291,6 +295,7 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { transaction_data: vec![], ticks_allocated, estimated_ticks_used: 0, + effective_gas_price, } } @@ -451,10 +456,11 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { &mut self, caller: H160, gas_limit: Option, + effective_gas_price: U256, ) -> Result { match gas_limit { Some(gas_limit) => { - let amount = U256::from(gas_limit) * self.block.gas_price; + let amount = U256::from(gas_limit).saturating_mul(effective_gas_price); log!( self.host, Debug, @@ -476,10 +482,11 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { &mut self, caller: H160, unused_gas: Option, + effective_gas_price: U256, ) -> Result<(), EthereumError> { match unused_gas { Some(unused_gas) => { - let amount = U256::from(unused_gas) * self.block.gas_price; + let amount = U256::from(unused_gas).saturating_mul(effective_gas_price); log!( self.host, Debug, @@ -1583,7 +1590,7 @@ impl<'a, Host: Runtime> Handler for EvmHandler<'a, Host> { } fn gas_price(&self) -> U256 { - self.block.gas_price + self.effective_gas_price } fn origin(&self) -> H160 { @@ -1889,6 +1896,8 @@ mod test { let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); + let gas_price = U256::from(21000); + // This is a randomly generated address. It has been used for testing legacy address // generation with zero nonce using Ethereum. To replicate (with new address): // - generate a fresh Ethereum account (on Rinkeby or other test net) @@ -1907,6 +1916,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let result = handler.create_address(CreateScheme::Legacy { caller }); @@ -1927,6 +1937,8 @@ mod test { let caller: H160 = H160::from_str("9bbfed6889322e016e0a02ee459d306fc19545d8").unwrap(); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -1935,6 +1947,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let code_hash: H256 = CODE_HASH_DEFAULT; @@ -1959,6 +1972,9 @@ mod test { let precompiles = precompiles::precompile_set::(); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); + + let gas_price = U256::from(21000); + let caller: H160 = H160::from_str("9bbfed6889322e016e0a02ee459d306fc19545d8").unwrap(); @@ -1970,6 +1986,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let code_hash: H256 = CODE_HASH_DEFAULT; @@ -2002,6 +2019,8 @@ mod test { // We use an origin distinct from caller for testing purposes let origin = H160::from_low_u64_be(117_u64); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2010,6 +2029,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let address = H160::from_low_u64_be(213_u64); @@ -2059,6 +2079,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(28349_u64); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2067,6 +2089,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let address = H160::from_low_u64_be(213_u64); @@ -2154,6 +2177,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(2340); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2162,6 +2187,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let input_value = U256::from(2026_u32); @@ -2255,6 +2281,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(8213); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2263,6 +2291,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let input_value = U256::from(1025_u32); // transaction depth for contract below is callarg - 1 @@ -2343,6 +2372,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(444); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2351,6 +2382,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let address = H160::from_low_u64_be(312); @@ -2410,6 +2442,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(117); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2418,6 +2452,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let value = U256::zero(); @@ -2463,6 +2498,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(118); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2471,6 +2508,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let address = H160::from_low_u64_be(117); @@ -2521,6 +2559,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2529,6 +2569,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let address = H160::from_low_u64_be(210_u64); @@ -2578,6 +2619,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2586,6 +2629,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let address = H160::from_low_u64_be(210_u64); @@ -2645,6 +2689,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); + let gas_price = U256::from(21000); + let handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2653,6 +2699,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let hash_of_unavailable_block = handler.block_hash(U256::zero()); @@ -2668,6 +2715,8 @@ mod test { let config = Config::london(); let caller = H160::from_low_u64_be(523_u64); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2676,6 +2725,7 @@ mod test { &config, &precompiles, 10_000, + gas_price, ); let address = H160::from_low_u64_be(210_u64); @@ -2724,6 +2774,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2732,6 +2784,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let address = H160::from_low_u64_be(210_u64); @@ -2771,6 +2824,8 @@ mod test { let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); + let gas_price = U256::from(21000); + let mut handler = EvmHandler::new( &mut mock_runtime, &mut evm_account_storage, @@ -2779,6 +2834,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let address = H160::from_low_u64_be(210_u64); @@ -2850,6 +2906,8 @@ mod test { let transaction_context = TransactionContext::new(caller, target_address, U256::zero()); + let gas_price = U256::from(21000); + // { (CALL 50000 0xec2c6832d00680ece8ff9254f81fdab0a5a2ac50 0 0 0 0 0) (MSTORE 0 0x6460016001556000526005601bf3) (CREATE2 0 18 14 0) } let input = hex::decode("6000600060006000600073e2b35478fdd26477cc576dd906e6277761246a3c61c350f1506000600060006000f500").unwrap(); @@ -2861,6 +2919,7 @@ mod test { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); // { (SELFDESTRUCT 0x10) } diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index 80b00d20ac34..4e56b4341655 100644 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022-2023 TriliTech +// SPDX-FileCopyrightText: 2022-2024 TriliTech // SPDX-FileCopyrightText: 2023 Functori // // SPDX-License-Identifier: MIT @@ -128,6 +128,7 @@ pub fn run_transaction<'a, Host>( caller: H160, call_data: Vec, gas_limit: Option, + effective_gas_price: U256, value: Option, pay_for_gas: bool, allocated_ticks: u64, @@ -152,9 +153,12 @@ where &config, precompiles, allocated_ticks, + effective_gas_price, ); - if (!pay_for_gas) || handler.pre_pay_transactions(caller, gas_limit)? { + if (!pay_for_gas) + || handler.pre_pay_transactions(caller, gas_limit, effective_gas_price)? + { let result = if let Some(address) = address { handler.call_contract(caller, address, value, call_data, gas_limit, false)? } else { @@ -166,7 +170,7 @@ where if do_refund(&result, pay_for_gas) { let unused_gas = gas_limit.map(|gl| gl - result.gas_used); - handler.repay_gas(caller, unused_gas)?; + handler.repay_gas(caller, unused_gas, effective_gas_price)?; } Ok(Some(result)) @@ -285,6 +289,7 @@ mod test { let call_data: Vec = vec![]; let transaction_value = U256::from(100_u32); let config = Config::shanghai(); + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -309,6 +314,7 @@ mod test { caller, call_data, Some(22000), + gas_price, Some(transaction_value), true, DUMMY_ALLOCATED_TICKS, @@ -348,6 +354,7 @@ mod test { let call_data: Vec = vec![]; let transaction_value = U256::from(100_u32); let config = Config::shanghai(); + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -372,6 +379,7 @@ mod test { caller, call_data, Some(21000), + gas_price, Some(transaction_value), true, DUMMY_ALLOCATED_TICKS, @@ -411,6 +419,7 @@ mod test { let caller = H160::from_low_u64_be(328794); let transaction_value = U256::from(100_u32); let call_data: Vec = hex::decode(STORAGE_CONTRACT_INITIALIZATION).unwrap(); + let gas_price = U256::from(21000); set_balance( &mut mock_runtime, @@ -429,6 +438,7 @@ mod test { caller, call_data, None, + gas_price, Some(transaction_value), true, DUMMY_ALLOCATED_TICKS, @@ -463,6 +473,7 @@ mod test { let caller = H160::from_low_u64_be(117); let transaction_value = U256::from(0); let call_data: Vec = hex::decode(STORAGE_CONTRACT_INITIALIZATION).unwrap(); + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -483,6 +494,7 @@ mod test { caller, call_data, Some(gas_limit), + gas_price, Some(transaction_value), true, DUMMY_ALLOCATED_TICKS, @@ -516,6 +528,7 @@ mod test { caller, call_data2, Some(31000), + gas_price, Some(U256::zero()), true, DUMMY_ALLOCATED_TICKS, @@ -543,6 +556,7 @@ mod test { caller, call_data_set, Some(100000), + gas_price, Some(U256::zero()), true, DUMMY_ALLOCATED_TICKS, @@ -569,6 +583,7 @@ mod test { caller, hex::decode(STORAGE_CONTRACT_CALL_NUM).unwrap(), Some(31000), + gas_price, Some(U256::zero()), true, DUMMY_ALLOCATED_TICKS, @@ -601,10 +616,11 @@ mod test { // gas_limit estimated using remix on shanghai network (1,631,430) // plus a 50% margin for gas accounting discrepancies let gas_limit = 2_400_000; + let gas_price = U256::from(21000); // the test is not to check that account can prepay, // so we can choose the balance depending on set gas limit - let balance = block.gas_price.saturating_mul(gas_limit.into()); + let balance = gas_price.saturating_mul(gas_limit.into()); set_balance( &mut mock_runtime, &mut evm_account_storage, @@ -621,6 +637,7 @@ mod test { caller, call_data, Some(gas_limit), + gas_price, Some(transaction_value), true, DUMMY_ALLOCATED_TICKS, @@ -651,6 +668,7 @@ mod test { // 0xFE, which is the designated INVALID opcode, so running this code // snippet must fail. let call_data: Vec = hex::decode("602e600055600054600154fe").unwrap(); + let gas_price = U256::from(21000); set_balance( &mut mock_runtime, @@ -669,6 +687,7 @@ mod test { caller, call_data, None, + gas_price, Some(transaction_value), true, DUMMY_ALLOCATED_TICKS, @@ -701,6 +720,7 @@ mod test { let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -720,6 +740,7 @@ mod test { caller, vec![], Some(22000), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -846,6 +867,7 @@ mod test { set_account_code(&mut mock_runtime, &mut evm_account_storage, &target, &code); let all_the_gas = 25_000; + let gas_price = U256::from(1); set_balance( &mut mock_runtime, &mut evm_account_storage, @@ -864,6 +886,7 @@ mod test { caller, vec![], Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -896,6 +919,7 @@ mod test { let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); + let gas_price = U256::from(1); let code = vec![ Opcode::PUSH1.as_u8(), 0u8, @@ -925,6 +949,7 @@ mod test { caller, vec![], Some(init_balance), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -950,9 +975,7 @@ mod test { // Some gas is returned to the send after the transaction is reverted assert_eq!( get_balance(&mut mock_runtime, &mut evm_account_storage, &caller), - block - .gas_price - .saturating_mul((init_balance - expected_gas).into()) + gas_price.saturating_mul((init_balance - expected_gas).into()) ) } @@ -965,6 +988,7 @@ mod test { let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); + let gas_price = U256::from(21000); let code = vec![ Opcode::INVALID.as_u8(), Opcode::PUSH1.as_u8(), @@ -987,6 +1011,7 @@ mod test { caller, vec![], None, + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -1014,6 +1039,7 @@ mod test { let precompiles = precompiles::precompile_set::(); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_low_u64_be(118_u64); + let gas_price = U256::from(21000); let address = H160::from_low_u64_be(117_u64); let code: Vec = vec![ @@ -1042,6 +1068,7 @@ mod test { caller, vec![], None, + gas_price, Some(U256::from(100)), true, DUMMY_ALLOCATED_TICKS, @@ -1079,6 +1106,7 @@ mod test { let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_low_u64_be(118u64); let data = [1u8; 32]; // Need some data to make it a contract call + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -1098,6 +1126,7 @@ mod test { caller, data.to_vec(), Some(22001), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -1136,12 +1165,14 @@ mod test { let target = H160::from_low_u64_be(1u64); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_low_u64_be(118u64); + let gas_price = U256::from(21000); + let gas_limit = 35000; set_balance( &mut mock_runtime, &mut evm_account_storage, &caller, - 35001.into(), + gas_price * gas_limit + U256::one(), ); // Act @@ -1154,7 +1185,8 @@ mod test { Some(target), caller, data.to_vec(), - Some(35000), + Some(gas_limit), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -1187,6 +1219,7 @@ mod test { let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); + let gas_price = U256::from(21000); let code = vec![ // Create a contract that creates an exception if first word of calldata is 0 @@ -1265,6 +1298,7 @@ mod test { caller, vec![], None, + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -1286,6 +1320,7 @@ mod test { let caller = H160::from_low_u64_be(118_u64); let static_call_target = H160::from_low_u64_be(200_u64); let all_the_gas = 2_000_000_u64; + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -1341,6 +1376,7 @@ mod test { caller, vec![], Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -1378,6 +1414,7 @@ mod test { let caller = H160::from_low_u64_be(118_u64); let static_call_target = H160::from_low_u64_be(200_u64); let all_the_gas = 2_000_000_u64; + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -1432,6 +1469,7 @@ mod test { caller, vec![], Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -1470,6 +1508,7 @@ mod test { let caller = H160::from_low_u64_be(118_u64); let call_target = H160::from_low_u64_be(200_u64); let all_the_gas = 2_000_000_u64; + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -1545,6 +1584,7 @@ mod test { caller, vec![], Some(all_the_gas), + gas_price, None, true, 1_000_000_000, @@ -1589,6 +1629,7 @@ mod test { let caller = H160::from_low_u64_be(118_u64); let static_call_target = H160::from_low_u64_be(200_u64); let all_the_gas = 2_000_000_u64; + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -1655,6 +1696,7 @@ mod test { caller, vec![], Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -1693,6 +1735,7 @@ mod test { let caller = H160::from_low_u64_be(115_u64); let selfdestructing_contract = H160::from_low_u64_be(100_u64); let all_the_gas = 1_000_000_u64; + let gas_price = U256::from(1); // This contract selfdestructs and gives its funds to `caller` let selfdestructing_code = vec![ @@ -1754,6 +1797,7 @@ mod test { caller, vec![], Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -1802,6 +1846,7 @@ mod test { let caller = H160::from_low_u64_be(115_u64); let selfdestructing_contract = H160::from_low_u64_be(100_u64); let all_the_gas = 1_000_000_u64; + let gas_price = U256::from(1); set_balance( &mut mock_runtime, @@ -1870,6 +1915,7 @@ mod test { caller, vec![], Some(all_the_gas), + gas_price, None, true, 10_000_000_000, @@ -1921,6 +1967,7 @@ mod test { let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); + let gas_price = U256::from(21000); let code = vec![ Opcode::CHAINID.as_u8(), // cost 2 Opcode::PUSH1.as_u8(), // push ost, cost 3 @@ -1940,7 +1987,7 @@ mod test { &mut mock_runtime, &mut evm_account_storage, &caller, - all_the_gas.into(), + gas_price * all_the_gas, ); set_account_code(&mut mock_runtime, &mut evm_account_storage, &target, &code); @@ -1956,6 +2003,7 @@ mod test { caller, vec![], Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -2005,12 +2053,13 @@ mod test { // value not relevant to test, just needs to be big enough let all_the_gas = 25_000_u64; + let gas_price = U256::from(21000); set_balance( &mut mock_runtime, &mut evm_account_storage, &caller, - all_the_gas.into(), + gas_price * all_the_gas, ); set_account_code(&mut mock_runtime, &mut evm_account_storage, &target, &code); @@ -2026,6 +2075,7 @@ mod test { caller, vec![], Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -2077,6 +2127,7 @@ mod test { let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_low_u64_be(523); let target = H160::from_low_u64_be(210); + let gas_price = U256::from(21000); set_balance( &mut mock_runtime, @@ -2101,6 +2152,7 @@ mod test { caller, vec![], None, + gas_price, Some(U256::from(100)), true, DUMMY_ALLOCATED_TICKS, @@ -2128,10 +2180,11 @@ mod test { // not testing gas_limit, should be big enough let gas_limit = 2_400_000; + let gas_price = U256::from(21000); // the test is not to check that account can prepay, // so we can choose the balance depending on set gas limit - let balance = block.gas_price.saturating_mul(gas_limit.into()); + let balance = gas_price.saturating_mul(gas_limit.into()); set_balance( &mut mock_runtime, &mut evm_account_storage, @@ -2148,6 +2201,7 @@ mod test { caller, call_data, Some(gas_limit), + gas_price, Some(transaction_value), true, DUMMY_ALLOCATED_TICKS, @@ -2180,10 +2234,11 @@ mod test { // not testing gas_limit, should be big enough let gas_limit = 2_400_000; + let gas_price = U256::from(21000); // the test is not to check that account can prepay, // so we can choose the balance depending on set gas limit - let balance = block.gas_price.saturating_mul(gas_limit.into()); + let balance = gas_price.saturating_mul(gas_limit.into()); set_balance( &mut mock_runtime, &mut evm_account_storage, @@ -2200,6 +2255,7 @@ mod test { caller, create_data, Some(gas_limit), + gas_price, Some(transaction_value), true, DUMMY_ALLOCATED_TICKS, @@ -2238,12 +2294,13 @@ mod test { // value not relevant to test, just needs to be big enough let all_the_gas = 25_000_u64; + let gas_price = U256::from(21000); set_balance( &mut mock_runtime, &mut evm_account_storage, &caller, - all_the_gas.into(), + gas_price * all_the_gas, ); set_account_code(&mut mock_runtime, &mut evm_account_storage, &target, &code); @@ -2259,6 +2316,7 @@ mod test { caller, data.to_vec(), Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -2295,12 +2353,13 @@ mod test { // value not relevant to test, just needs to be big enough let all_the_gas = 25_000_u64; + let gas_price = U256::from(21000); set_balance( &mut mock_runtime, &mut evm_account_storage, &caller, - all_the_gas.into(), + gas_price * all_the_gas, ); set_account_code(&mut mock_runtime, &mut evm_account_storage, &target, &code); @@ -2316,6 +2375,7 @@ mod test { caller, data.to_vec(), Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -2347,12 +2407,13 @@ mod test { let precompiles = precompiles::precompile_set::(); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_low_u64_be(118u64); + let gas_price = U256::from(1356); set_balance( &mut mock_runtime, &mut evm_account_storage, &caller, - all_the_gas.into(), + gas_price * all_the_gas, ); // Act @@ -2367,6 +2428,7 @@ mod test { caller, data.to_vec(), Some(all_the_gas), + gas_price, None, true, DUMMY_ALLOCATED_TICKS, @@ -2453,6 +2515,7 @@ mod test { .expect("Failed to decode call data"); let gas_limit = 300_000; + let gas_price = U256::from(1); let result = run_transaction( &mut mock_runtime, @@ -2464,6 +2527,7 @@ mod test { caller, call_data, Some(gas_limit), + gas_price, None, true, 10_000_000_000, @@ -2514,6 +2578,7 @@ mod test { .expect("Failed to decode call data"); let gas_limit = 300_000; + let gas_price = U256::from(1); let result = run_transaction( &mut mock_runtime, @@ -2525,6 +2590,7 @@ mod test { caller, call_data, Some(gas_limit), + gas_price, None, true, 10_000_000_000, @@ -2554,7 +2620,8 @@ mod test { let call_data: Vec = hex::decode(data_str).unwrap(); let gas_limit = 2_400_000; - let balance = block.gas_price.saturating_mul(gas_limit.into()); + let gas_price = U256::from(21000); + let balance = gas_price.saturating_mul(gas_limit.into()); set_balance(&mut host, &mut evm_account_storage, &caller, balance); @@ -2568,6 +2635,7 @@ mod test { caller, call_data, Some(gas_limit), + gas_price, Some(transaction_value), true, DUMMY_ALLOCATED_TICKS, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles.rs b/etherlink/kernel_evm/evm_execution/src/precompiles.rs index b9b0475ff26f..d5115ce6dd49 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles.rs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022-2023 TriliTech +// SPDX-FileCopyrightText: 2022-2024 TriliTech // // SPDX-License-Identifier: MIT @@ -519,13 +519,18 @@ mod tests { let mut evm_account_storage = init_evm_account_storage().unwrap(); let precompiles = precompile_set::(); let config = Config::shanghai(); + let gas_price = U256::from(21000); if let Some(Transfer { source, value, .. }) = transfer { set_balance( &mut mock_runtime, &mut evm_account_storage, &source, - value + gas_limit.unwrap_or(0), + value + + gas_limit + .map(U256::from) + .unwrap_or_default() + .saturating_mul(gas_price), ); } @@ -537,6 +542,7 @@ mod tests { &config, &precompiles, DUMMY_ALLOCATED_TICKS, + gas_price, ); let is_static = true; diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index 429046e95780..1e1e34a87974 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -1,12 +1,11 @@ // SPDX-FileCopyrightText: 2023 Marigold // SPDX-FileCopyrightText: 2023 Functori -// SPDX-FileCopyrightText: 2022-2023 TriliTech +// SPDX-FileCopyrightText: 2022-2024 TriliTech // SPDX-FileCopyrightText: 2023 Nomadic Labs // // SPDX-License-Identifier: MIT use alloc::borrow::Cow; -use anyhow::anyhow; use evm::{ExitError, ExitReason, ExitSucceed}; use evm_execution::account_storage::{ account_path, EthereumAccount, EthereumAccountStorage, @@ -65,16 +64,7 @@ impl Transaction { match &self.content { TransactionContent::Deposit(_) => Ok(U256::zero()), TransactionContent::Ethereum(transaction) => { - let priority_fee_per_gas = U256::min( - transaction.max_priority_fee_per_gas, - transaction - .max_fee_per_gas - .checked_sub(block_base_fee_per_gas) - .ok_or_else(|| anyhow!("Underflow when calculating gas price"))?, - ); - priority_fee_per_gas - .checked_add(block_base_fee_per_gas) - .ok_or_else(|| anyhow!("Overflow")) + transaction.effective_gas_price(block_base_fee_per_gas) } } } @@ -107,6 +97,7 @@ pub struct TransactionReceiptInfo { pub execution_outcome: Option, pub caller: H160, pub to: Option, + pub effective_gas_price: U256, } pub struct TransactionObjectInfo { @@ -129,6 +120,7 @@ fn make_receipt_info( execution_outcome: Option, caller: H160, to: Option, + effective_gas_price: U256, ) -> TransactionReceiptInfo { TransactionReceiptInfo { tx_hash, @@ -136,6 +128,7 @@ fn make_receipt_info( execution_outcome, caller, to, + effective_gas_price, } } @@ -203,11 +196,15 @@ pub enum Validity { InvalidMaxBaseFee, } +// TODO: https://gitlab.com/tezos/tezos/-/issues/6812 +// arguably, effective_gas_price should be set on EthereumTransactionCommon +// directly - initialised when constructed. fn is_valid_ethereum_transaction_common( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, transaction: &EthereumTransactionCommon, block_constant: &BlockConstants, + effective_gas_price: U256, ) -> Result { // Chain id is correct. if transaction.chain_id.is_some() @@ -250,7 +247,7 @@ fn is_valid_ethereum_transaction_common( }; // The sender account balance contains at least the cost. - let cost = U256::from(transaction.gas_limit).saturating_mul(block_constant.gas_price); + let cost = U256::from(transaction.gas_limit).saturating_mul(effective_gas_price); // The sender can afford the max gas fee he set, see EIP-1559 let max_fee = U256::from(transaction.gas_limit).saturating_mul(transaction.max_fee_per_gas); @@ -292,12 +289,15 @@ fn apply_ethereum_transaction_common( evm_account_storage: &mut EthereumAccountStorage, transaction: &EthereumTransactionCommon, allocated_ticks: u64, -) -> Result, Error> { +) -> Result, anyhow::Error> { + let effective_gas_price = + transaction.effective_gas_price(block_constants.base_fee_per_gas)?; let caller = match is_valid_ethereum_transaction_common( host, evm_account_storage, transaction, block_constants, + effective_gas_price, )? { Validity::Valid(caller) => caller, _reason => return Ok(None), @@ -317,6 +317,7 @@ fn apply_ethereum_transaction_common( caller, call_data, Some(gas_limit), + effective_gas_price, Some(value), true, allocated_ticks, @@ -327,7 +328,7 @@ fn apply_ethereum_transaction_common( // Because the proposal's state is unclear, and we do not have a sequencer // if an error that leads to a durable storage corruption is caught, we // invalidate the entire proposal. - return Err(Error::InvalidRunTransaction(err)); + return Err(Error::InvalidRunTransaction(err).into()); } }; @@ -492,11 +493,11 @@ pub fn apply_transaction( evm_account_storage, tx, allocated_ticks, - ), + )?, TransactionContent::Deposit(deposit) => { - apply_deposit(host, evm_account_storage, deposit) + apply_deposit(host, evm_account_storage, deposit)? } - }?; + }; match apply_result { Some(TransactionResult { @@ -513,14 +514,6 @@ pub fn apply_transaction( post_withdrawals(host, &execution_outcome.withdrawals)? } - let receipt_info = make_receipt_info( - transaction.tx_hash, - index, - execution_outcome, - caller, - to, - ); - let object_info = make_object_info( transaction, caller, @@ -529,6 +522,15 @@ pub fn apply_transaction( block_constants.base_fee_per_gas, )?; + let receipt_info = make_receipt_info( + transaction.tx_hash, + index, + execution_outcome, + caller, + to, + object_info.gas_price, + ); + index_new_accounts(host, accounts_index, &receipt_info)?; Ok(Some(ExecutionInfo { receipt_info, @@ -629,7 +631,8 @@ mod tests { // setup let address = address_from_str("af1276cbb260bb13deddb4209ae99ae6e497f446"); - let balance = U256::from(21000 * 21000); + let gas_price = U256::from(21000); + let balance = U256::from(21000) * gas_price; let transaction = valid_tx(); // fund account set_balance(&mut host, &mut evm_account_storage, &address, balance); @@ -640,6 +643,7 @@ mod tests { &mut evm_account_storage, &transaction, &block_constants, + gas_price, ); assert_eq!( Validity::Valid(address), @@ -657,6 +661,7 @@ mod tests { // setup let address = address_from_str("af1276cbb260bb13deddb4209ae99ae6e497f446"); + let gas_price = U256::from(21000); // account doesnt have enough fundes let balance = U256::from(1); let transaction = valid_tx(); @@ -669,6 +674,7 @@ mod tests { &mut evm_account_storage, &transaction, &block_constants, + gas_price, ); assert_eq!( Validity::InvalidPrePay, @@ -686,7 +692,8 @@ mod tests { // setup let address = address_from_str("af1276cbb260bb13deddb4209ae99ae6e497f446"); - let balance = U256::from(21000 * 21000); + let gas_price = U256::from(21000); + let balance = U256::from(21000) * gas_price; let mut transaction = valid_tx(); transaction.signature = None; // fund account @@ -698,6 +705,7 @@ mod tests { &mut evm_account_storage, &transaction, &block_constants, + gas_price, ); assert_eq!( Validity::InvalidSignature, @@ -715,7 +723,8 @@ mod tests { // setup let address = address_from_str("af1276cbb260bb13deddb4209ae99ae6e497f446"); - let balance = U256::from(21000 * 21000); + let gas_price = U256::from(21000); + let balance = U256::from(21000) * gas_price; let mut transaction = valid_tx(); transaction.nonce = U256::from(42); transaction = resign(transaction); @@ -729,6 +738,7 @@ mod tests { &mut evm_account_storage, &transaction, &block_constants, + gas_price, ); assert_eq!( Validity::InvalidNonce, @@ -746,7 +756,8 @@ mod tests { // setup let address = address_from_str("af1276cbb260bb13deddb4209ae99ae6e497f446"); - let balance = U256::from(21000 * 21000); + let gas_price = U256::from(21000); + let balance = U256::from(21000) * gas_price; let mut transaction = valid_tx(); transaction.chain_id = Some(U256::from(42)); transaction = resign(transaction); @@ -760,6 +771,7 @@ mod tests { &mut evm_account_storage, &transaction, &block_constants, + gas_price, ); assert_eq!( Validity::InvalidChainId, @@ -777,7 +789,8 @@ mod tests { // setup let address = address_from_str("af1276cbb260bb13deddb4209ae99ae6e497f446"); - let balance = U256::from(21000 * 21000); + let gas_price = U256::from(21000); + let balance = U256::from(21000) * gas_price; let mut transaction = valid_tx(); transaction.gas_limit = MAX_TRANSACTION_GAS_LIMIT + 1; transaction = resign(transaction); @@ -791,6 +804,7 @@ mod tests { &mut evm_account_storage, &transaction, &block_constants, + gas_price, ); assert_eq!( Validity::InvalidGasLimit, @@ -808,7 +822,8 @@ mod tests { // setup let address = address_from_str("af1276cbb260bb13deddb4209ae99ae6e497f446"); - let balance = U256::from(21000 * 21000); + let gas_price = U256::from(21000); + let balance = U256::from(21000) * gas_price; let mut transaction = valid_tx(); // set a max base fee too low transaction.max_fee_per_gas = U256::from(1); @@ -823,6 +838,7 @@ mod tests { &mut evm_account_storage, &transaction, &block_constants, + gas_price, ); assert_eq!( Validity::InvalidMaxBaseFee, @@ -840,7 +856,8 @@ mod tests { // setup let address = address_from_str("af1276cbb260bb13deddb4209ae99ae6e497f446"); - let balance = U256::from(21000 * 21000); + let gas_price = U256::from(21000); + let balance = U256::from(21000) * gas_price; let mut transaction = valid_tx(); // set a max_priority_fee bigger than, transaction.max_priority_fee_per_gas = U256::from(22000); @@ -855,6 +872,7 @@ mod tests { &mut evm_account_storage, &transaction, &block_constants, + gas_price, ); assert_eq!( Validity::InvalidMaxBaseFee, diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index 0edd2a6491e9..1dbb5994befa 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Nomadic Labs // SPDX-FileCopyrightText: 2023 Functori // SPDX-FileCopyrightText: 2023 Marigold +// SPDX-FileCopyrightText: 2024 Trilitech // // SPDX-License-Identifier: MIT @@ -796,7 +797,7 @@ mod tests { let dest_balance = get_balance(&mut host, &mut evm_account_storage, &dest_address); - assert_eq!(sender_balance, U256::from(9999999999499979000u64)); + assert_eq!(sender_balance, U256::from(9999999159500000000u64)); assert_eq!(dest_balance, U256::from(500000000u64)) } @@ -1063,13 +1064,7 @@ mod tests { // Ensures the caller has enough balance to pay for the fees, but not // the transaction itself, otherwise the transaction will not even be // taken into account. - let fees = BlockConstants::first_block( - U256::from(0), - DUMMY_CHAIN_ID, - DUMMY_BASE_FEE_PER_GAS.into(), - ) - .gas_price - * tx.gas_limit; + let fees = U256::from(21000) * tx.gas_limit; set_balance(&mut host, &mut evm_account_storage, &caller, fees); // Prepare a invalid transaction, i.e. with not enough funds. diff --git a/etherlink/kernel_evm/kernel/src/block_in_progress.rs b/etherlink/kernel_evm/kernel/src/block_in_progress.rs index 918e0eb3ddb8..fa6c0db78da5 100644 --- a/etherlink/kernel_evm/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_evm/kernel/src/block_in_progress.rs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Marigold // SPDX-FileCopyrightText: 2023 Nomadic Labs // SPDX-FileCopyrightText: 2023 Functori +// SPDX-FileCopyrightText: 2024 Trilitech // // SPDX-License-Identifier: MIT @@ -43,6 +44,10 @@ pub struct BlockInProgress { /// index for next transaction pub index: u32, /// gas price for transactions in the block being created + // TODO: https://gitlab.com/tezos/tezos/-/issues/6810 + // this seems like dead code, can we remove it? + // (ensure that BlockInProgress encoding doesn't need + // backwards compatibility). pub gas_price: U256, /// hash of the parent pub parent_hash: H256, @@ -208,7 +213,7 @@ impl BlockInProgress { BlockInProgress::new_with_ticks( current_block_number, parent_hash, - constants.gas_price, + constants.base_fee_per_gas, ring, tick_counter, blueprint.timestamp, @@ -334,12 +339,12 @@ impl BlockInProgress { caller: from, to, execution_outcome, + effective_gas_price, .. } = receipt_info; let &mut Self { number: block_number, - gas_price: effective_gas_price, cumulative_gas, logs_offset, .. diff --git a/etherlink/kernel_evm/kernel/src/simulation.rs b/etherlink/kernel_evm/kernel/src/simulation.rs index ffb6a4ae57c2..8879c3a18004 100644 --- a/etherlink/kernel_evm/kernel/src/simulation.rs +++ b/etherlink/kernel_evm/kernel/src/simulation.rs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022-2023 TriliTech +// SPDX-FileCopyrightText: 2022-2024 TriliTech // SPDX-FileCopyrightText: 2023 Marigold // SPDX-FileCopyrightText: 2023 Nomadic Labs // @@ -111,6 +111,13 @@ impl Evaluation { 0, tx_data_size, ); + + let gas_price = if let Some(gas_price) = self.gas_price { + U256::from(gas_price) + } else { + crate::retrieve_base_fee_per_gas(host)? + }; + let outcome = evm_execution::run_transaction( host, ¤t_constants, @@ -123,6 +130,7 @@ impl Evaluation { self.gas .map(|gas| u64::max(gas, MAX_EVALUATION_GAS)) .or(Some(MAX_EVALUATION_GAS)), // gas could be omitted + gas_price, self.value, false, allocated_ticks, @@ -538,6 +546,7 @@ mod tests { // gas limit was estimated using Remix on Shanghai network (256,842) // plus a safety margin for gas accounting discrepancies let gas_limit = 300_000; + let gas_price = U256::from(21000); // create contract let outcome = evm_execution::run_transaction( host, @@ -549,6 +558,7 @@ mod tests { caller, call_data, Some(gas_limit), + gas_price, Some(transaction_value), false, DUMMY_ALLOCATED_TICKS, diff --git a/tezt/tests/expected/evm_rollup.ml/Alpha- Regression test for L2 block hash.out b/tezt/tests/expected/evm_rollup.ml/Alpha- Regression test for L2 block hash.out index 0e4189850f24..87792d04e878 100644 --- a/tezt/tests/expected/evm_rollup.ml/Alpha- Regression test for L2 block hash.out +++ b/tezt/tests/expected/evm_rollup.ml/Alpha- Regression test for L2 block hash.out @@ -1 +1 @@ -Block hash: 0x3155b2064076ee84083d5a108ca17790542bdc28eb1456f8c82f38f9723c148e +Block hash: 0xb4cdc258645e3bc5668ff56c4c153a2a855c74413951177a5ac8e5abef0182b5 -- GitLab