From a5a79c4de4efc3fde78aa2e590ac33de29e5467b Mon Sep 17 00:00:00 2001 From: Rodrigo Quelhas <22591718+RomarQ@users.noreply.github.com> Date: Tue, 4 Jun 2024 12:42:50 +0100 Subject: [PATCH] Fix eip2929 implementation (#280) * burn base fee after eip-1559 included in london fork * feat: add Cancun configuration * fix(eip-2929): some addresses were considered cold when they shouldn't * Revert "feat: add Cancun configuration" This reverts commit 654fb20800753f164af96b0f2fd41e62fc8794b2. * Revert "burn base fee after eip-1559 included in london fork" This reverts commit 1e318692de81bec946662dac4ccf438220787c51. * add eip-2929 test * remove duplicated test --- .github/workflows/rust.yml | 4 +- interpreter/src/eval/system.rs | 7 --- jsontests/src/lib.rs | 8 ++++ src/standard/gasometer/mod.rs | 87 ++++++++++++++++++++++++++-------- 4 files changed, 78 insertions(+), 28 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8de37da97..b4dc811bd 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -52,4 +52,6 @@ jobs: jsontests/res/ethtests/GeneralStateTests/VMTests/vmBitwiseLogicOperation/ \ jsontests/res/ethtests/GeneralStateTests/VMTests/vmIOandFlowOperations/ \ jsontests/res/ethtests/GeneralStateTests/VMTests/vmLogTest/ \ - jsontests/res/ethtests/GeneralStateTests/VMTests/vmTests/ + jsontests/res/ethtests/GeneralStateTests/VMTests/vmTests/ \ + jsontests/res/ethtests/GeneralStateTests/stEIP150singleCodeGasPrices/eip2929.json + diff --git a/interpreter/src/eval/system.rs b/interpreter/src/eval/system.rs index 2521fe587..6d2e07459 100644 --- a/interpreter/src/eval/system.rs +++ b/interpreter/src/eval/system.rs @@ -50,7 +50,6 @@ pub fn balance, H: RuntimeEnvironment + RuntimeBackend, T handler: &mut H, ) -> Control { pop!(machine, address); - handler.mark_hot(address.into(), None); push_u256!(machine, handler.balance(address.into())); Control::Continue @@ -130,7 +129,6 @@ pub fn extcodesize, H: RuntimeEnvironment + RuntimeBacken handler: &mut H, ) -> Control { pop!(machine, address); - handler.mark_hot(address.into(), None); let code_size = handler.code_size(address.into()); push_u256!(machine, code_size); @@ -142,7 +140,6 @@ pub fn extcodehash, H: RuntimeEnvironment + RuntimeBacken handler: &mut H, ) -> Control { pop!(machine, address); - handler.mark_hot(address.into(), None); let code_hash = handler.code_hash(address.into()); push!(machine, code_hash); @@ -155,8 +152,6 @@ pub fn extcodecopy, H: RuntimeEnvironment + RuntimeBacken ) -> Control { pop!(machine, address); pop_u256!(machine, memory_offset, code_offset, len); - - handler.mark_hot(address.into(), None); try_or_fail!(machine.memory.resize_offset(memory_offset, len)); let code = handler.code(address.into()); @@ -266,7 +261,6 @@ pub fn sload, H: RuntimeEnvironment + RuntimeBackend, Tr> handler: &mut H, ) -> Control { pop!(machine, index); - handler.mark_hot(machine.state.as_ref().context.address, Some(index)); let value = handler.storage(machine.state.as_ref().context.address, index); push!(machine, value); @@ -278,7 +272,6 @@ pub fn sstore, H: RuntimeEnvironment + RuntimeBackend, Tr handler: &mut H, ) -> Control { pop!(machine, index, value); - handler.mark_hot(machine.state.as_ref().context.address, Some(index)); match handler.set_storage(machine.state.as_ref().context.address, index, value) { Ok(()) => Control::Continue, diff --git a/jsontests/src/lib.rs b/jsontests/src/lib.rs index 3dca24ae6..28661212f 100644 --- a/jsontests/src/lib.rs +++ b/jsontests/src/lib.rs @@ -73,3 +73,11 @@ fn vm_tests() { let tests_status = run::run_single(JSON_FILENAME, false).unwrap(); tests_status.print_total(); } + +#[test] +fn sqt_eip_2930() { + const JSON_FILENAME: &str = + "res/ethtests/GeneralStateTests/stEIP150singleCodeGasPrices/eip2929.json"; + let tests_status = run::run_single(JSON_FILENAME, false).unwrap(); + tests_status.print_total(); +} diff --git a/src/standard/gasometer/mod.rs b/src/standard/gasometer/mod.rs index 5321451d6..12eeea477 100644 --- a/src/standard/gasometer/mod.rs +++ b/src/standard/gasometer/mod.rs @@ -283,7 +283,7 @@ fn dynamic_opcode_cost( stack: &Stack, is_static: bool, config: &Config, - handler: &H, + handler: &mut H, ) -> Result<(GasCost, Option), ExitError> { let gas_cost = match opcode { Opcode::RETURN => GasCost::Zero, @@ -307,40 +307,59 @@ fn dynamic_opcode_cost( Opcode::EXTCODESIZE => { let target = stack.peek(0)?.into(); - GasCost::ExtCodeSize { - target_is_cold: handler.is_cold(target, None), - } + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(target, None); + handler.mark_hot(target, None); + + GasCost::ExtCodeSize { target_is_cold } } Opcode::BALANCE => { let target = stack.peek(0)?.into(); - GasCost::Balance { - target_is_cold: handler.is_cold(target, None), - } + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(target, None); + handler.mark_hot(target, None); + + GasCost::Balance { target_is_cold } } Opcode::BLOCKHASH => GasCost::BlockHash, Opcode::EXTCODEHASH if config.has_ext_code_hash => { let target = stack.peek(0)?.into(); - GasCost::ExtCodeHash { - target_is_cold: handler.is_cold(target, None), - } + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(target, None); + handler.mark_hot(target, None); + + GasCost::ExtCodeHash { target_is_cold } } Opcode::EXTCODEHASH => GasCost::Invalid(opcode), Opcode::CALLCODE => { let target = stack.peek(1)?.into(); + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(target, None); + handler.mark_hot(target, None); + GasCost::CallCode { value: U256::from_big_endian(&stack.peek(2)?[..]), gas: U256::from_big_endian(&stack.peek(0)?[..]), - target_is_cold: handler.is_cold(target, None), + target_is_cold, target_exists: { handler.exists(target) }, } } Opcode::STATICCALL => { let target = stack.peek(1)?.into(); + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(target, None); + handler.mark_hot(target, None); + GasCost::StaticCall { gas: U256::from_big_endian(&stack.peek(0)?[..]), - target_is_cold: handler.is_cold(target, None), + target_is_cold, target_exists: { handler.exists(target) }, } } @@ -349,8 +368,13 @@ fn dynamic_opcode_cost( }, Opcode::EXTCODECOPY => { let target = stack.peek(0)?.into(); + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(target, None); + handler.mark_hot(target, None); + GasCost::ExtCodeCopy { - target_is_cold: handler.is_cold(target, None), + target_is_cold, len: U256::from_big_endian(&stack.peek(3)?[..]), } } @@ -365,17 +389,25 @@ fn dynamic_opcode_cost( }, Opcode::SLOAD => { let index = stack.peek(0)?; - GasCost::SLoad { - target_is_cold: handler.is_cold(address, Some(index)), - } + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(address, Some(index)); + handler.mark_hot(address, Some(index)); + + GasCost::SLoad { target_is_cold } } Opcode::TLOAD if config.eip_1153_enabled => GasCost::TLoad, Opcode::DELEGATECALL if config.has_delegate_call => { let target = stack.peek(1)?.into(); + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(target, None); + handler.mark_hot(target, None); + GasCost::DelegateCall { gas: U256::from_big_endian(&stack.peek(0)?[..]), - target_is_cold: handler.is_cold(target, None), + target_is_cold, target_exists: { handler.exists(target) }, } } @@ -390,11 +422,16 @@ fn dynamic_opcode_cost( Opcode::SSTORE if !is_static => { let index = stack.peek(0)?; let value = stack.peek(1)?; + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(address, Some(index)); + handler.mark_hot(address, Some(index)); + GasCost::SStore { original: handler.original_storage(address, index), current: handler.storage(address, index), new: value, - target_is_cold: handler.is_cold(address, Some(index)), + target_is_cold, } } Opcode::TSTORE if !is_static && config.eip_1153_enabled => GasCost::TStore, @@ -424,9 +461,14 @@ fn dynamic_opcode_cost( }, Opcode::SUICIDE if !is_static => { let target = stack.peek(0)?.into(); + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(target, None); + handler.mark_hot(target, None); + GasCost::Suicide { value: handler.balance(address), - target_is_cold: handler.is_cold(target, None), + target_is_cold, target_exists: { handler.exists(target) }, already_removed: handler.deleted(address), } @@ -436,10 +478,15 @@ fn dynamic_opcode_cost( || (is_static && U256::from_big_endian(&stack.peek(2)?[..]) == U256::zero()) => { let target = stack.peek(1)?.into(); + + // https://eips.ethereum.org/EIPS/eip-2929 + let target_is_cold = handler.is_cold(target, None); + handler.mark_hot(target, None); + GasCost::Call { value: U256::from_big_endian(&stack.peek(2)?[..]), gas: U256::from_big_endian(&stack.peek(0)?[..]), - target_is_cold: handler.is_cold(target, None), + target_is_cold, target_exists: { handler.exists(target) }, } }