diff --git a/crates/common/types/transaction.rs b/crates/common/types/transaction.rs index a8df1275fb1..6758d5a4581 100644 --- a/crates/common/types/transaction.rs +++ b/crates/common/types/transaction.rs @@ -163,7 +163,8 @@ impl RLPDecode for WrappedEIP4844Transaction { #[derive(Clone, Debug, PartialEq, Eq, Default, RSerialize, RDeserialize, Archive)] pub struct LegacyTransaction { pub nonce: u64, - pub gas_price: u64, + #[rkyv(with=crate::rkyv_utils::U256Wrapper)] + pub gas_price: U256, pub gas: u64, /// The recipient of the transaction. /// Create transactions contain a [`null`](RLP_NULL) value in this field. @@ -186,7 +187,8 @@ pub struct LegacyTransaction { pub struct EIP2930Transaction { pub chain_id: u64, pub nonce: u64, - pub gas_price: u64, + #[rkyv(with=crate::rkyv_utils::U256Wrapper)] + pub gas_price: U256, pub gas_limit: u64, pub to: TxKind, #[rkyv(with=crate::rkyv_utils::U256Wrapper)] @@ -351,20 +353,19 @@ impl Transaction { } } - fn calc_effective_gas_price(&self, base_fee_per_gas: Option) -> Option { - if self.max_fee_per_gas()? < base_fee_per_gas? { + fn calc_effective_gas_price(&self, base_fee_per_gas: Option) -> Option { + let base_fee = base_fee_per_gas?; + let max_fee = self.max_fee_per_gas()?; + if max_fee < base_fee { // This is invalid, can't calculate return None; } - let priority_fee_per_gas = min( - self.max_priority_fee()?, - self.max_fee_per_gas()?.saturating_sub(base_fee_per_gas?), - ); - Some(priority_fee_per_gas + base_fee_per_gas?) + let priority_fee_per_gas = min(self.max_priority_fee()?, max_fee.saturating_sub(base_fee)); + Some(U256::from(priority_fee_per_gas) + U256::from(base_fee)) } - pub fn effective_gas_price(&self, base_fee_per_gas: Option) -> Option { + pub fn effective_gas_price(&self, base_fee_per_gas: Option) -> Option { match self.tx_type() { TxType::Legacy => Some(self.gas_price()), TxType::EIP2930 => Some(self.gas_price()), @@ -379,14 +380,14 @@ impl Transaction { let price = match self.tx_type() { TxType::Legacy => self.gas_price(), TxType::EIP2930 => self.gas_price(), - TxType::EIP1559 => self.max_fee_per_gas()?, - TxType::EIP4844 => self.max_fee_per_gas()?, - TxType::EIP7702 => self.max_fee_per_gas()?, + TxType::EIP1559 => U256::from(self.max_fee_per_gas()?), + TxType::EIP4844 => U256::from(self.max_fee_per_gas()?), + TxType::EIP7702 => U256::from(self.max_fee_per_gas()?), TxType::Privileged => self.gas_price(), }; Some(U256::saturating_add( - U256::saturating_mul(price.into(), self.gas_limit().into()), + U256::saturating_mul(price, self.gas_limit().into()), self.value(), )) } @@ -1067,14 +1068,15 @@ impl Transaction { } } - pub fn gas_price(&self) -> u64 { + //TODO: It's not very correct to return gas price for legacy and eip-2930 txs but return the max fee per gas for the others, make necessary changes for it to be technically correct. + pub fn gas_price(&self) -> U256 { match self { Transaction::LegacyTransaction(tx) => tx.gas_price, Transaction::EIP2930Transaction(tx) => tx.gas_price, - Transaction::EIP1559Transaction(tx) => tx.max_fee_per_gas, - Transaction::EIP7702Transaction(tx) => tx.max_fee_per_gas, - Transaction::EIP4844Transaction(tx) => tx.max_fee_per_gas, - Transaction::PrivilegedL2Transaction(tx) => tx.max_fee_per_gas, + Transaction::EIP1559Transaction(tx) => U256::from(tx.max_fee_per_gas), + Transaction::EIP7702Transaction(tx) => U256::from(tx.max_fee_per_gas), + Transaction::EIP4844Transaction(tx) => U256::from(tx.max_fee_per_gas), + Transaction::PrivilegedL2Transaction(tx) => U256::from(tx.max_fee_per_gas), } } @@ -1236,11 +1238,11 @@ impl Transaction { } pub fn gas_tip_cap(&self) -> u64 { - self.max_priority_fee().unwrap_or(self.gas_price()) + self.max_priority_fee().unwrap_or(self.gas_price().as_u64()) } pub fn gas_fee_cap(&self) -> u64 { - self.max_fee_per_gas().unwrap_or(self.gas_price()) + self.max_fee_per_gas().unwrap_or(self.gas_price().as_u64()) } pub fn effective_gas_tip(&self, base_fee: Option) -> Option { @@ -1941,7 +1943,7 @@ mod serde_impl { Ok(LegacyTransaction { nonce: deserialize_field::(&mut map, "nonce")?.as_u64(), - gas_price: deserialize_field::(&mut map, "gasPrice")?.as_u64(), + gas_price: deserialize_field::(&mut map, "gasPrice")?, gas: deserialize_field::(&mut map, "gas")?.as_u64(), to: deserialize_field::(&mut map, "to")?, value: deserialize_field::(&mut map, "value")?, @@ -1964,7 +1966,7 @@ mod serde_impl { Ok(EIP2930Transaction { chain_id: deserialize_field::(&mut map, "chainId")?.as_u64(), nonce: deserialize_field::(&mut map, "nonce")?.as_u64(), - gas_price: deserialize_field::(&mut map, "gasPrice")?.as_u64(), + gas_price: deserialize_field::(&mut map, "gasPrice")?, gas_limit: deserialize_field::(&mut map, "gas")?.as_u64(), to: deserialize_field::(&mut map, "to")?, value: deserialize_field::(&mut map, "value")?, @@ -2452,7 +2454,7 @@ mod serde_impl { from: Address::default(), gas: Some(value.gas), value: value.value, - gas_price: value.gas_price, + gas_price: value.gas_price.as_u64(), max_priority_fee_per_gas: None, max_fee_per_gas: None, max_fee_per_blob_gas: None, @@ -2475,7 +2477,7 @@ mod serde_impl { from: Address::default(), gas: Some(value.gas_limit), value: value.value, - gas_price: value.gas_price, + gas_price: value.gas_price.as_u64(), max_priority_fee_per_gas: None, max_fee_per_gas: None, max_fee_per_blob_gas: None, @@ -2626,7 +2628,7 @@ mod tests { let mut body = BlockBody::empty(); let tx = LegacyTransaction { nonce: 0, - gas_price: 0x0a, + gas_price: U256::from(0x0a), gas: 0x05f5e100, to: TxKind::Call(hex!("1000000000000000000000000000000000000000").into()), value: 0.into(), @@ -2653,7 +2655,7 @@ mod tests { let tx_eip2930 = EIP2930Transaction { chain_id: 3503995874084926u64, nonce: 7, - gas_price: 0x2dbf1f9a, + gas_price: U256::from(0x2dbf1f9a_u64), gas_limit: 0x186A0, to: TxKind::Call(hex!("7dcd17433742f4c0ca53122ab541d0ba67fc27df").into()), value: 2.into(), @@ -2707,7 +2709,7 @@ mod tests { let tx = LegacyTransaction::decode(&encoded_tx_bytes).unwrap(); let expected_tx = LegacyTransaction { nonce: 0, - gas_price: 1001000000, + gas_price: U256::from(1001000000u64), gas: 63000, to: TxKind::Call(Address::from_slice( &hex::decode("6177843db3138ae69679A54b95cf345ED759450d").unwrap(), @@ -3065,7 +3067,7 @@ mod tests { fn test_legacy_transaction_into_generic() { let legacy_tx = LegacyTransaction { nonce: 1, - gas_price: 20_000_000_000, + gas_price: U256::from(20_000_000_000u64), gas: 21000, to: TxKind::Call( Address::from_str("0x742d35Cc6634C0532925a3b844Bc454e4438f44e").unwrap(), @@ -3104,7 +3106,7 @@ mod tests { let eip2930_tx = EIP2930Transaction { chain_id: 1, nonce: 1, - gas_price: 20_000_000_000, + gas_price: U256::from(20_000_000_000u64), gas_limit: 21000, to: TxKind::Call( Address::from_str("0x742d35Cc6634C0532925a3b844Bc454e4438f44e").unwrap(), diff --git a/crates/networking/rpc/eth/mod.rs b/crates/networking/rpc/eth/mod.rs index 96c778a143a..8151cc4e1f2 100644 --- a/crates/networking/rpc/eth/mod.rs +++ b/crates/networking/rpc/eth/mod.rs @@ -110,7 +110,7 @@ pub mod test_utils { fn legacy_tx_for_test(nonce: u64) -> Transaction { Transaction::LegacyTransaction(LegacyTransaction { nonce, - gas_price: nonce * BASE_PRICE_IN_WEI, + gas_price: U256::from(nonce) * U256::from(BASE_PRICE_IN_WEI), gas: 10000, to: TxKind::Create, value: 100.into(), diff --git a/crates/networking/rpc/types/receipt.rs b/crates/networking/rpc/types/receipt.rs index 9f752dfcb51..bdf4f2ddc45 100644 --- a/crates/networking/rpc/types/receipt.rs +++ b/crates/networking/rpc/types/receipt.rs @@ -177,12 +177,12 @@ impl RpcReceiptTxInfo { let nonce = transaction.nonce(); let from = transaction.sender()?; let transaction_hash = transaction.hash(); - let effective_gas_price = - transaction - .effective_gas_price(base_fee_per_gas) - .ok_or(RpcErr::Internal( - "Could not get effective gas price from tx".into(), - ))?; + let effective_gas_price = transaction + .effective_gas_price(base_fee_per_gas) + .ok_or(RpcErr::Internal( + "Could not get effective gas price from tx".into(), + ))? + .as_u64(); let transaction_index = index; let (blob_gas_price, blob_gas_used) = match &transaction { Transaction::EIP4844Transaction(tx) => ( diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index 926469a8425..af2a3df1c19 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -90,8 +90,7 @@ impl LEVM { .effective_gas_price(block_header.base_fee_per_gas) .ok_or(VMError::TxValidation( TxValidationError::InsufficientMaxFeePerGas, - ))? - .into(); + ))?; let config = EVMConfig::new_from_chain_config(&chain_config, block_header); let env = Environment { diff --git a/crates/vm/levm/runner/src/input.rs b/crates/vm/levm/runner/src/input.rs index 4820f744c4b..35f53ef404e 100644 --- a/crates/vm/levm/runner/src/input.rs +++ b/crates/vm/levm/runner/src/input.rs @@ -93,7 +93,7 @@ impl From for ethrex_common::types::LegacyTransaction { fn from(tx: InputTransaction) -> Self { ethrex_common::types::LegacyTransaction { nonce: 0, - gas_price: tx.gas_price.try_into().unwrap(), + gas_price: tx.gas_price, gas: tx.gas_limit, to: match tx.to { Some(address) => ethrex_common::types::TxKind::Call(address), diff --git a/tooling/ef_tests/blockchain/tests/all.rs b/tooling/ef_tests/blockchain/tests/all.rs index 0e55dfeeab5..64c1e065435 100644 --- a/tooling/ef_tests/blockchain/tests/all.rs +++ b/tooling/ef_tests/blockchain/tests/all.rs @@ -14,8 +14,6 @@ const SKIPPED_BASE: &[&str] = &[ "static_Call50000_sha256", "CALLBlake2f_MaxRounds", "loopMul", - // Gas price higher than u64::MAX; impractical scenario. Fix is on its way on https://github.com/lambdaclass/ethrex/pull/4823 - "HighGasPriceParis", // Skip because it tries to deserialize number > U256::MAX "ValueOverflowParis", // Skip because it's a "Create" Blob Transaction, which doesn't actually exist. It never reaches the EVM because we can't even parse it as an actual Transaction. diff --git a/tooling/ef_tests/blockchain/types.rs b/tooling/ef_tests/blockchain/types.rs index f12ecaa4d7b..c9ff6749437 100644 --- a/tooling/ef_tests/blockchain/types.rs +++ b/tooling/ef_tests/blockchain/types.rs @@ -514,7 +514,7 @@ impl From for LegacyTransaction { fn from(val: Transaction) -> Self { LegacyTransaction { nonce: val.nonce.as_u64(), - gas_price: val.gas_price.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option + gas_price: val.gas_price.unwrap_or_default(), // TODO: Consider converting this into Option gas: val.gas_limit.as_u64(), // to: match val.to { // zero if zero == H160::zero() => TxKind::Create, @@ -536,7 +536,7 @@ impl From for EIP2930Transaction { EIP2930Transaction { chain_id: val.chain_id.map(|id: U256| id.as_u64()).unwrap_or(1), nonce: val.nonce.as_u64(), - gas_price: val.gas_price.unwrap_or_default().as_u64(), + gas_price: val.gas_price.unwrap_or_default(), gas_limit: val.gas_limit.as_u64(), // to: match val.to { // zero if zero == H160::zero() => TxKind::Create, diff --git a/tooling/ef_tests/state_v2/src/modules/runner.rs b/tooling/ef_tests/state_v2/src/modules/runner.rs index 73fc0ec1671..db907c4f3f6 100644 --- a/tooling/ef_tests/state_v2/src/modules/runner.rs +++ b/tooling/ef_tests/state_v2/src/modules/runner.rs @@ -221,7 +221,7 @@ pub async fn get_tx_from_test_case(test_case: &TestCase) -> Result Result Transaction { LibmdbxTransaction::LegacyTransaction(tx) => { Transaction::LegacyTransaction(LegacyTransaction { nonce: tx.nonce, - gas_price: tx.gas_price, + gas_price: tx.gas_price.into(), gas: tx.gas, to: match tx.to { LibmdbxTxKind::Create => TxKind::Create, @@ -100,7 +100,7 @@ pub fn migrate_transaction(tx: LibmdbxTransaction) -> Transaction { Transaction::EIP2930Transaction(EIP2930Transaction { chain_id: tx.chain_id, nonce: tx.nonce, - gas_price: tx.gas_price, + gas_price: tx.gas_price.into(), gas_limit: tx.gas_limit, to: match tx.to { LibmdbxTxKind::Create => TxKind::Create,