From 2bb8fa9b455c8f0ca51e8a4e26af63e2b915ce4d Mon Sep 17 00:00:00 2001 From: Tomas Fabrizio Orsi Date: Fri, 20 Dec 2024 17:11:14 -0300 Subject: [PATCH] fix(levm): change gas type from U256 to u64 (#1528) **Motivation** The execution client uses `u64` for measuring gas, while LEVM uses `U256`. This PR makes LEVM also use u64 for gas **Description** Closes https://github.com/lambdaclass/ethrex/issues/1499 --- cmd/ef_tests/levm/deserialize.rs | 33 +- cmd/ef_tests/levm/runner/levm_runner.rs | 2 +- cmd/ef_tests/levm/runner/revm_runner.rs | 5 +- cmd/ef_tests/levm/types.rs | 13 +- crates/vm/levm/src/call_frame.rs | 10 +- crates/vm/levm/src/constants.rs | 2 +- crates/vm/levm/src/environment.rs | 10 +- crates/vm/levm/src/gas_cost.rs | 502 ++++++++++-------- crates/vm/levm/src/opcode_handlers/block.rs | 4 +- .../stack_memory_storage_flow.rs | 13 +- crates/vm/levm/src/opcode_handlers/system.rs | 50 +- crates/vm/levm/src/precompiles.rs | 52 +- crates/vm/levm/src/vm.rs | 113 ++-- crates/vm/levm/tests/edge_case_tests.rs | 6 +- crates/vm/levm/tests/tests.rs | 240 ++++----- crates/vm/vm.rs | 6 +- 16 files changed, 587 insertions(+), 474 deletions(-) diff --git a/cmd/ef_tests/levm/deserialize.rs b/cmd/ef_tests/levm/deserialize.rs index 2e6a223a3..0a1c40611 100644 --- a/cmd/ef_tests/levm/deserialize.rs +++ b/cmd/ef_tests/levm/deserialize.rs @@ -131,6 +131,22 @@ where ) } +/// This serializes a hexadecimal string to u64 +pub fn deserialize_u64_safe<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + u64::from_str_radix( + String::deserialize(deserializer)?.trim_start_matches("0x"), + 16, + ) + .map_err(|err| { + serde::de::Error::custom(format!( + "error parsing U64 when deserializing U64 safely: {err}" + )) + }) +} + pub fn deserialize_h256_vec_optional_safe<'de, D>( deserializer: D, ) -> Result>, D::Error> @@ -201,7 +217,22 @@ where .map(|s| { U256::from_str(s.trim_start_matches("0x:bigint ")).map_err(|err| { serde::de::Error::custom(format!( - "error parsing U256 when deserializing U256 safely: {err}" + "error parsing U256 when deserializing U256 vector safely: {err}" + )) + }) + }) + .collect() +} +pub fn deserialize_u64_vec_safe<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + Vec::::deserialize(deserializer)? + .iter() + .map(|s| { + u64::from_str_radix(s.trim_start_matches("0x"), 16).map_err(|err| { + serde::de::Error::custom(format!( + "error parsing u64 when deserializing u64 vector safely: {err}" )) }) }) diff --git a/cmd/ef_tests/levm/runner/levm_runner.rs b/cmd/ef_tests/levm/runner/levm_runner.rs index 0e3a92abf..fe361c141 100644 --- a/cmd/ef_tests/levm/runner/levm_runner.rs +++ b/cmd/ef_tests/levm/runner/levm_runner.rs @@ -94,7 +94,7 @@ pub fn prepare_vm_for_tx(vector: &TestVector, test: &EFTest) -> Result( let chain_spec = initial_state .chain_config() .map_err(|err| EFTestRunnerError::VMInitializationFailed(err.to_string()))?; + let block_env = RevmBlockEnv { number: RevmU256::from_limbs(test.env.current_number.0), coinbase: RevmAddress(test.env.current_coinbase.0.into()), timestamp: RevmU256::from_limbs(test.env.current_timestamp.0), - gas_limit: RevmU256::from_limbs(test.env.current_gas_limit.0), + gas_limit: RevmU256::from(test.env.current_gas_limit), basefee: RevmU256::from_limbs(test.env.current_base_fee.unwrap_or_default().0), difficulty: RevmU256::from_limbs(test.env.current_difficulty.0), prevrandao: test.env.current_random.map(|v| v.0.into()), @@ -137,7 +138,7 @@ pub fn prepare_revm_for_tx<'state>( let tx_env = RevmTxEnv { caller: tx.sender.0.into(), - gas_limit: tx.gas_limit.as_u64(), + gas_limit: tx.gas_limit, gas_price: RevmU256::from_limbs(effective_gas_price(test, tx)?.0), transact_to: match tx.to { TxKind::Call(to) => RevmTxKind::Call(to.0.into()), diff --git a/cmd/ef_tests/levm/types.rs b/cmd/ef_tests/levm/types.rs index e92d304df..a74805be1 100644 --- a/cmd/ef_tests/levm/types.rs +++ b/cmd/ef_tests/levm/types.rs @@ -4,6 +4,7 @@ use crate::{ deserialize_h256_vec_optional_safe, deserialize_hex_bytes, deserialize_hex_bytes_vec, deserialize_transaction_expected_exception, deserialize_u256_optional_safe, deserialize_u256_safe, deserialize_u256_valued_hashmap_safe, deserialize_u256_vec_safe, + deserialize_u64_safe, deserialize_u64_vec_safe, }, report::TestVector, }; @@ -61,7 +62,7 @@ impl From<&EFTest> for Genesis { }, coinbase: test.env.current_coinbase, difficulty: test.env.current_difficulty, - gas_limit: test.env.current_gas_limit.as_u64(), + gas_limit: test.env.current_gas_limit, mix_hash: test.env.current_random.unwrap_or_default(), timestamp: test.env.current_timestamp.as_u64(), base_fee_per_gas: test.env.current_base_fee.map(|v| v.as_u64()), @@ -99,8 +100,8 @@ pub struct EFTestEnv { pub current_difficulty: U256, #[serde(default, deserialize_with = "deserialize_u256_optional_safe")] pub current_excess_blob_gas: Option, - #[serde(deserialize_with = "deserialize_u256_safe")] - pub current_gas_limit: U256, + #[serde(deserialize_with = "deserialize_u64_safe")] + pub current_gas_limit: u64, #[serde(deserialize_with = "deserialize_u256_safe")] pub current_number: U256, pub current_random: Option, @@ -268,8 +269,8 @@ pub struct EFTestAccessListItem { pub struct EFTestRawTransaction { #[serde(deserialize_with = "deserialize_hex_bytes_vec")] pub data: Vec, - #[serde(deserialize_with = "deserialize_u256_vec_safe")] - pub gas_limit: Vec, + #[serde(deserialize_with = "deserialize_u64_vec_safe")] + pub gas_limit: Vec, #[serde(default, deserialize_with = "deserialize_u256_optional_safe")] pub gas_price: Option, #[serde(deserialize_with = "deserialize_u256_safe")] @@ -295,7 +296,7 @@ pub struct EFTestRawTransaction { #[serde(rename_all = "camelCase")] pub struct EFTestTransaction { pub data: Bytes, - pub gas_limit: U256, + pub gas_limit: u64, pub gas_price: Option, #[serde(deserialize_with = "deserialize_u256_safe")] pub nonce: U256, diff --git a/crates/vm/levm/src/call_frame.rs b/crates/vm/levm/src/call_frame.rs index 0794e899e..d62b3fefd 100644 --- a/crates/vm/levm/src/call_frame.rs +++ b/crates/vm/levm/src/call_frame.rs @@ -53,9 +53,9 @@ impl Stack { /// the EVM is currently executing. pub struct CallFrame { /// Max gas a callframe can use - pub gas_limit: U256, + pub gas_limit: u64, /// Keeps track of the gas that's been used in current context - pub gas_used: U256, + pub gas_used: u64, /// Program Counter pub pc: usize, /// Address of the account that sent the message @@ -91,7 +91,7 @@ impl CallFrame { pub fn new_from_bytecode(bytecode: Bytes) -> Self { let valid_jump_destinations = get_valid_jump_destinations(&bytecode).unwrap_or_default(); Self { - gas_limit: U256::MAX, + gas_limit: u64::MAX, bytecode, valid_jump_destinations, ..Default::default() @@ -113,8 +113,8 @@ impl CallFrame { msg_value: U256, calldata: Bytes, is_static: bool, - gas_limit: U256, - gas_used: U256, + gas_limit: u64, + gas_used: u64, depth: usize, create_op_called: bool, ) -> Self { diff --git a/crates/vm/levm/src/constants.rs b/crates/vm/levm/src/constants.rs index 291be9bd5..a179002bf 100644 --- a/crates/vm/levm/src/constants.rs +++ b/crates/vm/levm/src/constants.rs @@ -21,7 +21,7 @@ pub const EMPTY_CODE_HASH: H256 = H256([ pub const MEMORY_EXPANSION_QUOTIENT: usize = 512; // Transaction costs in gas (in wei) -pub const TX_BASE_COST: U256 = U256([21000, 0, 0, 0]); +pub const TX_BASE_COST: u64 = 21000; pub const MAX_CODE_SIZE: usize = 0x6000; pub const INIT_CODE_MAX_SIZE: usize = 49152; diff --git a/crates/vm/levm/src/environment.rs b/crates/vm/levm/src/environment.rs index 014fb458f..e48052d8a 100644 --- a/crates/vm/levm/src/environment.rs +++ b/crates/vm/levm/src/environment.rs @@ -10,8 +10,8 @@ pub struct Environment { /// The sender address of the transaction that originated /// this execution. pub origin: Address, - pub refunded_gas: U256, - pub gas_limit: U256, + pub refunded_gas: u64, + pub gas_limit: u64, pub block_number: U256, pub coinbase: Address, pub timestamp: U256, @@ -25,7 +25,7 @@ pub struct Environment { pub tx_max_priority_fee_per_gas: Option, pub tx_max_fee_per_gas: Option, pub tx_max_fee_per_blob_gas: Option, - pub block_gas_limit: U256, + pub block_gas_limit: u64, pub transient_storage: TransientStorage, } @@ -33,8 +33,8 @@ impl Environment { pub fn default_from_address(origin: Address) -> Self { Self { origin, - refunded_gas: U256::default(), - gas_limit: U256::MAX, + refunded_gas: 0, + gas_limit: u64::MAX, block_number: Default::default(), coinbase: Default::default(), timestamp: Default::default(), diff --git a/crates/vm/levm/src/gas_cost.rs b/crates/vm/levm/src/gas_cost.rs index 06bf1a213..be2ec78d2 100644 --- a/crates/vm/levm/src/gas_cost.rs +++ b/crates/vm/levm/src/gas_cost.rs @@ -5,164 +5,164 @@ use crate::{ memory, StorageSlot, }; use bytes::Bytes; -/// Contains the gas costs of the EVM instructions (in wei) +/// Contains the gas costs of the EVM instructions use ethrex_core::U256; // Opcodes cost -pub const STOP: U256 = U256::zero(); -pub const ADD: U256 = U256([3, 0, 0, 0]); -pub const MUL: U256 = U256([5, 0, 0, 0]); -pub const SUB: U256 = U256([3, 0, 0, 0]); -pub const DIV: U256 = U256([5, 0, 0, 0]); -pub const SDIV: U256 = U256([5, 0, 0, 0]); -pub const MOD: U256 = U256([5, 0, 0, 0]); -pub const SMOD: U256 = U256([5, 0, 0, 0]); -pub const ADDMOD: U256 = U256([8, 0, 0, 0]); -pub const MULMOD: U256 = U256([8, 0, 0, 0]); -pub const EXP_STATIC: U256 = U256([10, 0, 0, 0]); -pub const EXP_DYNAMIC_BASE: U256 = U256([50, 0, 0, 0]); -pub const SIGNEXTEND: U256 = U256([5, 0, 0, 0]); -pub const LT: U256 = U256([3, 0, 0, 0]); -pub const GT: U256 = U256([3, 0, 0, 0]); -pub const SLT: U256 = U256([3, 0, 0, 0]); -pub const SGT: U256 = U256([3, 0, 0, 0]); -pub const EQ: U256 = U256([3, 0, 0, 0]); -pub const ISZERO: U256 = U256([3, 0, 0, 0]); -pub const AND: U256 = U256([3, 0, 0, 0]); -pub const OR: U256 = U256([3, 0, 0, 0]); -pub const XOR: U256 = U256([3, 0, 0, 0]); -pub const NOT: U256 = U256([3, 0, 0, 0]); -pub const BYTE: U256 = U256([3, 0, 0, 0]); -pub const SHL: U256 = U256([3, 0, 0, 0]); -pub const SHR: U256 = U256([3, 0, 0, 0]); -pub const SAR: U256 = U256([3, 0, 0, 0]); -pub const KECCAK25_STATIC: U256 = U256([30, 0, 0, 0]); -pub const KECCAK25_DYNAMIC_BASE: U256 = U256([6, 0, 0, 0]); -pub const CALLDATALOAD: U256 = U256([3, 0, 0, 0]); -pub const CALLDATASIZE: U256 = U256([2, 0, 0, 0]); -pub const CALLDATACOPY_STATIC: U256 = U256([3, 0, 0, 0]); -pub const CALLDATACOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]); -pub const RETURNDATASIZE: U256 = U256([2, 0, 0, 0]); -pub const RETURNDATACOPY_STATIC: U256 = U256([3, 0, 0, 0]); -pub const RETURNDATACOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]); -pub const ADDRESS: U256 = U256([2, 0, 0, 0]); -pub const ORIGIN: U256 = U256([2, 0, 0, 0]); -pub const CALLER: U256 = U256([2, 0, 0, 0]); -pub const BLOCKHASH: U256 = U256([20, 0, 0, 0]); -pub const COINBASE: U256 = U256([2, 0, 0, 0]); -pub const TIMESTAMP: U256 = U256([2, 0, 0, 0]); -pub const NUMBER: U256 = U256([2, 0, 0, 0]); -pub const PREVRANDAO: U256 = U256([2, 0, 0, 0]); -pub const GASLIMIT: U256 = U256([2, 0, 0, 0]); -pub const CHAINID: U256 = U256([2, 0, 0, 0]); -pub const SELFBALANCE: U256 = U256([5, 0, 0, 0]); -pub const BASEFEE: U256 = U256([2, 0, 0, 0]); -pub const BLOBHASH: U256 = U256([3, 0, 0, 0]); -pub const BLOBBASEFEE: U256 = U256([2, 0, 0, 0]); -pub const POP: U256 = U256([2, 0, 0, 0]); -pub const MLOAD_STATIC: U256 = U256([3, 0, 0, 0]); -pub const MSTORE_STATIC: U256 = U256([3, 0, 0, 0]); -pub const MSTORE8_STATIC: U256 = U256([3, 0, 0, 0]); -pub const JUMP: U256 = U256([8, 0, 0, 0]); -pub const JUMPI: U256 = U256([10, 0, 0, 0]); -pub const PC: U256 = U256([2, 0, 0, 0]); -pub const MSIZE: U256 = U256([2, 0, 0, 0]); -pub const GAS: U256 = U256([2, 0, 0, 0]); -pub const JUMPDEST: U256 = U256([1, 0, 0, 0]); -pub const TLOAD: U256 = U256([100, 0, 0, 0]); -pub const TSTORE: U256 = U256([100, 0, 0, 0]); -pub const MCOPY_STATIC: U256 = U256([3, 0, 0, 0]); -pub const MCOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]); -pub const PUSH0: U256 = U256([2, 0, 0, 0]); -pub const PUSHN: U256 = U256([3, 0, 0, 0]); -pub const DUPN: U256 = U256([3, 0, 0, 0]); -pub const SWAPN: U256 = U256([3, 0, 0, 0]); -pub const LOGN_STATIC: U256 = U256([375, 0, 0, 0]); -pub const LOGN_DYNAMIC_BASE: U256 = U256([375, 0, 0, 0]); -pub const LOGN_DYNAMIC_BYTE_BASE: U256 = U256([8, 0, 0, 0]); -pub const CALLVALUE: U256 = U256([2, 0, 0, 0]); -pub const CODESIZE: U256 = U256([2, 0, 0, 0]); -pub const CODECOPY_STATIC: U256 = U256([3, 0, 0, 0]); -pub const CODECOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]); -pub const GASPRICE: U256 = U256([2, 0, 0, 0]); -pub const SELFDESTRUCT_STATIC: U256 = U256([5000, 0, 0, 0]); -pub const SELFDESTRUCT_DYNAMIC: U256 = U256([25000, 0, 0, 0]); - -pub const DEFAULT_STATIC: U256 = U256::zero(); -pub const DEFAULT_COLD_DYNAMIC: U256 = U256([2600, 0, 0, 0]); -pub const DEFAULT_WARM_DYNAMIC: U256 = U256([100, 0, 0, 0]); - -pub const SLOAD_STATIC: U256 = U256::zero(); -pub const SLOAD_COLD_DYNAMIC: U256 = U256([2100, 0, 0, 0]); -pub const SLOAD_WARM_DYNAMIC: U256 = U256([100, 0, 0, 0]); - -pub const SSTORE_STATIC: U256 = U256::zero(); -pub const SSTORE_COLD_DYNAMIC: U256 = U256([2100, 0, 0, 0]); -pub const SSTORE_DEFAULT_DYNAMIC: U256 = U256([100, 0, 0, 0]); -pub const SSTORE_STORAGE_CREATION: U256 = U256([20000, 0, 0, 0]); -pub const SSTORE_STORAGE_MODIFICATION: U256 = U256([2900, 0, 0, 0]); -pub const SSTORE_STIPEND: U256 = U256([2300, 0, 0, 0]); - -pub const BALANCE_STATIC: U256 = DEFAULT_STATIC; -pub const BALANCE_COLD_DYNAMIC: U256 = DEFAULT_COLD_DYNAMIC; -pub const BALANCE_WARM_DYNAMIC: U256 = DEFAULT_WARM_DYNAMIC; - -pub const EXTCODESIZE_STATIC: U256 = DEFAULT_STATIC; -pub const EXTCODESIZE_COLD_DYNAMIC: U256 = DEFAULT_COLD_DYNAMIC; -pub const EXTCODESIZE_WARM_DYNAMIC: U256 = DEFAULT_WARM_DYNAMIC; - -pub const EXTCODEHASH_STATIC: U256 = DEFAULT_STATIC; -pub const EXTCODEHASH_COLD_DYNAMIC: U256 = DEFAULT_COLD_DYNAMIC; -pub const EXTCODEHASH_WARM_DYNAMIC: U256 = DEFAULT_WARM_DYNAMIC; - -pub const EXTCODECOPY_STATIC: U256 = U256::zero(); -pub const EXTCODECOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]); -pub const EXTCODECOPY_COLD_DYNAMIC: U256 = DEFAULT_COLD_DYNAMIC; -pub const EXTCODECOPY_WARM_DYNAMIC: U256 = DEFAULT_WARM_DYNAMIC; - -pub const CALL_STATIC: U256 = DEFAULT_STATIC; -pub const CALL_COLD_DYNAMIC: U256 = DEFAULT_COLD_DYNAMIC; -pub const CALL_WARM_DYNAMIC: U256 = DEFAULT_WARM_DYNAMIC; -pub const CALL_POSITIVE_VALUE: U256 = U256([9000, 0, 0, 0]); -pub const CALL_POSITIVE_VALUE_STIPEND: U256 = U256([2300, 0, 0, 0]); -pub const CALL_TO_EMPTY_ACCOUNT: U256 = U256([25000, 0, 0, 0]); - -pub const CALLCODE_STATIC: U256 = DEFAULT_STATIC; -pub const CALLCODE_COLD_DYNAMIC: U256 = DEFAULT_COLD_DYNAMIC; -pub const CALLCODE_WARM_DYNAMIC: U256 = DEFAULT_WARM_DYNAMIC; -pub const CALLCODE_POSITIVE_VALUE: U256 = U256([9000, 0, 0, 0]); -pub const CALLCODE_POSITIVE_VALUE_STIPEND: U256 = U256([2300, 0, 0, 0]); - -pub const DELEGATECALL_STATIC: U256 = DEFAULT_STATIC; -pub const DELEGATECALL_COLD_DYNAMIC: U256 = DEFAULT_COLD_DYNAMIC; -pub const DELEGATECALL_WARM_DYNAMIC: U256 = DEFAULT_WARM_DYNAMIC; - -pub const STATICCALL_STATIC: U256 = DEFAULT_STATIC; -pub const STATICCALL_COLD_DYNAMIC: U256 = DEFAULT_COLD_DYNAMIC; -pub const STATICCALL_WARM_DYNAMIC: U256 = DEFAULT_WARM_DYNAMIC; - -// Costs in gas for call opcodes (in wei) -pub const WARM_ADDRESS_ACCESS_COST: U256 = U256([100, 0, 0, 0]); -pub const COLD_ADDRESS_ACCESS_COST: U256 = U256([2600, 0, 0, 0]); -pub const NON_ZERO_VALUE_COST: U256 = U256([9000, 0, 0, 0]); -pub const BASIC_FALLBACK_FUNCTION_STIPEND: U256 = U256([2300, 0, 0, 0]); -pub const VALUE_TO_EMPTY_ACCOUNT_COST: U256 = U256([25000, 0, 0, 0]); - -// Costs in gas for create opcodes (in wei) -pub const INIT_CODE_WORD_COST: U256 = U256([2, 0, 0, 0]); -pub const CODE_DEPOSIT_COST: U256 = U256([200, 0, 0, 0]); -pub const CREATE_BASE_COST: U256 = U256([32000, 0, 0, 0]); +pub const STOP: u64 = 0; +pub const ADD: u64 = 3; +pub const MUL: u64 = 5; +pub const SUB: u64 = 3; +pub const DIV: u64 = 5; +pub const SDIV: u64 = 5; +pub const MOD: u64 = 5; +pub const SMOD: u64 = 5; +pub const ADDMOD: u64 = 8; +pub const MULMOD: u64 = 8; +pub const EXP_STATIC: u64 = 10; +pub const EXP_DYNAMIC_BASE: u64 = 50; +pub const SIGNEXTEND: u64 = 5; +pub const LT: u64 = 3; +pub const GT: u64 = 3; +pub const SLT: u64 = 3; +pub const SGT: u64 = 3; +pub const EQ: u64 = 3; +pub const ISZERO: u64 = 3; +pub const AND: u64 = 3; +pub const OR: u64 = 3; +pub const XOR: u64 = 3; +pub const NOT: u64 = 3; +pub const BYTE: u64 = 3; +pub const SHL: u64 = 3; +pub const SHR: u64 = 3; +pub const SAR: u64 = 3; +pub const KECCAK25_STATIC: u64 = 30; +pub const KECCAK25_DYNAMIC_BASE: u64 = 6; +pub const CALLDATALOAD: u64 = 3; +pub const CALLDATASIZE: u64 = 2; +pub const CALLDATACOPY_STATIC: u64 = 3; +pub const CALLDATACOPY_DYNAMIC_BASE: u64 = 3; +pub const RETURNDATASIZE: u64 = 2; +pub const RETURNDATACOPY_STATIC: u64 = 3; +pub const RETURNDATACOPY_DYNAMIC_BASE: u64 = 3; +pub const ADDRESS: u64 = 2; +pub const ORIGIN: u64 = 2; +pub const CALLER: u64 = 2; +pub const BLOCKHASH: u64 = 20; +pub const COINBASE: u64 = 2; +pub const TIMESTAMP: u64 = 2; +pub const NUMBER: u64 = 2; +pub const PREVRANDAO: u64 = 2; +pub const GASLIMIT: u64 = 2; +pub const CHAINID: u64 = 2; +pub const SELFBALANCE: u64 = 5; +pub const BASEFEE: u64 = 2; +pub const BLOBHASH: u64 = 3; +pub const BLOBBASEFEE: u64 = 2; +pub const POP: u64 = 2; +pub const MLOAD_STATIC: u64 = 3; +pub const MSTORE_STATIC: u64 = 3; +pub const MSTORE8_STATIC: u64 = 3; +pub const JUMP: u64 = 8; +pub const JUMPI: u64 = 10; +pub const PC: u64 = 2; +pub const MSIZE: u64 = 2; +pub const GAS: u64 = 2; +pub const JUMPDEST: u64 = 1; +pub const TLOAD: u64 = 100; +pub const TSTORE: u64 = 100; +pub const MCOPY_STATIC: u64 = 3; +pub const MCOPY_DYNAMIC_BASE: u64 = 3; +pub const PUSH0: u64 = 2; +pub const PUSHN: u64 = 3; +pub const DUPN: u64 = 3; +pub const SWAPN: u64 = 3; +pub const LOGN_STATIC: u64 = 375; +pub const LOGN_DYNAMIC_BASE: u64 = 375; +pub const LOGN_DYNAMIC_BYTE_BASE: u64 = 8; +pub const CALLVALUE: u64 = 2; +pub const CODESIZE: u64 = 2; +pub const CODECOPY_STATIC: u64 = 3; +pub const CODECOPY_DYNAMIC_BASE: u64 = 3; +pub const GASPRICE: u64 = 2; +pub const SELFDESTRUCT_STATIC: u64 = 5000; +pub const SELFDESTRUCT_DYNAMIC: u64 = 25000; + +pub const DEFAULT_STATIC: u64 = 0; +pub const DEFAULT_COLD_DYNAMIC: u64 = 2600; +pub const DEFAULT_WARM_DYNAMIC: u64 = 100; + +pub const SLOAD_STATIC: u64 = 0; +pub const SLOAD_COLD_DYNAMIC: u64 = 2100; +pub const SLOAD_WARM_DYNAMIC: u64 = 100; + +pub const SSTORE_STATIC: u64 = 0; +pub const SSTORE_COLD_DYNAMIC: u64 = 2100; +pub const SSTORE_DEFAULT_DYNAMIC: u64 = 100; +pub const SSTORE_STORAGE_CREATION: u64 = 20000; +pub const SSTORE_STORAGE_MODIFICATION: u64 = 2900; +pub const SSTORE_STIPEND: u64 = 2300; + +pub const BALANCE_STATIC: u64 = DEFAULT_STATIC; +pub const BALANCE_COLD_DYNAMIC: u64 = DEFAULT_COLD_DYNAMIC; +pub const BALANCE_WARM_DYNAMIC: u64 = DEFAULT_WARM_DYNAMIC; + +pub const EXTCODESIZE_STATIC: u64 = DEFAULT_STATIC; +pub const EXTCODESIZE_COLD_DYNAMIC: u64 = DEFAULT_COLD_DYNAMIC; +pub const EXTCODESIZE_WARM_DYNAMIC: u64 = DEFAULT_WARM_DYNAMIC; + +pub const EXTCODEHASH_STATIC: u64 = DEFAULT_STATIC; +pub const EXTCODEHASH_COLD_DYNAMIC: u64 = DEFAULT_COLD_DYNAMIC; +pub const EXTCODEHASH_WARM_DYNAMIC: u64 = DEFAULT_WARM_DYNAMIC; + +pub const EXTCODECOPY_STATIC: u64 = 0; +pub const EXTCODECOPY_DYNAMIC_BASE: u64 = 3; +pub const EXTCODECOPY_COLD_DYNAMIC: u64 = DEFAULT_COLD_DYNAMIC; +pub const EXTCODECOPY_WARM_DYNAMIC: u64 = DEFAULT_WARM_DYNAMIC; + +pub const CALL_STATIC: u64 = DEFAULT_STATIC; +pub const CALL_COLD_DYNAMIC: u64 = DEFAULT_COLD_DYNAMIC; +pub const CALL_WARM_DYNAMIC: u64 = DEFAULT_WARM_DYNAMIC; +pub const CALL_POSITIVE_VALUE: u64 = 9000; +pub const CALL_POSITIVE_VALUE_STIPEND: u64 = 2300; +pub const CALL_TO_EMPTY_ACCOUNT: u64 = 25000; + +pub const CALLCODE_STATIC: u64 = DEFAULT_STATIC; +pub const CALLCODE_COLD_DYNAMIC: u64 = DEFAULT_COLD_DYNAMIC; +pub const CALLCODE_WARM_DYNAMIC: u64 = DEFAULT_WARM_DYNAMIC; +pub const CALLCODE_POSITIVE_VALUE: u64 = 9000; +pub const CALLCODE_POSITIVE_VALUE_STIPEND: u64 = 2300; + +pub const DELEGATECALL_STATIC: u64 = DEFAULT_STATIC; +pub const DELEGATECALL_COLD_DYNAMIC: u64 = DEFAULT_COLD_DYNAMIC; +pub const DELEGATECALL_WARM_DYNAMIC: u64 = DEFAULT_WARM_DYNAMIC; + +pub const STATICCALL_STATIC: u64 = DEFAULT_STATIC; +pub const STATICCALL_COLD_DYNAMIC: u64 = DEFAULT_COLD_DYNAMIC; +pub const STATICCALL_WARM_DYNAMIC: u64 = DEFAULT_WARM_DYNAMIC; + +// Costs in gas for call opcodes +pub const WARM_ADDRESS_ACCESS_COST: u64 = 100; +pub const COLD_ADDRESS_ACCESS_COST: u64 = 2600; +pub const NON_ZERO_VALUE_COST: u64 = 9000; +pub const BASIC_FALLBACK_FUNCTION_STIPEND: u64 = 2300; +pub const VALUE_TO_EMPTY_ACCOUNT_COST: u64 = 25000; + +// Costs in gas for create opcodes +pub const INIT_CODE_WORD_COST: u64 = 2; +pub const CODE_DEPOSIT_COST: u64 = 200; +pub const CREATE_BASE_COST: u64 = 32000; // Calldata costs -pub const CALLDATA_COST_ZERO_BYTE: U256 = U256([4, 0, 0, 0]); -pub const CALLDATA_COST_NON_ZERO_BYTE: U256 = U256([16, 0, 0, 0]); +pub const CALLDATA_COST_ZERO_BYTE: u64 = 4; +pub const CALLDATA_COST_NON_ZERO_BYTE: u64 = 16; -// Blob gas costs 2^17 -pub const BLOB_GAS_PER_BLOB: U256 = U256([131072, 0, 0, 0]); +// Blob gas costs +pub const BLOB_GAS_PER_BLOB: u64 = 131072; // Access lists costs -pub const ACCESS_LIST_STORAGE_KEY_COST: U256 = U256([1900, 0, 0, 0]); -pub const ACCESS_LIST_ADDRESS_COST: U256 = U256([2400, 0, 0, 0]); +pub const ACCESS_LIST_STORAGE_KEY_COST: u64 = 1900; +pub const ACCESS_LIST_ADDRESS_COST: u64 = 2400; // Precompile costs pub const ECRECOVER_COST: u64 = 3000; @@ -180,27 +180,31 @@ pub const MODEXP_STATIC_COST: u64 = 0; pub const MODEXP_DYNAMIC_BASE: u64 = 200; pub const MODEXP_DYNAMIC_QUOTIENT: u64 = 3; -pub fn exp(exponent: U256) -> Result { +pub fn exp(exponent: U256) -> Result { let exponent_byte_size = (exponent .bits() .checked_add(7) - .ok_or(OutOfGasError::GasCostOverflow)?) + .ok_or(VMError::OutOfGas(OutOfGasError::GasCostOverflow))?) / 8; + let exponent_byte_size: u64 = exponent_byte_size + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; + let exponent_byte_size_cost = EXP_DYNAMIC_BASE - .checked_mul(exponent_byte_size.into()) - .ok_or(OutOfGasError::GasCostOverflow)?; + .checked_mul(exponent_byte_size) + .ok_or(VMError::OutOfGas(OutOfGasError::GasCostOverflow))?; EXP_STATIC .checked_add(exponent_byte_size_cost) - .ok_or(OutOfGasError::GasCostOverflow) + .ok_or(VMError::OutOfGas(OutOfGasError::GasCostOverflow)) } pub fn calldatacopy( new_memory_size: usize, current_memory_size: usize, size: usize, -) -> Result { +) -> Result { copy_behavior( new_memory_size, current_memory_size, @@ -214,7 +218,7 @@ pub fn codecopy( new_memory_size: usize, current_memory_size: usize, size: usize, -) -> Result { +) -> Result { copy_behavior( new_memory_size, current_memory_size, @@ -228,7 +232,7 @@ pub fn returndatacopy( new_memory_size: usize, current_memory_size: usize, size: usize, -) -> Result { +) -> Result { copy_behavior( new_memory_size, current_memory_size, @@ -242,24 +246,31 @@ fn copy_behavior( new_memory_size: usize, current_memory_size: usize, size: usize, - dynamic_base: U256, - static_cost: U256, -) -> Result { + dynamic_base: u64, + static_cost: u64, +) -> Result { let minimum_word_size = (size .checked_add(WORD_SIZE) .ok_or(OutOfGasError::GasCostOverflow)? .saturating_sub(1)) / WORD_SIZE; + let minimum_word_size: u64 = minimum_word_size + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; + let memory_expansion_cost = memory::expansion_cost(new_memory_size, current_memory_size)?; + let memory_expansion_cost: u64 = memory_expansion_cost + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; let minimum_word_size_cost = dynamic_base - .checked_mul(minimum_word_size.into()) + .checked_mul(minimum_word_size) .ok_or(OutOfGasError::GasCostOverflow)?; Ok(static_cost .checked_add(minimum_word_size_cost) .ok_or(OutOfGasError::GasCostOverflow)? - .checked_add(memory_expansion_cost.into()) + .checked_add(memory_expansion_cost) .ok_or(OutOfGasError::GasCostOverflow)?) } @@ -267,7 +278,7 @@ pub fn keccak256( new_memory_size: usize, current_memory_size: usize, size: usize, -) -> Result { +) -> Result { copy_behavior( new_memory_size, current_memory_size, @@ -282,48 +293,59 @@ pub fn log( current_memory_size: usize, size: usize, number_of_topics: u8, -) -> Result { +) -> Result { let memory_expansion_cost = memory::expansion_cost(new_memory_size, current_memory_size)?; let topics_cost = LOGN_DYNAMIC_BASE .checked_mul(number_of_topics.into()) .ok_or(OutOfGasError::GasCostOverflow)?; + + let size: u64 = size.try_into().map_err(|_| VMError::VeryLargeNumber)?; let bytes_cost = LOGN_DYNAMIC_BYTE_BASE - .checked_mul(size.into()) + .checked_mul(size) .ok_or(OutOfGasError::GasCostOverflow)?; + + let memory_expansion_cost: u64 = memory_expansion_cost + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; + Ok(topics_cost .checked_add(LOGN_STATIC) .ok_or(OutOfGasError::GasCostOverflow)? .checked_add(bytes_cost) .ok_or(OutOfGasError::GasCostOverflow)? - .checked_add(memory_expansion_cost.into()) + .checked_add(memory_expansion_cost) .ok_or(OutOfGasError::GasCostOverflow)?) } -pub fn mload(new_memory_size: usize, current_memory_size: usize) -> Result { +pub fn mload(new_memory_size: usize, current_memory_size: usize) -> Result { mem_expansion_behavior(new_memory_size, current_memory_size, MLOAD_STATIC) } -pub fn mstore(new_memory_size: usize, current_memory_size: usize) -> Result { +pub fn mstore(new_memory_size: usize, current_memory_size: usize) -> Result { mem_expansion_behavior(new_memory_size, current_memory_size, MSTORE_STATIC) } -pub fn mstore8(new_memory_size: usize, current_memory_size: usize) -> Result { +pub fn mstore8(new_memory_size: usize, current_memory_size: usize) -> Result { mem_expansion_behavior(new_memory_size, current_memory_size, MSTORE8_STATIC) } fn mem_expansion_behavior( new_memory_size: usize, current_memory_size: usize, - static_cost: U256, -) -> Result { + static_cost: u64, +) -> Result { let memory_expansion_cost = memory::expansion_cost(new_memory_size, current_memory_size)?; + let memory_expansion_cost: u64 = memory_expansion_cost + .try_into() + .map_err(|_| VMError::RevertOpcode)?; + Ok(static_cost - .checked_add(memory_expansion_cost.into()) + .checked_add(memory_expansion_cost) .ok_or(OutOfGasError::GasCostOverflow)?) } -pub fn sload(storage_slot_was_cold: bool) -> Result { +pub fn sload(storage_slot_was_cold: bool) -> Result { let static_gas = SLOAD_STATIC; let dynamic_cost = if storage_slot_was_cold { @@ -342,7 +364,7 @@ pub fn sstore( new_value: U256, storage_slot_was_cold: bool, current_call_frame: &CallFrame, -) -> Result { +) -> Result { // EIP-2200 let gas_left = current_call_frame .gas_limit @@ -381,7 +403,7 @@ pub fn mcopy( new_memory_size: usize, current_memory_size: usize, size: usize, -) -> Result { +) -> Result { let words_copied = (size .checked_add(WORD_SIZE) .ok_or(OutOfGasError::GasCostOverflow)? @@ -389,15 +411,22 @@ pub fn mcopy( / WORD_SIZE; let memory_expansion_cost = memory::expansion_cost(new_memory_size, current_memory_size)?; + let memory_expansion_cost: u64 = memory_expansion_cost + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; + + let words_copied: u64 = words_copied + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; let copied_words_cost = MCOPY_DYNAMIC_BASE - .checked_mul(words_copied.into()) + .checked_mul(words_copied) .ok_or(OutOfGasError::GasCostOverflow)?; Ok(MCOPY_STATIC .checked_add(copied_words_cost) .ok_or(OutOfGasError::GasCostOverflow)? - .checked_add(memory_expansion_cost.into()) + .checked_add(memory_expansion_cost) .ok_or(OutOfGasError::GasCostOverflow)?) } @@ -405,7 +434,7 @@ pub fn create( new_memory_size: usize, current_memory_size: usize, code_size_in_memory: usize, -) -> Result { +) -> Result { compute_gas_create( new_memory_size, current_memory_size, @@ -418,7 +447,7 @@ pub fn create_2( new_memory_size: usize, current_memory_size: usize, code_size_in_memory: usize, -) -> Result { +) -> Result { compute_gas_create( new_memory_size, current_memory_size, @@ -432,41 +461,50 @@ fn compute_gas_create( current_memory_size: usize, code_size_in_memory: usize, is_create_2: bool, -) -> Result { +) -> Result { let minimum_word_size = (code_size_in_memory .checked_add(31) .ok_or(OutOfGasError::GasCostOverflow)?) .checked_div(32) .ok_or(OutOfGasError::ArithmeticOperationDividedByZero)?; // '32' will never be zero + let minimum_word_size: u64 = minimum_word_size + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; + let init_code_cost = minimum_word_size - .checked_mul(INIT_CODE_WORD_COST.as_usize()) // will not panic since it's 2 - .ok_or(OutOfGasError::GasCostOverflow)?; + .checked_mul(INIT_CODE_WORD_COST) + .ok_or(OutOfGasError::GasCostOverflow)?; // will not panic since it's 2 let memory_expansion_cost = memory::expansion_cost(new_memory_size, current_memory_size)?; + let memory_expansion_cost: u64 = memory_expansion_cost + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; let hash_cost = if is_create_2 { minimum_word_size - .checked_mul(KECCAK25_DYNAMIC_BASE.as_usize()) // will not panic since it's 6 - .ok_or(OutOfGasError::GasCostOverflow)? + .checked_mul(KECCAK25_DYNAMIC_BASE) + .ok_or(OutOfGasError::GasCostOverflow)? // will not panic since it's 6 } else { 0 }; - Ok(U256::from(memory_expansion_cost) - .checked_add(init_code_cost.into()) + let gas_create_cost = memory_expansion_cost + .checked_add(init_code_cost) .ok_or(OutOfGasError::CreationCostIsTooHigh)? .checked_add(CREATE_BASE_COST) .ok_or(OutOfGasError::CreationCostIsTooHigh)? - .checked_add(hash_cost.into()) - .ok_or(OutOfGasError::CreationCostIsTooHigh)?) + .checked_add(hash_cost) + .ok_or(OutOfGasError::CreationCostIsTooHigh)?; + + Ok(gas_create_cost) } pub fn selfdestruct( address_was_cold: bool, account_is_empty: bool, balance_to_transfer: U256, -) -> Result { +) -> Result { let mut gas_cost = SELFDESTRUCT_STATIC; if address_was_cold { @@ -485,10 +523,10 @@ pub fn selfdestruct( Ok(gas_cost) } -pub fn tx_calldata(calldata: &Bytes) -> Result { +pub fn tx_calldata(calldata: &Bytes) -> Result { // This cost applies both for call and create // 4 gas for each zero byte in the transaction data 16 gas for each non-zero byte in the transaction. - let mut calldata_cost: U256 = U256::zero(); + let mut calldata_cost: u64 = 0; for byte in calldata { if *byte != 0 { calldata_cost = calldata_cost @@ -522,12 +560,12 @@ pub fn tx_creation(code_length: u64, number_of_words: u64) -> Result Result { + static_cost: u64, + cold_dynamic_cost: u64, + warm_dynamic_cost: u64, +) -> Result { let static_gas = static_cost; - let dynamic_cost: U256 = if address_was_cold { + let dynamic_cost: u64 = if address_was_cold { cold_dynamic_cost } else { warm_dynamic_cost @@ -538,7 +576,7 @@ fn address_access_cost( .ok_or(OutOfGasError::GasCostOverflow)?) } -pub fn balance(address_was_cold: bool) -> Result { +pub fn balance(address_was_cold: bool) -> Result { address_access_cost( address_was_cold, BALANCE_STATIC, @@ -547,7 +585,7 @@ pub fn balance(address_was_cold: bool) -> Result { ) } -pub fn extcodesize(address_was_cold: bool) -> Result { +pub fn extcodesize(address_was_cold: bool) -> Result { address_access_cost( address_was_cold, EXTCODESIZE_STATIC, @@ -561,7 +599,7 @@ pub fn extcodecopy( new_memory_size: usize, current_memory_size: usize, address_was_cold: bool, -) -> Result { +) -> Result { let base_access_cost = copy_behavior( new_memory_size, current_memory_size, @@ -581,7 +619,7 @@ pub fn extcodecopy( .ok_or(OutOfGasError::GasCostOverflow)?) } -pub fn extcodehash(address_was_cold: bool) -> Result { +pub fn extcodehash(address_was_cold: bool) -> Result { address_access_cost( address_was_cold, EXTCODEHASH_STATIC, @@ -596,10 +634,14 @@ pub fn call( address_was_cold: bool, address_is_empty: bool, value_to_transfer: U256, -) -> Result { +) -> Result { let static_gas = CALL_STATIC; let memory_expansion_cost = memory::expansion_cost(new_memory_size, current_memory_size)?; + let memory_expansion_cost: u64 = memory_expansion_cost + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; + let address_access_cost = address_access_cost( address_was_cold, CALL_STATIC, @@ -611,16 +653,16 @@ pub fn call( .checked_sub(CALL_POSITIVE_VALUE_STIPEND) .ok_or(InternalError::ArithmeticOperationUnderflow)? } else { - U256::zero() + 0 }; let value_to_empty_account = if address_is_empty && !value_to_transfer.is_zero() { CALL_TO_EMPTY_ACCOUNT } else { - U256::zero() + 0 }; // Note: code_execution_cost will be charged from the sub context post-state. - let dynamic_gas = U256::from(memory_expansion_cost) + let dynamic_gas = memory_expansion_cost .checked_add(address_access_cost) .ok_or(OutOfGasError::GasCostOverflow)? .checked_add(positive_value_cost) @@ -638,10 +680,14 @@ pub fn callcode( current_memory_size: usize, address_was_cold: bool, value_to_transfer: U256, -) -> Result { +) -> Result { let static_gas = CALLCODE_STATIC; let memory_expansion_cost = memory::expansion_cost(new_memory_size, current_memory_size)?; + let memory_expansion_cost: u64 = memory_expansion_cost + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; + let address_access_cost = address_access_cost( address_was_cold, CALLCODE_STATIC, @@ -653,11 +699,11 @@ pub fn callcode( .checked_sub(CALLCODE_POSITIVE_VALUE_STIPEND) .ok_or(InternalError::ArithmeticOperationUnderflow)? } else { - U256::zero() + 0 }; // Note: code_execution_cost will be charged from the sub context post-state. - let dynamic_gas = U256::from(memory_expansion_cost) + let dynamic_gas = memory_expansion_cost .checked_add(address_access_cost) .ok_or(OutOfGasError::GasCostOverflow)? .checked_add(positive_value_cost) @@ -672,10 +718,14 @@ pub fn delegatecall( new_memory_size: usize, current_memory_size: usize, address_was_cold: bool, -) -> Result { +) -> Result { let static_gas = DELEGATECALL_STATIC; let memory_expansion_cost = memory::expansion_cost(new_memory_size, current_memory_size)?; + let memory_expansion_cost: u64 = memory_expansion_cost + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; + let address_access_cost = address_access_cost( address_was_cold, DELEGATECALL_STATIC, @@ -684,7 +734,7 @@ pub fn delegatecall( )?; // Note: code_execution_cost will be charged from the sub context post-state. - let dynamic_gas = U256::from(memory_expansion_cost) + let dynamic_gas = memory_expansion_cost .checked_add(address_access_cost) .ok_or(OutOfGasError::GasCostOverflow)?; @@ -697,10 +747,14 @@ pub fn staticcall( new_memory_size: usize, current_memory_size: usize, address_was_cold: bool, -) -> Result { +) -> Result { let static_gas = STATICCALL_STATIC; let memory_expansion_cost = memory::expansion_cost(new_memory_size, current_memory_size)?; + let memory_expansion_cost: u64 = memory_expansion_cost + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?; + let address_access_cost = address_access_cost( address_was_cold, STATICCALL_STATIC, @@ -709,7 +763,7 @@ pub fn staticcall( )?; // Note: code_execution_cost will be charged from the sub context post-state. - let dynamic_gas = U256::from(memory_expansion_cost) + let dynamic_gas = memory_expansion_cost .checked_add(address_access_cost) .ok_or(OutOfGasError::GasCostOverflow)?; @@ -718,7 +772,7 @@ pub fn staticcall( .ok_or(OutOfGasError::GasCostOverflow)?) } -pub fn fake_exponential(factor: u64, numerator: u64, denominator: u64) -> Result { +pub fn fake_exponential(factor: u64, numerator: u64, denominator: u64) -> Result { let mut i = 1; let mut output: u64 = 0; @@ -751,22 +805,20 @@ pub fn fake_exponential(factor: u64, numerator: u64, denominator: u64) -> Result .ok_or(InternalError::ArithmeticOperationOverflow)?; } - Ok(U256::from( - output - .checked_div(denominator) - .ok_or(InternalError::ArithmeticOperationOverflow)?, - )) + Ok(output + .checked_div(denominator) + .ok_or(InternalError::ArithmeticOperationOverflow)?) } -pub fn sha2_256(data_size: usize) -> Result { +pub fn sha2_256(data_size: usize) -> Result { precompile(data_size, SHA2_256_STATIC_COST, SHA2_256_DYNAMIC_BASE) } -pub fn ripemd_160(data_size: usize) -> Result { +pub fn ripemd_160(data_size: usize) -> Result { precompile(data_size, RIPEMD_160_STATIC_COST, RIPEMD_160_DYNAMIC_BASE) } -pub fn identity(data_size: usize) -> Result { +pub fn identity(data_size: usize) -> Result { precompile(data_size, IDENTITY_STATIC_COST, IDENTITY_DYNAMIC_BASE) } @@ -834,7 +886,7 @@ pub fn modexp( .ok_or(OutOfGasError::GasCostOverflow)?) } -fn precompile(data_size: usize, static_cost: u64, dynamic_base: u64) -> Result { +fn precompile(data_size: usize, static_cost: u64, dynamic_base: u64) -> Result { let data_size: u64 = data_size .try_into() .map_err(|_| PrecompileError::ParsingInputError)?; @@ -851,8 +903,7 @@ fn precompile(data_size: usize, static_cost: u64, dynamic_base: u64) -> Result Result Result { let mut remaining_gas = current_call_frame .gas_limit - .low_u64() - .checked_sub(current_call_frame.gas_used.low_u64()) + .checked_sub(current_call_frame.gas_used) .ok_or(InternalError::GasOverflow)?; remaining_gas = remaining_gas diff --git a/crates/vm/levm/src/opcode_handlers/block.rs b/crates/vm/levm/src/opcode_handlers/block.rs index bb6ef5bad..562c2691c 100644 --- a/crates/vm/levm/src/opcode_handlers/block.rs +++ b/crates/vm/levm/src/opcode_handlers/block.rs @@ -110,7 +110,9 @@ impl VM { ) -> Result { self.increase_consumed_gas(current_call_frame, gas_cost::GASLIMIT)?; - current_call_frame.stack.push(self.env.block_gas_limit)?; + current_call_frame + .stack + .push(self.env.block_gas_limit.into())?; Ok(OpcodeSuccess::Continue) } diff --git a/crates/vm/levm/src/opcode_handlers/stack_memory_storage_flow.rs b/crates/vm/levm/src/opcode_handlers/stack_memory_storage_flow.rs index 17a748f0c..36a50e5e3 100644 --- a/crates/vm/levm/src/opcode_handlers/stack_memory_storage_flow.rs +++ b/crates/vm/levm/src/opcode_handlers/stack_memory_storage_flow.rs @@ -185,31 +185,32 @@ impl VM { // Gas Refunds // Sync gas refund with global env, ensuring consistency accross contexts. let mut gas_refunds = self.env.refunded_gas; + if new_storage_slot_value != storage_slot.current_value { if storage_slot.current_value == storage_slot.original_value { if !storage_slot.original_value.is_zero() && new_storage_slot_value.is_zero() { gas_refunds = gas_refunds - .checked_add(U256::from(4800)) + .checked_add(4800) .ok_or(VMError::GasRefundsOverflow)?; } } else if !storage_slot.original_value.is_zero() { if storage_slot.current_value.is_zero() { gas_refunds = gas_refunds - .checked_sub(U256::from(4800)) + .checked_sub(4800) .ok_or(VMError::GasRefundsUnderflow)?; } else if new_storage_slot_value.is_zero() { gas_refunds = gas_refunds - .checked_add(U256::from(4800)) + .checked_add(4800) .ok_or(VMError::GasRefundsOverflow)?; } } else if new_storage_slot_value == storage_slot.original_value { if storage_slot.original_value.is_zero() { gas_refunds = gas_refunds - .checked_add(U256::from(19900)) + .checked_add(19900) .ok_or(VMError::GasRefundsOverflow)?; } else { gas_refunds = gas_refunds - .checked_add(U256::from(2800)) + .checked_add(2800) .ok_or(VMError::GasRefundsOverflow)?; } } @@ -242,7 +243,7 @@ impl VM { .checked_sub(current_call_frame.gas_used) .ok_or(OutOfGasError::ConsumedGasOverflow)?; // Note: These are not consumed gas calculations, but are related, so I used this wrapping here - current_call_frame.stack.push(remaining_gas)?; + current_call_frame.stack.push(remaining_gas.into())?; Ok(OpcodeSuccess::Continue) } diff --git a/crates/vm/levm/src/opcode_handlers/system.rs b/crates/vm/levm/src/opcode_handlers/system.rs index 12bc90306..0cbcb6dda 100644 --- a/crates/vm/levm/src/opcode_handlers/system.rs +++ b/crates/vm/levm/src/opcode_handlers/system.rs @@ -71,7 +71,7 @@ impl VM { // We add the stipend gas for the subcall. This ensures that the callee has enough gas to perform basic operations let gas_for_subcall = if !value_to_transfer.is_zero() { - gas.saturating_add(CALL_POSITIVE_VALUE_STIPEND) + gas.saturating_add(CALL_POSITIVE_VALUE_STIPEND.into()) } else { gas }; @@ -142,7 +142,7 @@ impl VM { // We add the stipend gas for the subcall. This ensures that the callee has enough gas to perform basic operations let gas_for_subcall = if !value_to_transfer.is_zero() { - gas.saturating_add(CALLCODE_POSITIVE_VALUE_STIPEND) + gas.saturating_add(CALLCODE_POSITIVE_VALUE_STIPEND.into()) } else { gas }; @@ -180,10 +180,13 @@ impl VM { } let new_memory_size = calculate_memory_size(offset, size)?; - self.increase_consumed_gas( - current_call_frame, - memory::expansion_cost(new_memory_size, current_call_frame.memory.len())?.into(), - )?; + + let memory_expansion_cost: u64 = + memory::expansion_cost(new_memory_size, current_call_frame.memory.len())? + .try_into() + .map_err(|_err| VMError::Internal(InternalError::ConversionError))?; + + self.increase_consumed_gas(current_call_frame, memory_expansion_cost)?; current_call_frame.output = memory::load_range(&mut current_call_frame.memory, offset, size)? @@ -396,10 +399,13 @@ impl VM { .map_err(|_err| VMError::VeryLargeNumber)?; let new_memory_size = calculate_memory_size(offset, size)?; - self.increase_consumed_gas( - current_call_frame, - memory::expansion_cost(new_memory_size, current_call_frame.memory.len())?.into(), - )?; + + let memory_expansion_cost: u64 = + memory::expansion_cost(new_memory_size, current_call_frame.memory.len())? + .try_into() + .map_err(|_err| VMError::Internal(InternalError::ConversionError))?; + + self.increase_consumed_gas(current_call_frame, memory_expansion_cost)?; current_call_frame.output = memory::load_range(&mut current_call_frame.memory, offset, size)? @@ -488,7 +494,7 @@ impl VM { // Reserve gas for subcall let max_message_call_gas = max_message_call_gas(current_call_frame)?; - self.increase_consumed_gas(current_call_frame, max_message_call_gas.into())?; + self.increase_consumed_gas(current_call_frame, max_message_call_gas)?; // Clear callframe subreturn data current_call_frame.sub_return_data = Bytes::new(); @@ -529,7 +535,7 @@ impl VM { // Return reserved gas current_call_frame.gas_used = current_call_frame .gas_used - .checked_sub(max_message_call_gas.into()) + .checked_sub(max_message_call_gas) .ok_or(VMError::Internal(InternalError::GasOverflow))?; // Push 0 current_call_frame.stack.push(CREATE_DEPLOYMENT_FAIL)?; @@ -569,8 +575,8 @@ impl VM { value_in_wei_to_send, Bytes::new(), false, - U256::from(max_message_call_gas), - U256::zero(), + max_message_call_gas, + 0, new_depth, true, ); @@ -585,8 +591,9 @@ impl VM { // Return reserved gas current_call_frame.gas_used = current_call_frame .gas_used - .checked_sub(unused_gas.into()) + .checked_sub(unused_gas) .ok_or(InternalError::GasOverflow)?; + current_call_frame.logs.extend(tx_report.logs); match tx_report.result { @@ -615,6 +622,9 @@ impl VM { } #[allow(clippy::too_many_arguments)] + /// This (should) be the only function where gas is used as a + /// U256. This is because we have to use the values that are + /// pushed to the stack. pub fn generic_call( &mut self, current_call_frame: &mut CallFrame, @@ -658,6 +668,12 @@ impl VM { let gas_cap = max_message_call_gas(current_call_frame)?; let gas_limit = std::cmp::min(gas_limit, gas_cap.into()); + // This should always cast correcly because the gas_cap is in + // u64; therefore, at most, it will be u64::MAX + let gas_limit: u64 = gas_limit + .try_into() + .map_err(|_| VMError::Internal(InternalError::ConversionError))?; + let mut new_call_frame = CallFrame::new( msg_sender, to, @@ -667,7 +683,7 @@ impl VM { calldata.into(), is_static, gas_limit, - U256::zero(), + 0, new_depth, false, ); @@ -683,7 +699,7 @@ impl VM { // Add gas used by the sub-context to the current one after it's execution. current_call_frame.gas_used = current_call_frame .gas_used - .checked_add(tx_report.gas_used.into()) + .checked_add(tx_report.gas_used) .ok_or(VMError::OutOfGas(OutOfGasError::ConsumedGasOverflow))?; current_call_frame.logs.extend(tx_report.logs); memory::try_store_range( diff --git a/crates/vm/levm/src/precompiles.rs b/crates/vm/levm/src/precompiles.rs index 9ffef1e9c..d793cb741 100644 --- a/crates/vm/levm/src/precompiles.rs +++ b/crates/vm/levm/src/precompiles.rs @@ -101,9 +101,9 @@ pub fn execute_precompile(current_call_frame: &mut CallFrame) -> Result Result<(), VMError> { if gas_for_call < gas_cost { return Err(VMError::PrecompileError(PrecompileError::NotEnoughGas)); @@ -135,10 +135,10 @@ fn fill_with_zeros(slice: &[u8]) -> Result<[u8; 128], VMError> { pub fn ecrecover( calldata: &Bytes, - gas_for_call: U256, - consumed_gas: &mut U256, + gas_for_call: u64, + consumed_gas: &mut u64, ) -> Result { - let gas_cost = ECRECOVER_COST.into(); + let gas_cost = ECRECOVER_COST; increase_precompile_consumed_gas(gas_for_call, gas_cost, consumed_gas)?; @@ -193,16 +193,16 @@ pub fn ecrecover( fn identity( _calldata: &Bytes, - _gas_for_call: U256, - _consumed_gas: &mut U256, + _gas_for_call: u64, + _consumed_gas: &mut u64, ) -> Result { Ok(Bytes::new()) } pub fn sha2_256( calldata: &Bytes, - gas_for_call: U256, - consumed_gas: &mut U256, + gas_for_call: u64, + consumed_gas: &mut u64, ) -> Result { let gas_cost = sha2_256_cost(calldata.len())?; @@ -215,8 +215,8 @@ pub fn sha2_256( pub fn ripemd_160( calldata: &Bytes, - gas_for_call: U256, - consumed_gas: &mut U256, + gas_for_call: u64, + consumed_gas: &mut u64, ) -> Result { let gas_cost = ripemd_160_cost(calldata.len())?; @@ -234,48 +234,40 @@ pub fn ripemd_160( fn modexp( _calldata: &Bytes, - _gas_for_call: U256, - _consumed_gas: &mut U256, + _gas_for_call: u64, + _consumed_gas: &mut u64, ) -> Result { Ok(Bytes::new()) } -fn ecadd( - _calldata: &Bytes, - _gas_for_call: U256, - _consumed_gas: &mut U256, -) -> Result { +fn ecadd(_calldata: &Bytes, _gas_for_call: u64, _consumed_gas: &mut u64) -> Result { Ok(Bytes::new()) } -fn ecmul( - _calldata: &Bytes, - _gas_for_call: U256, - _consumed_gas: &mut U256, -) -> Result { +fn ecmul(_calldata: &Bytes, _gas_for_call: u64, _consumed_gas: &mut u64) -> Result { Ok(Bytes::new()) } fn ecpairing( _calldata: &Bytes, - _gas_for_call: U256, - _consumed_gas: &mut U256, + _gas_for_call: u64, + _consumed_gas: &mut u64, ) -> Result { Ok(Bytes::new()) } fn blake2f( _calldata: &Bytes, - _gas_for_call: U256, - _consumed_gas: &mut U256, + _gas_for_call: u64, + _consumed_gas: &mut u64, ) -> Result { Ok(Bytes::new()) } fn point_evaluation( _calldata: &Bytes, - _gas_for_call: U256, - _consumed_gas: &mut U256, + _gas_for_call: u64, + _consumed_gas: &mut u64, ) -> Result { Ok(Bytes::new()) } diff --git a/crates/vm/levm/src/vm.rs b/crates/vm/levm/src/vm.rs index f91d5309a..a40780931 100644 --- a/crates/vm/levm/src/vm.rs +++ b/crates/vm/levm/src/vm.rs @@ -176,7 +176,7 @@ impl VM { calldata.clone(), false, env.gas_limit, - U256::zero(), + 0, 0, false, ); @@ -230,7 +230,7 @@ impl VM { calldata, // Calldata is removed after passing validations. false, env.gas_limit, - U256::zero(), + 0, 0, false, ); @@ -277,7 +277,7 @@ impl VM { return Ok(TransactionReport { result: TxResult::Success, new_state: self.cache.clone(), - gas_used: current_call_frame.gas_used.low_u64(), + gas_used: current_call_frame.gas_used, gas_refunded: 0, output, logs: current_call_frame.logs.clone(), @@ -301,7 +301,7 @@ impl VM { return Ok(TransactionReport { result: TxResult::Revert(error), new_state: self.cache.clone(), - gas_used: current_call_frame.gas_limit.low_u64(), + gas_used: current_call_frame.gas_limit, gas_refunded: 0, output: Bytes::new(), logs: current_call_frame.logs.clone(), @@ -434,11 +434,15 @@ impl VM { { let contract_code = current_call_frame.output.clone(); let code_length = contract_code.len(); - let code_deposit_cost = U256::from(code_length) - .checked_mul(CODE_DEPOSIT_COST) - .ok_or(VMError::Internal( - InternalError::ArithmeticOperationOverflow, - ))?; + + let code_length_u64: u64 = code_length + .try_into() + .map_err(|_| VMError::Internal(InternalError::ConversionError))?; + + let code_deposit_cost: u64 = + code_length_u64.checked_mul(CODE_DEPOSIT_COST).ok_or( + VMError::Internal(InternalError::ArithmeticOperationOverflow), + )?; // Revert // If the first byte of code is 0xef @@ -475,8 +479,8 @@ impl VM { return Ok(TransactionReport { result: TxResult::Revert(error), new_state: self.cache.clone(), - gas_used: current_call_frame.gas_used.low_u64(), - gas_refunded: self.env.refunded_gas.low_u64(), + gas_used: current_call_frame.gas_used, + gas_refunded: self.env.refunded_gas, output: current_call_frame.output.clone(), logs: current_call_frame.logs.clone(), created_address: None, @@ -488,8 +492,8 @@ impl VM { return Ok(TransactionReport { result: TxResult::Success, new_state: self.cache.clone(), - gas_used: current_call_frame.gas_used.low_u64(), - gas_refunded: self.env.refunded_gas.low_u64(), + gas_used: current_call_frame.gas_used, + gas_refunded: self.env.refunded_gas, output: current_call_frame.output.clone(), logs: current_call_frame.logs.clone(), created_address: None, @@ -521,8 +525,8 @@ impl VM { return Ok(TransactionReport { result: TxResult::Revert(error), new_state: self.cache.clone(), - gas_used: current_call_frame.gas_used.low_u64(), - gas_refunded: self.env.refunded_gas.low_u64(), + gas_used: current_call_frame.gas_used, + gas_refunded: self.env.refunded_gas, output: current_call_frame.output.clone(), // Bytes::new() if error is not RevertOpcode logs: current_call_frame.logs.clone(), created_address: None, @@ -536,7 +540,7 @@ impl VM { &mut self, backup_cache: CacheDB, backup_substate: Substate, - backup_refunded_gas: U256, + backup_refunded_gas: u64, backup_transient_storage: TransientStorage, ) { self.cache = backup_cache; @@ -553,7 +557,7 @@ impl VM { // Intrinsic gas is the gas consumed by the transaction before the execution of the opcodes. Section 6.2 in the Yellow Paper. // Intrinsic Gas = Calldata cost + Create cost + Base cost + Access list cost - let mut intrinsic_gas = U256::zero(); + let mut intrinsic_gas: u64 = 0; // Calldata Cost // 4 gas for each zero byte in the transaction data 16 gas for each non-zero byte in the transaction. @@ -576,18 +580,19 @@ impl VM { .ok_or(OutOfGasError::ConsumedGasOverflow)?; let number_of_words = initial_call_frame.calldata.len().div_ceil(WORD_SIZE); + let double_number_of_words: u64 = number_of_words + .checked_mul(2) + .ok_or(OutOfGasError::ConsumedGasOverflow)? + .try_into() + .map_err(|_| VMError::Internal(InternalError::ConversionError))?; intrinsic_gas = intrinsic_gas - .checked_add( - U256::from(number_of_words) - .checked_mul(U256::from(2)) - .ok_or(OutOfGasError::ConsumedGasOverflow)?, - ) + .checked_add(double_number_of_words) .ok_or(OutOfGasError::ConsumedGasOverflow)?; } // Access List Cost - let mut access_lists_cost = U256::zero(); + let mut access_lists_cost: u64 = 0; for (_, keys) in self.access_list.clone() { access_lists_cost = access_lists_cost .checked_add(ACCESS_LIST_ADDRESS_COST) @@ -610,8 +615,15 @@ impl VM { } /// Gets the max blob gas cost for a transaction that a user is willing to pay. - fn get_max_blob_gas_cost(&self) -> Result { - let blob_gas_used = U256::from(self.env.tx_blob_hashes.len()) + fn get_max_blob_gas_price(&self) -> Result { + let blobhash_amount: u64 = self + .env + .tx_blob_hashes + .len() + .try_into() + .map_err(|_| VMError::Internal(InternalError::ConversionError))?; + + let blob_gas_used: u64 = blobhash_amount .checked_mul(BLOB_GAS_PER_BLOB) .unwrap_or_default(); @@ -619,23 +631,31 @@ impl VM { .env .tx_max_fee_per_blob_gas .unwrap_or_default() - .checked_mul(blob_gas_used) + .checked_mul(blob_gas_used.into()) .ok_or(InternalError::UndefinedState(1))?; Ok(max_blob_gas_cost) } /// Gets the actual blob gas cost. - fn get_blob_gas_cost(&self) -> Result { - let blob_gas_used = U256::from(self.env.tx_blob_hashes.len()) + fn get_blob_gas_price(&self) -> Result { + let blobhash_amount: u64 = self + .env + .tx_blob_hashes + .len() + .try_into() + .map_err(|_| VMError::Internal(InternalError::ConversionError))?; + + let blob_gas_price: u64 = blobhash_amount .checked_mul(BLOB_GAS_PER_BLOB) .unwrap_or_default(); let base_fee_per_blob_gas = self.get_base_fee_per_blob_gas()?; - let blob_fee = blob_gas_used + let blob_gas_price: U256 = blob_gas_price.into(); + let blob_fee: U256 = blob_gas_price .checked_mul(base_fee_per_blob_gas) - .ok_or(InternalError::UndefinedState(1))?; + .ok_or(VMError::Internal(InternalError::UndefinedState(1)))?; Ok(blob_fee) } @@ -643,9 +663,14 @@ impl VM { pub fn get_base_fee_per_blob_gas(&self) -> Result { fake_exponential( MIN_BASE_FEE_PER_BLOB_GAS, - self.env.block_excess_blob_gas.unwrap_or_default().low_u64(), //Maybe replace unwrap_or_default for sth else later. + self.env + .block_excess_blob_gas + .unwrap_or_default() + .try_into() + .map_err(|_| VMError::VeryLargeNumber)?, //Maybe replace unwrap_or_default for sth else later. BLOB_BASE_FEE_UPDATE_FRACTION, ) + .map(|ok_value| ok_value.into()) } /// ## Description @@ -661,20 +686,20 @@ impl VM { let sender_account = self.get_account(sender_address); // (1) GASLIMIT_PRICE_PRODUCT_OVERFLOW - let gaslimit_price_product = - self.env - .gas_price - .checked_mul(self.env.gas_limit) - .ok_or(VMError::TxValidation( - TxValidationError::GasLimitPriceProductOverflow, - ))?; + let gaslimit_price_product = self + .env + .gas_price + .checked_mul(self.env.gas_limit.into()) + .ok_or(VMError::TxValidation( + TxValidationError::GasLimitPriceProductOverflow, + ))?; // Up front cost is the maximum amount of wei that a user is willing to pay for. Gaslimit * gasprice + value + blob_gas_cost let value = initial_call_frame.msg_value; // blob gas cost = max fee per blob gas * blob gas used // https://eips.ethereum.org/EIPS/eip-4844 - let max_blob_gas_cost = self.get_max_blob_gas_cost()?; + let max_blob_gas_cost = self.get_max_blob_gas_price()?; // For the transaction to be valid the sender account has to have a balance >= gas_price * gas_limit + value if tx is type 0 and 1 // balance >= max_fee_per_gas * gas_limit + value + blob_gas_cost if tx is type 2 or 3 @@ -682,7 +707,7 @@ impl VM { .env .tx_max_fee_per_gas .unwrap_or(self.env.gas_price) - .checked_mul(self.env.gas_limit) + .checked_mul(self.env.gas_limit.into()) .ok_or(VMError::TxValidation( TxValidationError::GasLimitPriceProductOverflow, ))?; @@ -702,7 +727,7 @@ impl VM { )); } - let blob_gas_cost = self.get_blob_gas_cost()?; + let blob_gas_cost = self.get_blob_gas_price()?; // The real cost to deduct is calculated as effective_gas_price * gas_limit + value + blob_gas_cost let up_front_cost = gaslimit_price_product @@ -854,7 +879,7 @@ impl VM { } // 2. Return unused gas + gas refunds to the sender. - let max_gas = self.env.gas_limit.low_u64(); + let max_gas = self.env.gas_limit; let consumed_gas = report.gas_used; let refunded_gas = report.gas_refunded.min( consumed_gas @@ -998,7 +1023,7 @@ impl VM { pub fn increase_consumed_gas( &mut self, current_call_frame: &mut CallFrame, - gas: U256, + gas: u64, ) -> Result<(), VMError> { let potential_consumed_gas = current_call_frame .gas_used @@ -1194,7 +1219,7 @@ impl VM { ) -> Result { let mut report = TransactionReport { result: TxResult::Revert(VMError::AddressAlreadyOccupied), - gas_used: self.env.gas_limit.low_u64(), + gas_used: self.env.gas_limit, gas_refunded: 0, logs: vec![], new_state: self.cache.clone(), diff --git a/crates/vm/levm/tests/edge_case_tests.rs b/crates/vm/levm/tests/edge_case_tests.rs index 80a759552..80ece79c7 100644 --- a/crates/vm/levm/tests/edge_case_tests.rs +++ b/crates/vm/levm/tests/edge_case_tests.rs @@ -17,7 +17,7 @@ fn test_extcodecopy_memory_allocation() { ])) .unwrap(); let mut current_call_frame = vm.call_frames.pop().unwrap(); - current_call_frame.gas_limit = U256::from(100_000_000); + current_call_frame.gas_limit = 100_000_000; vm.env.gas_price = U256::from(10_000); vm.execute(&mut current_call_frame).unwrap(); } @@ -293,8 +293,8 @@ fn test_non_compliance_codecopy_memory_resize() { fn test_non_compliance_log_gas_cost() { let mut vm = new_vm_with_bytecode(Bytes::copy_from_slice(&[56, 68, 68, 68, 131, 163])).unwrap(); vm.env.gas_price = U256::zero(); - vm.env.gas_limit = U256::from(100_000_000); - vm.env.block_gas_limit = U256::from(100_000_001); + vm.env.gas_limit = 100_000_000; + vm.env.block_gas_limit = 100_000_001; let res = vm.transact().unwrap(); assert_eq!(res.gas_used, 22511); } diff --git a/crates/vm/levm/tests/tests.rs b/crates/vm/levm/tests/tests.rs index 9e3a46937..9d279e8b8 100644 --- a/crates/vm/levm/tests/tests.rs +++ b/crates/vm/levm/tests/tests.rs @@ -441,7 +441,7 @@ fn and_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0b1000)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -453,7 +453,7 @@ fn and_binary_with_zero() { Operation::Stop, ]) .unwrap(); - let expected_consumed_gas = gas_cost::AND + gas_cost::PUSHN.checked_mul(U256::from(2)).unwrap(); + let expected_consumed_gas = gas_cost::AND + gas_cost::PUSHN.checked_mul(2).unwrap(); let mut current_call_frame = vm.call_frames.pop().unwrap(); vm.execute(&mut current_call_frame).unwrap(); @@ -478,7 +478,7 @@ fn and_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xF0F0)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xF000))), @@ -493,7 +493,7 @@ fn and_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xF000)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xB020))), @@ -508,7 +508,7 @@ fn and_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0b1000000000000)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -526,7 +526,7 @@ fn or_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0b1110)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0b1010))), @@ -541,7 +541,7 @@ fn or_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0b1010)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(u64::MAX))), @@ -556,7 +556,7 @@ fn or_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xFFFFFFFFFFFFFFFF_u64)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -574,7 +574,7 @@ fn or_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xFFFF)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xF000))), @@ -589,7 +589,7 @@ fn or_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xF0F0)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xB020))), @@ -604,7 +604,7 @@ fn or_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0b1011111100101111)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -622,7 +622,7 @@ fn xor_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0b110)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0b1010))), @@ -637,7 +637,7 @@ fn xor_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0b1010)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(u64::MAX))), @@ -652,7 +652,7 @@ fn xor_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(u64::MAX)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(u64::MAX))), @@ -667,7 +667,7 @@ fn xor_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -685,7 +685,7 @@ fn xor_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xFF)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xFF))), @@ -700,7 +700,7 @@ fn xor_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xFFFF))), @@ -715,7 +715,7 @@ fn xor_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xF0F)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xF000))), @@ -730,7 +730,7 @@ fn xor_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xF0)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0x4C0F))), @@ -745,7 +745,7 @@ fn xor_with_hex_numbers() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0b111011001000100)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -763,7 +763,7 @@ fn not() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); let expected = !U256::from(0b1010); assert_eq!(result, expected); - assert_eq!(current_call_frame.gas_used, U256::from(6)); + assert_eq!(current_call_frame.gas_used, 6); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::MAX)), @@ -777,7 +777,7 @@ fn not() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(6)); + assert_eq!(current_call_frame.gas_used, 6); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::zero())), @@ -791,7 +791,7 @@ fn not() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::MAX); - assert_eq!(current_call_frame.gas_used, U256::from(6)); + assert_eq!(current_call_frame.gas_used, 6); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(1))), @@ -805,7 +805,7 @@ fn not() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::MAX - 1); - assert_eq!(current_call_frame.gas_used, U256::from(6)); + assert_eq!(current_call_frame.gas_used, 6); } #[test] @@ -823,7 +823,7 @@ fn byte_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xF1)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0x33ED))), @@ -838,7 +838,7 @@ fn byte_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x33)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -856,7 +856,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xFF)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::MAX)), @@ -871,7 +871,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xFF)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0x00E0D0000))), @@ -886,7 +886,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x0D)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xFDEA179))), @@ -901,7 +901,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xFDEA179))), @@ -916,7 +916,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::zero())), @@ -931,7 +931,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let word = U256::from_big_endian(&[ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x57, 0x08, 0x09, 0x90, 0x0B, 0x0C, 0x0D, 0x0E, @@ -952,7 +952,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x90)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, word)), @@ -967,7 +967,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x57)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, word)), @@ -982,7 +982,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xDD)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, word)), @@ -997,7 +997,7 @@ fn byte_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x40)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1015,7 +1015,7 @@ fn shl_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xDDDD)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0x12345678))), @@ -1030,7 +1030,7 @@ fn shl_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x2468acf0)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0x12345678))), @@ -1045,7 +1045,7 @@ fn shl_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(4886718336_u64)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xFF))), @@ -1060,7 +1060,7 @@ fn shl_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xFF << 4)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1078,7 +1078,7 @@ fn shl_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::zero())), @@ -1093,7 +1093,7 @@ fn shl_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::MAX)), @@ -1108,7 +1108,7 @@ fn shl_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::MAX - 1); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1126,7 +1126,7 @@ fn shr_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xDDDD)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0x12345678))), @@ -1141,7 +1141,7 @@ fn shr_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x91a2b3c)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0x12345678))), @@ -1156,7 +1156,7 @@ fn shr_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x1234567)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::from(0xFF))), @@ -1171,7 +1171,7 @@ fn shr_basic() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0xF)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1189,7 +1189,7 @@ fn shr_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::zero())), @@ -1204,7 +1204,7 @@ fn shr_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); let mut vm = new_vm_with_ops(&[ Operation::Push((32, U256::MAX)), @@ -1219,7 +1219,7 @@ fn shr_edge_cases() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::MAX >> 1); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1237,7 +1237,7 @@ fn sar_shift_by_0() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x12345678)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1266,7 +1266,7 @@ fn sar_shifting_large_value_with_all_bits_set() { 0xff, 0xff, ]); assert_eq!(result, expected); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1295,7 +1295,7 @@ fn sar_shifting_negative_value_and_small_shift() { 0x00, 0x00, ]); assert_eq!(result, expected); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1313,7 +1313,7 @@ fn sar_shift_positive_value() { let result = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(result, U256::from(0x07FFFF)); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1343,7 +1343,7 @@ fn sar_shift_negative_value() { ]); // change 0x8f to 0xf8 assert_eq!(result, expected); - assert_eq!(current_call_frame.gas_used, U256::from(9)); + assert_eq!(current_call_frame.gas_used, 9); } #[test] @@ -1373,7 +1373,7 @@ fn keccak256_zero_offset_size_four() { U256::from("0x29045a592007d0c246ef02c2223570da9522d0cf0f73282c79a1bc8f0bb2c238") ); assert_eq!(vm.current_call_frame_mut().unwrap().pc(), 40); - assert_eq!(current_call_frame.gas_used, U256::from(52)); + assert_eq!(current_call_frame.gas_used, 52); } #[test] @@ -1403,7 +1403,7 @@ fn keccak256_zero_offset_size_bigger_than_actual_memory() { == U256::from("0xae75624a7d0413029c1e0facdd38cc8e177d9225892e2490a69c2f1f89512061") ); assert_eq!(vm.current_call_frame_mut().unwrap().pc(), 40); - assert_eq!(current_call_frame.gas_used, U256::from(61)); + assert_eq!(current_call_frame.gas_used, 61); } #[test] @@ -1425,7 +1425,7 @@ fn keccak256_zero_offset_zero_size() { U256::from("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470") ); assert_eq!(vm.current_call_frame_mut().unwrap().pc(), 4); - assert_eq!(current_call_frame.gas_used, U256::from(34)); + assert_eq!(current_call_frame.gas_used, 34); } #[test] @@ -1455,7 +1455,7 @@ fn keccak256_offset_four_size_four() { U256::from("0xe8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c") ); assert_eq!(vm.current_call_frame_mut().unwrap().pc(), 41); - assert_eq!(current_call_frame.gas_used, U256::from(53)); + assert_eq!(current_call_frame.gas_used, 53); } #[test] @@ -1477,7 +1477,7 @@ fn mstore() { U256::from(32) ); assert_eq!(vm.current_call_frame_mut().unwrap().pc(), 69); - assert_eq!(current_call_frame.gas_used, U256::from(14)); + assert_eq!(current_call_frame.gas_used, 14); } #[test] @@ -1504,7 +1504,7 @@ fn mstore_saves_correct_value() { let memory_size = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(memory_size, U256::from(32)); - assert_eq!(current_call_frame.gas_used, U256::from(14)); + assert_eq!(current_call_frame.gas_used, 14); } #[test] @@ -1531,7 +1531,7 @@ fn mstore8() { stored_value.to_big_endian(&mut value_bytes); assert_eq!(value_bytes[0..1], [0xAB]); - assert_eq!(current_call_frame.gas_used, U256::from(12)); + assert_eq!(current_call_frame.gas_used, 12); } #[test] @@ -1562,7 +1562,7 @@ fn mcopy() { let memory_size = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(memory_size, U256::from(96)); - assert_eq!(current_call_frame.gas_used, U256::from(35)); + assert_eq!(current_call_frame.gas_used, 35); } #[test] @@ -1583,7 +1583,7 @@ fn mload() { let loaded_value = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(loaded_value, U256::from(0x33333)); - assert_eq!(current_call_frame.gas_used, U256::from(18)); + assert_eq!(current_call_frame.gas_used, 18); } #[test] @@ -1597,7 +1597,7 @@ fn msize() { let initial_size = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(initial_size, U256::zero()); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); let operations = [ Operation::Push((32, U256::from(0x33333))), // value @@ -1614,7 +1614,7 @@ fn msize() { let after_store_size = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(after_store_size, U256::from(32)); - assert_eq!(current_call_frame.gas_used, U256::from(14)); + assert_eq!(current_call_frame.gas_used, 14); let operations = [ Operation::Push((32, U256::from(0x55555))), // value @@ -1631,7 +1631,7 @@ fn msize() { let final_size = vm.current_call_frame_mut().unwrap().stack.pop().unwrap(); assert_eq!(final_size, U256::from(96)); - assert_eq!(current_call_frame.gas_used, U256::from(20)); + assert_eq!(current_call_frame.gas_used, 20); } #[test] @@ -1656,7 +1656,7 @@ fn mstore_mload_offset_not_multiple_of_32() { assert_eq!(loaded_value, U256::from(0xabcdef)); assert_eq!(memory_size, U256::from(64)); - assert_eq!(current_call_frame.gas_used, U256::from(23)); + assert_eq!(current_call_frame.gas_used, 23); // check with big offset @@ -1680,7 +1680,7 @@ fn mstore_mload_offset_not_multiple_of_32() { assert_eq!(loaded_value, U256::from(0x123456)); assert_eq!(memory_size, U256::from(2048)); - assert_eq!(current_call_frame.gas_used, U256::from(217)); + assert_eq!(current_call_frame.gas_used, 217); } #[test] @@ -1702,7 +1702,7 @@ fn mload_uninitialized_memory() { assert_eq!(loaded_value, U256::zero()); assert_eq!(memory_size, U256::from(96)); - assert_eq!(current_call_frame.gas_used, U256::from(17)); + assert_eq!(current_call_frame.gas_used, 17); } #[test] @@ -2002,7 +2002,7 @@ fn pc_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::zero() ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2022,7 +2022,7 @@ fn pc_op_with_push_offset() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::from(33) ); - assert_eq!(current_call_frame.gas_used, U256::from(5)); + assert_eq!(current_call_frame.gas_used, 5); } // #[test] @@ -2320,7 +2320,7 @@ fn jumpi_not_zero() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::from(10) ); - assert_eq!(current_call_frame.gas_used, U256::from(20)); + assert_eq!(current_call_frame.gas_used, 20); } #[test] @@ -2345,7 +2345,7 @@ fn jumpi_for_zero() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::from(100) ); - assert_eq!(current_call_frame.gas_used, U256::from(19)); + assert_eq!(current_call_frame.gas_used, 19); } // This test is just for trying things out, not a real test. But it is useful to have this as an example for conversions between bytes and u256. @@ -2423,7 +2423,7 @@ fn calldataload() { 0x00, 0x00, 0x00, 0x00 ]) ); - assert_eq!(current_call_frame.gas_used, U256::from(6)); + assert_eq!(current_call_frame.gas_used, 6); } #[test] @@ -2519,7 +2519,7 @@ fn calldatasize() { let current_call_frame = vm.current_call_frame_mut().unwrap(); let top_of_stack = current_call_frame.stack.pop().unwrap(); assert_eq!(top_of_stack, U256::from(3)); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2542,7 +2542,7 @@ fn calldatacopy() { let current_call_frame = vm.current_call_frame_mut().unwrap(); let memory = memory::load_range(&mut current_call_frame.memory, U256::zero(), 2).unwrap(); assert_eq!(memory, vec![0x22, 0x33]); - assert_eq!(current_call_frame.gas_used, U256::from(18)); + assert_eq!(current_call_frame.gas_used, 18); } #[test] @@ -2559,7 +2559,7 @@ fn returndatasize() { let current_call_frame = vm.current_call_frame_mut().unwrap(); let top_of_stack = current_call_frame.stack.pop().unwrap(); assert_eq!(top_of_stack, U256::from(3)); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2582,7 +2582,7 @@ fn returndatacopy() { let current_call_frame = vm.current_call_frame_mut().unwrap(); let memory = memory::load_range(&mut current_call_frame.memory, U256::zero(), 2).unwrap(); assert_eq!(memory, vec![0xBB, 0xCC]); - assert_eq!(current_call_frame.gas_used, U256::from(18)); + assert_eq!(current_call_frame.gas_used, 18); } #[test] @@ -2669,7 +2669,7 @@ fn blockhash_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), expected_block_hash ); - assert_eq!(current_call_frame.gas_used, U256::from(23)); + assert_eq!(current_call_frame.gas_used, 23); } #[test] @@ -2701,7 +2701,7 @@ fn blockhash_same_block_number() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), expected_block_hash ); - assert_eq!(current_call_frame.gas_used, U256::from(23)); + assert_eq!(current_call_frame.gas_used, 23); } #[test] @@ -2737,7 +2737,7 @@ fn blockhash_block_number_not_from_recent_256() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), expected_block_hash ); - assert_eq!(current_call_frame.gas_used, U256::from(23)); + assert_eq!(current_call_frame.gas_used, 23); } #[test] @@ -2756,7 +2756,7 @@ fn coinbase_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::from(coinbase_address) ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2775,7 +2775,7 @@ fn timestamp_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), timestamp ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2794,7 +2794,7 @@ fn number_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), block_number ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2813,7 +2813,7 @@ fn prevrandao_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::from_big_endian(&prevrandao.0) ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2830,9 +2830,9 @@ fn gaslimit_op() { assert_eq!( vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), - gas_limit + gas_limit.into() ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2877,7 +2877,7 @@ fn chain_id_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), chain_id ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2896,7 +2896,7 @@ fn basefee_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), base_fee_per_gas ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } // TODO: Add excess_blob_gas and blob_gas_used to env @@ -2915,7 +2915,7 @@ fn blobbasefee_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::from(2) ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } // TODO: Add excess_blob_gas and blob_gas_used to env @@ -2934,7 +2934,7 @@ fn blobbasefee_minimum_cost() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::one() ); - assert_eq!(current_call_frame.gas_used, U256::from(2)); + assert_eq!(current_call_frame.gas_used, 2); } #[test] @@ -2955,7 +2955,7 @@ fn pop_op() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::one() ); - assert_eq!(current_call_frame.gas_used, U256::from(8)); + assert_eq!(current_call_frame.gas_used, 8); } #[test] @@ -2979,7 +2979,7 @@ fn jump_op() { U256::from(10) ); assert_eq!(vm.current_call_frame_mut().unwrap().pc(), 70); - assert_eq!(current_call_frame.gas_used, U256::from(15)); + assert_eq!(current_call_frame.gas_used, 15); } #[test] @@ -3148,7 +3148,7 @@ fn log0() { assert_eq!(logs.len(), 1); assert_eq!(logs[0].data, data.to_vec()); assert_eq!(logs[0].topics.len(), 0); - assert_eq!(current_call_frame.gas_used, U256::from(649)); + assert_eq!(current_call_frame.gas_used, 649); } #[test] @@ -3178,7 +3178,7 @@ fn log1() { assert_eq!(logs.len(), 1); assert_eq!(logs[0].data, data.to_vec()); assert_eq!(logs[0].topics, vec![H256::from_slice(&topic1)]); - assert_eq!(current_call_frame.gas_used, U256::from(1027)); + assert_eq!(current_call_frame.gas_used, 1027); } #[test] @@ -3214,7 +3214,7 @@ fn log2() { logs[0].topics, vec![H256::from_slice(&topic1), H256::from_slice(&topic2)] ); - assert_eq!(current_call_frame.gas_used, U256::from(1405)); + assert_eq!(current_call_frame.gas_used, 1405); } #[test] @@ -3257,7 +3257,7 @@ fn log3() { H256::from_slice(&topic3) ] ); - assert_eq!(current_call_frame.gas_used, U256::from(1783)); + assert_eq!(current_call_frame.gas_used, 1783); } #[test] @@ -3304,7 +3304,7 @@ fn log4() { H256::from_slice(&topic4) ] ); - assert_eq!(current_call_frame.gas_used, U256::from(2161)); + assert_eq!(current_call_frame.gas_used, 2161); } #[test] @@ -3329,7 +3329,7 @@ fn log_with_0_data_size() { assert_eq!(logs.len(), 1); assert_eq!(logs[0].data, Vec::new()); assert_eq!(logs[0].topics.len(), 0); - assert_eq!(current_call_frame.gas_used, U256::from(393)); + assert_eq!(current_call_frame.gas_used, 393); } #[test] @@ -3382,7 +3382,7 @@ fn log_with_data_in_memory_smaller_than_size() { assert_eq!(logs.len(), 1); assert_eq!(logs[0].data, data); assert_eq!(logs[0].topics.len(), 0); - assert_eq!(current_call_frame.gas_used, U256::from(649)); + assert_eq!(current_call_frame.gas_used, 649); } #[test] @@ -4257,10 +4257,7 @@ fn codecopy_op() { .unwrap(), expected_memory ); - assert_eq!( - current_call_frame.gas_used, - U256::from(9) + U256::from(3) * gas_cost::PUSHN - ); + assert_eq!(current_call_frame.gas_used, 9 + 3 * gas_cost::PUSHN); } #[test] @@ -4286,7 +4283,7 @@ fn extcodesize_existing_account() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), 23.into() ); - assert_eq!(current_call_frame.gas_used, 2603.into()); + assert_eq!(current_call_frame.gas_used, 2603); } #[test] @@ -4306,7 +4303,7 @@ fn extcodesize_non_existing_account() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), 0.into() ); - assert_eq!(current_call_frame.gas_used, 2603.into()); + assert_eq!(current_call_frame.gas_used, 2603); } #[test] @@ -4342,7 +4339,7 @@ fn extcodecopy_existing_account() { .unwrap(), vec![0x60] ); - assert_eq!(current_call_frame.gas_used, 2616.into()); + assert_eq!(current_call_frame.gas_used, 2616); } #[test] @@ -4372,7 +4369,7 @@ fn extcodecopy_non_existing_account() { .unwrap(), vec![0; size] ); - assert_eq!(current_call_frame.gas_used, 2616.into()); + assert_eq!(current_call_frame.gas_used, 2616); } #[test] @@ -4396,7 +4393,7 @@ fn extcodehash_account_with_zero_bytecode_but_not_empty() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".into() ); - assert_eq!(current_call_frame.gas_used, 2603.into()); + assert_eq!(current_call_frame.gas_used, 2603); } #[test] @@ -4417,7 +4414,7 @@ fn extcodehash_non_existing_account() { vm.current_call_frame_mut().unwrap().stack.pop().unwrap(), U256::zero() ); - assert_eq!(current_call_frame.gas_used, 2603.into()); + assert_eq!(current_call_frame.gas_used, 2603); } #[test] @@ -4492,15 +4489,15 @@ fn recover_test() { let calldata = hex::decode("456e9aea5e197a1f1af7a3e85a3212fa4049a3ba34c2289b4c860fc0b0c64ef3000000000000000000000000000000000000000000000000000000000000001c9242685bf161793cc25603c231bc2f568eb630ea16aa137d2664ac80388256084f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852ada").unwrap(); let calldata = Bytes::from(calldata); - let mut consumed_gas = U256::zero(); - let result = ecrecover(&calldata, 10000.into(), &mut consumed_gas).unwrap(); + let mut consumed_gas = 0; + let result = ecrecover(&calldata, 10000, &mut consumed_gas).unwrap(); let expected_result = Bytes::from( hex::decode("0000000000000000000000007156526fbd7a3c72969b54f64e42c10fbb768c8a").unwrap(), ); assert_eq!(result, expected_result); - assert_eq!(consumed_gas, ECRECOVER_COST.into()); + assert_eq!(consumed_gas, ECRECOVER_COST); } #[test] @@ -4508,18 +4505,15 @@ fn sha2_256_test() { let calldata = hex::decode("ff").unwrap(); let calldata = Bytes::from(calldata); - let mut consumed_gas = U256::zero(); - let result = sha2_256(&calldata, 10000.into(), &mut consumed_gas).unwrap(); + let mut consumed_gas = 0; + let result = sha2_256(&calldata, 10000, &mut consumed_gas).unwrap(); let expected_result = Bytes::from( hex::decode("a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89").unwrap(), ); assert_eq!(result, expected_result); - assert_eq!( - consumed_gas, - (SHA2_256_STATIC_COST + SHA2_256_DYNAMIC_BASE).into() - ); + assert_eq!(consumed_gas, (SHA2_256_STATIC_COST + SHA2_256_DYNAMIC_BASE)); } #[test] @@ -4527,8 +4521,8 @@ fn ripemd_160_test() { let calldata = hex::decode("ff").unwrap(); let calldata = Bytes::from(calldata); - let mut consumed_gas = U256::zero(); - let result = ripemd_160(&calldata, 10000.into(), &mut consumed_gas).unwrap(); + let mut consumed_gas = 0; + let result = ripemd_160(&calldata, 10000, &mut consumed_gas).unwrap(); let expected_result = Bytes::from( hex::decode("0000000000000000000000002c0c45d3ecab80fe060e5f1d7057cd2f8de5e557").unwrap(), @@ -4537,6 +4531,6 @@ fn ripemd_160_test() { assert_eq!(result, expected_result); assert_eq!( consumed_gas, - (RIPEMD_160_STATIC_COST + RIPEMD_160_DYNAMIC_BASE).into() + (RIPEMD_160_STATIC_COST + RIPEMD_160_DYNAMIC_BASE) ); } diff --git a/crates/vm/vm.rs b/crates/vm/vm.rs index 00a6f07a1..c2940edc3 100644 --- a/crates/vm/vm.rs +++ b/crates/vm/vm.rs @@ -169,8 +169,8 @@ cfg_if::cfg_if! { let env = Environment { origin: tx.sender(), - refunded_gas: U256::zero(), - gas_limit: tx.gas_limit().into(), + refunded_gas: 0, + gas_limit: tx.gas_limit(), block_number: block_header.number.into(), coinbase: block_header.coinbase, timestamp: block_header.timestamp.into(), @@ -184,7 +184,7 @@ cfg_if::cfg_if! { tx_max_priority_fee_per_gas: tx.max_priority_fee().map(U256::from), tx_max_fee_per_gas: tx.max_fee_per_gas().map(U256::from), tx_max_fee_per_blob_gas: tx.max_fee_per_blob_gas().map(U256::from), - block_gas_limit: block_header.gas_limit.into(), + block_gas_limit: block_header.gas_limit, transient_storage: HashMap::new(), };