From b6f60aa08371798ef7eb7285d49b737f381883d6 Mon Sep 17 00:00:00 2001 From: otaliptus Date: Wed, 20 Mar 2024 18:00:56 +0300 Subject: [PATCH] Update call + genesis + tests --- .../genesis/demo-tests/mock/evm.json | 18 +-- .../sov-evm/src/evm/call.rs | 140 +++++++++++++++--- .../sov-evm/src/query.rs | 9 +- .../src/tests/queries/basic_queries.rs | 6 +- .../src/tests/queries/evm_call_tests.rs | 21 ++- 5 files changed, 148 insertions(+), 46 deletions(-) diff --git a/examples/test-data/genesis/demo-tests/mock/evm.json b/examples/test-data/genesis/demo-tests/mock/evm.json index 0784e7587..35c5ca636 100644 --- a/examples/test-data/genesis/demo-tests/mock/evm.json +++ b/examples/test-data/genesis/demo-tests/mock/evm.json @@ -2,63 +2,63 @@ "data": [ { "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "balance": "0xffffffffffffffff", + "balance": "0xffffffffffffffffffffffffffffff", "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "code": "0x", "nonce": 0 }, { "address": "0x66f68692c03eB9C0656D676f2F4bD13eba40D1B7", - "balance": "0xffffffffffffffff", + "balance": "0xffffffffffffffffffffffffffffff", "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "code": "0x", "nonce": 0 }, { "address": "0xaafB7442f7F00B64057C2e9EaE2815bb63Ee0EcE", - "balance": "0xffffffffffffffff", + "balance": "0xffffffffffffffffffffffffffffff", "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "code": "0x", "nonce": 0 }, { "address": "0x9fCDf8f60d3009656E50Bf805Cd53C7335b284Fb", - "balance": "0xffffffffffffffff", + "balance": "0xffffffffffffffffffffffffffffff", "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "code": "0x", "nonce": 0 }, { "address": "0xe756fdf89367EF428b48BCa2d272Ec8EcEC053fD", - "balance": "0xffffffffffffffff", + "balance": "0xffffffffffffffffffffffffffffff", "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "code": "0x", "nonce": 0 }, { "address": "0x3AEEb871F83C85E68fFD1868bef3425eD6649D39", - "balance": "0xffffffffffffffff", + "balance": "0xffffffffffffffffffffffffffffff", "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "code": "0x", "nonce": 0 }, { "address": "0xd44821f906E3909b8AE944F7060551c33b922cc9", - "balance": "0xffffffffffffffff", + "balance": "0xffffffffffffffffffffffffffffff", "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "code": "0x", "nonce": 0 }, { "address": "0x0f820f428AE436C1000b27577bF5bbf09BfeC8f2", - "balance": "0xffffffffffffffff", + "balance": "0xffffffffffffffffffffffffffffff", "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "code": "0x", "nonce": 0 }, { "address": "0xC2F8Eed77da1583f7bae0a3125Dc7BC426002dDE", - "balance": "0xfffffffffffffffff", + "balance": "0xffffffffffffffffffffffffffffff", "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "code": "0x", "nonce": 0 diff --git a/module-system/module-implementations/sov-evm/src/evm/call.rs b/module-system/module-implementations/sov-evm/src/evm/call.rs index e6203f17c..b71d4c734 100644 --- a/module-system/module-implementations/sov-evm/src/evm/call.rs +++ b/module-system/module-implementations/sov-evm/src/evm/call.rs @@ -1,5 +1,7 @@ // https://github.com/paradigmxyz/reth/blob/main/crates/rpc/rpc/src/eth/revm_utils.rs +use std::cmp::min; + use reth_primitives::{B256, U256}; use reth_rpc_types::TransactionRequest; use revm::primitives::{TransactTo, TxEnv}; @@ -49,21 +51,38 @@ impl CallFees { max_fee_per_blob_gas: Option, block_blob_fee: Option, ) -> EthResult { - /// Ensures that the transaction's max fee is lower than the priority fee, if any. - fn ensure_valid_fee_cap( - max_fee: U256, + /// Get the effective gas price of a transaction as specfified in EIP-1559 with relevant + /// checks. + fn get_effective_gas_price( + max_fee_per_gas: Option, max_priority_fee_per_gas: Option, - ) -> EthResult<()> { - if let Some(max_priority) = max_priority_fee_per_gas { - if max_priority > max_fee { - // Fail early - return Err( - // `max_priority_fee_per_gas` is greater than the `max_fee_per_gas` - RpcInvalidTransactionError::TipAboveFeeCap.into(), - ); + block_base_fee: U256, + ) -> EthResult { + match max_fee_per_gas { + Some(max_fee) => { + if max_fee < block_base_fee { + // `base_fee_per_gas` is greater than the `max_fee_per_gas` + return Err(RpcInvalidTransactionError::FeeCapTooLow.into()); + } + if max_fee < max_priority_fee_per_gas.unwrap_or(U256::ZERO) { + return Err( + // `max_priority_fee_per_gas` is greater than the `max_fee_per_gas` + RpcInvalidTransactionError::TipAboveFeeCap.into(), + ); + } + Ok(min( + max_fee, + block_base_fee + .checked_add(max_priority_fee_per_gas.unwrap_or(U256::ZERO)) + .ok_or_else(|| { + EthApiError::from(RpcInvalidTransactionError::TipVeryHigh) + })?, + )) } + None => Ok(block_base_fee + .checked_add(max_priority_fee_per_gas.unwrap_or(U256::ZERO)) + .ok_or_else(|| EthApiError::from(RpcInvalidTransactionError::TipVeryHigh))?), } - Ok(()) } let has_blob_hashes = blob_versioned_hashes @@ -89,21 +108,27 @@ impl CallFees { } (None, max_fee_per_gas, max_priority_fee_per_gas, None) => { // request for eip-1559 transaction - let max_fee = max_fee_per_gas.unwrap_or(block_base_fee); - ensure_valid_fee_cap(max_fee, max_priority_fee_per_gas)?; + let effective_gas_price = get_effective_gas_price( + max_fee_per_gas, + max_priority_fee_per_gas, + block_base_fee, + )?; let max_fee_per_blob_gas = has_blob_hashes.then_some(block_blob_fee).flatten(); Ok(CallFees { - gas_price: max_fee, + gas_price: effective_gas_price, max_priority_fee_per_gas, max_fee_per_blob_gas, }) } (None, max_fee_per_gas, max_priority_fee_per_gas, Some(max_fee_per_blob_gas)) => { // request for eip-4844 transaction - let max_fee = max_fee_per_gas.unwrap_or(block_base_fee); - ensure_valid_fee_cap(max_fee, max_priority_fee_per_gas)?; + let effective_gas_price = get_effective_gas_price( + max_fee_per_gas, + max_priority_fee_per_gas, + block_base_fee, + )?; // Ensure blob_hashes are present if !has_blob_hashes { @@ -112,7 +137,7 @@ impl CallFees { } Ok(CallFees { - gas_price: max_fee, + gas_price: effective_gas_price, max_priority_fee_per_gas, max_fee_per_blob_gas: Some(max_fee_per_blob_gas), }) @@ -203,3 +228,82 @@ pub(crate) fn prepare_call_env( Ok(env) } + +#[cfg(test)] +mod tests { + use reth_primitives::constants::GWEI_TO_WEI; + + use super::*; + + #[test] + fn test_eip_1559_fees() { + let CallFees { gas_price, .. } = CallFees::ensure_fees( + None, + Some(U256::from(25 * GWEI_TO_WEI)), + Some(U256::from(15 * GWEI_TO_WEI)), + U256::from(15 * GWEI_TO_WEI), + None, + None, + Some(U256::ZERO), + ) + .unwrap(); + assert_eq!(gas_price, U256::from(25 * GWEI_TO_WEI)); + + let CallFees { gas_price, .. } = CallFees::ensure_fees( + None, + Some(U256::from(25 * GWEI_TO_WEI)), + Some(U256::from(5 * GWEI_TO_WEI)), + U256::from(15 * GWEI_TO_WEI), + None, + None, + Some(U256::ZERO), + ) + .unwrap(); + assert_eq!(gas_price, U256::from(20 * GWEI_TO_WEI)); + + let CallFees { gas_price, .. } = CallFees::ensure_fees( + None, + Some(U256::from(30 * GWEI_TO_WEI)), + Some(U256::from(30 * GWEI_TO_WEI)), + U256::from(15 * GWEI_TO_WEI), + None, + None, + Some(U256::ZERO), + ) + .unwrap(); + assert_eq!(gas_price, U256::from(30 * GWEI_TO_WEI)); + + let call_fees = CallFees::ensure_fees( + None, + Some(U256::from(30 * GWEI_TO_WEI)), + Some(U256::from(31 * GWEI_TO_WEI)), + U256::from(15 * GWEI_TO_WEI), + None, + None, + Some(U256::ZERO), + ); + assert!(call_fees.is_err()); + + let call_fees = CallFees::ensure_fees( + None, + Some(U256::from(5 * GWEI_TO_WEI)), + Some(U256::from(GWEI_TO_WEI)), + U256::from(15 * GWEI_TO_WEI), + None, + None, + Some(U256::ZERO), + ); + assert!(call_fees.is_err()); + + let call_fees = CallFees::ensure_fees( + None, + Some(U256::MAX), + Some(U256::MAX), + U256::from(5 * GWEI_TO_WEI), + None, + None, + Some(U256::ZERO), + ); + assert!(call_fees.is_err()); + } +} diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index d3cceab67..050656ed6 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -585,7 +585,10 @@ impl Evm { } }; - let tx_env = prepare_call_env(&block_env, request.clone())?; + let mut tx_env = prepare_call_env(&block_env, request.clone())?; + + // https://github.com/paradigmxyz/reth/issues/6574 + tx_env.nonce = None; let cfg = self .cfg @@ -603,7 +606,9 @@ impl Evm { TracingInspector::new(TracingInspectorConfig::all()), ) { Ok(result) => result.result, - Err(err) => return Err(EthApiError::from(err).into()), + Err(err) => { + return Err(EthApiError::from(err).into()); + } }; Ok(ensure_success(result)?) diff --git a/module-system/module-implementations/sov-evm/src/tests/queries/basic_queries.rs b/module-system/module-implementations/sov-evm/src/tests/queries/basic_queries.rs index dca97c0e3..8b32dd52b 100644 --- a/module-system/module-implementations/sov-evm/src/tests/queries/basic_queries.rs +++ b/module-system/module-implementations/sov-evm/src/tests/queries/basic_queries.rs @@ -5,7 +5,6 @@ use alloy_primitives::FixedBytes; use alloy_rpc_types::request::{TransactionInput, TransactionRequest}; use hex::FromHex; use reth_primitives::{Address, BlockId, BlockNumberOrTag, U64}; -use reth_rpc::eth::error::RpcInvalidTransactionError; use reth_rpc_types::{Block, Rich, TransactionReceipt}; use revm::primitives::{B256, U256}; use serde_json::json; @@ -250,10 +249,7 @@ fn call_test() { &mut working_set, ); - assert_eq!( - nonce_too_low_result, - Err(RpcInvalidTransactionError::NonceTooLow.into()) - ); + assert!(nonce_too_low_result.is_err()); working_set.unset_archival_version(); let result = evm diff --git a/module-system/module-implementations/sov-evm/src/tests/queries/evm_call_tests.rs b/module-system/module-implementations/sov-evm/src/tests/queries/evm_call_tests.rs index 0c2acc450..a69299710 100644 --- a/module-system/module-implementations/sov-evm/src/tests/queries/evm_call_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/queries/evm_call_tests.rs @@ -153,10 +153,7 @@ fn call_contract_with_invalid_nonce() { &mut working_set, ); - assert_eq!( - call_result, - Err(RpcInvalidTransactionError::NonceTooHigh.into()) - ); + assert_eq!(call_result, Ok(Bytes::from_str("0x").unwrap())); let low_nonce = U64::from(2); @@ -176,10 +173,7 @@ fn call_contract_with_invalid_nonce() { &mut working_set, ); - assert_eq!( - call_result, - Err(RpcInvalidTransactionError::NonceTooLow.into()) - ); + assert_eq!(call_result, Ok(Bytes::from_str("0x").unwrap())); } #[test] @@ -268,7 +262,7 @@ fn test_eip1559_fields_call() { ); assert_eq!( high_fee_result, - Err(RpcInvalidTransactionError::GasUintOverflow.into()) + Err(RpcInvalidTransactionError::TipVeryHigh.into()) ); let low_max_fee_result = eth_call_eip1559( @@ -280,8 +274,8 @@ fn test_eip1559_fields_call() { ); assert_eq!( - low_max_fee_result.unwrap().to_string(), - "0x00000000000000000000000000000000000000000000000000000000000001de" + low_max_fee_result, + Err(RpcInvalidTransactionError::FeeCapTooLow.into()) ); let no_max_fee_per_gas = eth_call_eip1559( @@ -293,7 +287,10 @@ fn test_eip1559_fields_call() { ); assert_eq!( no_max_fee_per_gas, - Err(RpcInvalidTransactionError::TipAboveFeeCap.into()) + Ok( + Bytes::from_str("0x00000000000000000000000000000000000000000000000000000000000001de") + .unwrap() + ) ); let no_priority_fee = eth_call_eip1559(