From 3a49a552c73d1036bd1abba533e339648768a096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <3535019+leruaa@users.noreply.github.com> Date: Sat, 31 Aug 2024 19:36:28 +0200 Subject: [PATCH] feat: migrate to alloy TxEip1559 (#10262) Co-authored-by: Arsenii Kulikov --- crates/net/eth-wire-types/src/transactions.rs | 4 +- crates/primitives/src/alloy_compat.rs | 5 +- crates/primitives/src/transaction/compat.rs | 2 +- crates/primitives/src/transaction/eip1559.rs | 243 +----------------- crates/primitives/src/transaction/mod.rs | 44 ++-- crates/primitives/src/transaction/pooled.rs | 22 +- .../primitives/src/transaction/signature.rs | 6 + crates/storage/codecs/Cargo.toml | 2 +- .../codecs/src/alloy/transaction/eip1559.rs | 67 +++++ .../{transaction.rs => transaction/legacy.rs} | 20 +- .../codecs/src/alloy/transaction/mod.rs | 20 ++ crates/storage/db-api/src/models/mod.rs | 5 +- crates/transaction-pool/src/test_utils/gen.rs | 2 +- .../transaction-pool/src/test_utils/mock.rs | 6 +- 14 files changed, 149 insertions(+), 299 deletions(-) create mode 100644 crates/storage/codecs/src/alloy/transaction/eip1559.rs rename crates/storage/codecs/src/alloy/{transaction.rs => transaction/legacy.rs} (83%) create mode 100644 crates/storage/codecs/src/alloy/transaction/mod.rs diff --git a/crates/net/eth-wire-types/src/transactions.rs b/crates/net/eth-wire-types/src/transactions.rs index 2e3a6015d..8d837f824 100644 --- a/crates/net/eth-wire-types/src/transactions.rs +++ b/crates/net/eth-wire-types/src/transactions.rs @@ -283,7 +283,7 @@ mod tests { nonce: 26u64, max_priority_fee_per_gas: 1500000000, max_fee_per_gas: 1500000013, - gas_limit: 21000u64, + gas_limit: 21000, to: TxKind::Call(hex!("61815774383099e24810ab832a5b2a5425c154d5").into()), value: U256::from(3000000000000000000u64), input: Default::default(), @@ -422,7 +422,7 @@ mod tests { nonce: 26u64, max_priority_fee_per_gas: 1500000000, max_fee_per_gas: 1500000013, - gas_limit: 21000u64, + gas_limit: 21000, to: TxKind::Call(hex!("61815774383099e24810ab832a5b2a5425c154d5").into()), value: U256::from(3000000000000000000u64), input: Default::default(), diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index d63bac7c0..8d0cb853f 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -135,10 +135,7 @@ impl TryFrom> for Transaction { max_fee_per_gas: tx .max_fee_per_gas .ok_or(ConversionError::MissingMaxFeePerGas)?, - gas_limit: tx - .gas - .try_into() - .map_err(|_| ConversionError::Eip2718Error(RlpError::Overflow.into()))?, + gas_limit: tx.gas, to: tx.to.map_or(TxKind::Create, TxKind::Call), value: tx.value, access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?, diff --git a/crates/primitives/src/transaction/compat.rs b/crates/primitives/src/transaction/compat.rs index a58277374..4845283f5 100644 --- a/crates/primitives/src/transaction/compat.rs +++ b/crates/primitives/src/transaction/compat.rs @@ -50,7 +50,7 @@ impl FillTxEnv for TransactionSigned { tx_env.authorization_list = None; } Transaction::Eip1559(tx) => { - tx_env.gas_limit = tx.gas_limit; + tx_env.gas_limit = tx.gas_limit as u64; tx_env.gas_price = U256::from(tx.max_fee_per_gas); tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas)); tx_env.transact_to = tx.to; diff --git a/crates/primitives/src/transaction/eip1559.rs b/crates/primitives/src/transaction/eip1559.rs index f95f84cc4..cbdea1496 100644 --- a/crates/primitives/src/transaction/eip1559.rs +++ b/crates/primitives/src/transaction/eip1559.rs @@ -1,245 +1,4 @@ -use super::access_list::AccessList; -use crate::{keccak256, Bytes, ChainId, Signature, TxKind, TxType, B256, U256}; -use alloy_rlp::{length_of_length, Decodable, Encodable, Header}; -use core::mem; - -#[cfg(any(test, feature = "reth-codec"))] -use reth_codecs::Compact; - -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; -use serde::{Deserialize, Serialize}; - -/// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). -#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Serialize, Deserialize)] -#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[cfg_attr(any(test, feature = "reth-codec"), derive(Compact))] -#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))] -pub struct TxEip1559 { - /// Added as EIP-155: Simple replay attack protection - pub chain_id: ChainId, - - /// A scalar value equal to the number of transactions sent by the sender; formally Tn. - pub nonce: u64, - - /// A scalar value equal to the maximum - /// amount of gas that should be used in executing - /// this transaction. This is paid up-front, before any - /// computation is done and may not be increased - /// later; formally Tg. - pub gas_limit: u64, - - /// A scalar value equal to the maximum - /// amount of gas that should be used in executing - /// this transaction. This is paid up-front, before any - /// computation is done and may not be increased - /// later; formally Tg. - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - /// - /// This is also known as `GasFeeCap` - pub max_fee_per_gas: u128, - - /// Max Priority fee that transaction is paying - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - /// - /// This is also known as `GasTipCap` - pub max_priority_fee_per_gas: u128, - - /// The 160-bit address of the message call’s recipient or, for a contract creation - /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. - pub to: TxKind, - - /// A scalar value equal to the number of Wei to - /// be transferred to the message call’s recipient or, - /// in the case of contract creation, as an endowment - /// to the newly created account; formally Tv. - pub value: U256, - - /// The accessList specifies a list of addresses and storage keys; - /// these addresses and storage keys are added into the `accessed_addresses` - /// and `accessed_storage_keys` global sets (introduced in EIP-2929). - /// A gas cost is charged, though at a discount relative to the cost of - /// accessing outside the list. - pub access_list: AccessList, - - /// Input has two uses depending if the transaction `to` field is [`TxKind::Create`] or - /// [`TxKind::Call`]. - /// - /// Input as init code, or if `to` is [`TxKind::Create`]: An unlimited size byte array - /// specifying the EVM-code for the account initialisation procedure `CREATE` - /// - /// Input as data, or if `to` is [`TxKind::Call`]: An unlimited size byte array specifying the - /// input data of the message call, formally Td. - pub input: Bytes, -} - -impl TxEip1559 { - /// Returns the effective gas price for the given `base_fee`. - pub const fn effective_gas_price(&self, base_fee: Option) -> u128 { - match base_fee { - None => self.max_fee_per_gas, - Some(base_fee) => { - // if the tip is greater than the max priority fee per gas, set it to the max - // priority fee per gas + base fee - let tip = self.max_fee_per_gas.saturating_sub(base_fee as u128); - if tip > self.max_priority_fee_per_gas { - self.max_priority_fee_per_gas + base_fee as u128 - } else { - // otherwise return the max fee per gas - self.max_fee_per_gas - } - } - } - } - - /// Decodes the inner [`TxEip1559`] fields from RLP bytes. - /// - /// NOTE: This assumes a RLP header has already been decoded, and _just_ decodes the following - /// RLP fields in the following order: - /// - /// - `chain_id` - /// - `nonce` - /// - `max_priority_fee_per_gas` - /// - `max_fee_per_gas` - /// - `gas_limit` - /// - `to` - /// - `value` - /// - `data` (`input`) - /// - `access_list` - pub(crate) fn decode_inner(buf: &mut &[u8]) -> alloy_rlp::Result { - Ok(Self { - chain_id: Decodable::decode(buf)?, - nonce: Decodable::decode(buf)?, - max_priority_fee_per_gas: Decodable::decode(buf)?, - max_fee_per_gas: Decodable::decode(buf)?, - gas_limit: Decodable::decode(buf)?, - to: Decodable::decode(buf)?, - value: Decodable::decode(buf)?, - input: Decodable::decode(buf)?, - access_list: Decodable::decode(buf)?, - }) - } - - /// Encodes only the transaction's fields into the desired buffer, without a RLP header. - pub(crate) fn fields_len(&self) -> usize { - self.chain_id.length() + - self.nonce.length() + - self.max_priority_fee_per_gas.length() + - self.max_fee_per_gas.length() + - self.gas_limit.length() + - self.to.length() + - self.value.length() + - self.input.0.length() + - self.access_list.length() - } - - /// Encodes only the transaction's fields into the desired buffer, without a RLP header. - pub(crate) fn encode_fields(&self, out: &mut dyn bytes::BufMut) { - self.chain_id.encode(out); - self.nonce.encode(out); - self.max_priority_fee_per_gas.encode(out); - self.max_fee_per_gas.encode(out); - self.gas_limit.encode(out); - self.to.encode(out); - self.value.encode(out); - self.input.0.encode(out); - self.access_list.encode(out); - } - - /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating - /// hash that for eip2718 does not require rlp header - /// - /// This encodes the transaction as: - /// `rlp(chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit to, value, input, - /// access_list, y_parity, r, s)` - pub(crate) fn encode_with_signature( - &self, - signature: &Signature, - out: &mut dyn bytes::BufMut, - with_header: bool, - ) { - let payload_length = self.fields_len() + signature.payload_len(); - if with_header { - Header { - list: false, - payload_length: 1 + length_of_length(payload_length) + payload_length, - } - .encode(out); - } - out.put_u8(self.tx_type() as u8); - let header = Header { list: true, payload_length }; - header.encode(out); - self.encode_fields(out); - signature.encode(out); - } - - /// Output the length of the RLP signed transaction encoding, _without_ a RLP string header. - pub(crate) fn payload_len_with_signature_without_header(&self, signature: &Signature) -> usize { - let payload_length = self.fields_len() + signature.payload_len(); - // 'transaction type byte length' + 'header length' + 'payload length' - 1 + length_of_length(payload_length) + payload_length - } - - /// Output the length of the RLP signed transaction encoding. This encodes with a RLP header. - pub(crate) fn payload_len_with_signature(&self, signature: &Signature) -> usize { - let len = self.payload_len_with_signature_without_header(signature); - length_of_length(len) + len - } - - /// Get transaction type - pub(crate) const fn tx_type(&self) -> TxType { - TxType::Eip1559 - } - - /// Calculates a heuristic for the in-memory size of the [`TxEip1559`] transaction. - #[inline] - pub fn size(&self) -> usize { - mem::size_of::() + // chain_id - mem::size_of::() + // nonce - mem::size_of::() + // gas_limit - mem::size_of::() + // max_fee_per_gas - mem::size_of::() + // max_priority_fee_per_gas - self.to.size() + // to - mem::size_of::() + // value - self.access_list.size() + // access_list - self.input.len() // input - } - - /// Encodes the EIP-1559 transaction in RLP for signing. - /// - /// This encodes the transaction as: - /// `tx_type || rlp(chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, - /// value, input, access_list)` - /// - /// Note that there is no rlp header before the transaction type byte. - pub(crate) fn encode_for_signing(&self, out: &mut dyn bytes::BufMut) { - out.put_u8(self.tx_type() as u8); - Header { list: true, payload_length: self.fields_len() }.encode(out); - self.encode_fields(out); - } - - /// Outputs the length of the signature RLP encoding for the transaction. - pub(crate) fn payload_len_for_signature(&self) -> usize { - let payload_length = self.fields_len(); - // 'transaction type byte length' + 'header length' + 'payload length' - 1 + length_of_length(payload_length) + payload_length - } - - /// Outputs the signature hash of the transaction by first encoding without a signature, then - /// hashing. - pub(crate) fn signature_hash(&self) -> B256 { - let mut buf = Vec::with_capacity(self.payload_len_for_signature()); - self.encode_for_signing(&mut buf); - keccak256(&buf) - } -} - +pub use alloy_consensus::TxEip1559; #[cfg(test)] mod tests { use super::TxEip1559; diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index a9f80a230..f39973e79 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -153,9 +153,15 @@ impl<'a> arbitrary::Arbitrary<'a> for Transaction { TxType::Deposit => Self::Deposit(TxDeposit::arbitrary(u)?), }; - if let Self::Legacy(tx) = &mut tx { - tx.gas_limit = (tx.gas_limit as u64).into(); - }; + match &mut tx { + Self::Legacy(tx) => { + tx.gas_limit = (tx.gas_limit as u64).into(); + } + Self::Eip1559(tx) => { + tx.gas_limit = (tx.gas_limit as u64).into(); + } + _ => {} + } Ok(tx) } @@ -231,7 +237,7 @@ impl Transaction { match self { Self::Legacy(_) => TxType::Legacy, Self::Eip2930(access_list_tx) => access_list_tx.tx_type(), - Self::Eip1559(dynamic_fee_tx) => dynamic_fee_tx.tx_type(), + Self::Eip1559(_) => TxType::Eip1559, Self::Eip4844(blob_tx) => blob_tx.tx_type(), Self::Eip7702(set_code_tx) => set_code_tx.tx_type(), #[cfg(feature = "optimism")] @@ -294,9 +300,9 @@ impl Transaction { /// Get the gas limit of the transaction. pub const fn gas_limit(&self) -> u64 { match self { - Self::Legacy(TxLegacy { gas_limit, .. }) => *gas_limit as u64, + Self::Legacy(TxLegacy { gas_limit, .. }) | + Self::Eip1559(TxEip1559 { gas_limit, .. }) => *gas_limit as u64, Self::Eip2930(TxEip2930 { gas_limit, .. }) | - Self::Eip1559(TxEip1559 { gas_limit, .. }) | Self::Eip4844(TxEip4844 { gas_limit, .. }) | Self::Eip7702(TxEip7702 { gas_limit, .. }) => *gas_limit, #[cfg(feature = "optimism")] @@ -523,9 +529,11 @@ impl Transaction { Self::Eip2930(access_list_tx) => { access_list_tx.encode_with_signature(signature, out, with_header) } - Self::Eip1559(dynamic_fee_tx) => { - dynamic_fee_tx.encode_with_signature(signature, out, with_header) - } + Self::Eip1559(dynamic_fee_tx) => dynamic_fee_tx.encode_with_signature( + &signature.as_signature_with_boolean_parity(), + out, + with_header, + ), Self::Eip4844(blob_tx) => blob_tx.encode_with_signature(signature, out, with_header), Self::Eip7702(set_code_tx) => { set_code_tx.encode_with_signature(signature, out, with_header) @@ -540,7 +548,7 @@ impl Transaction { match self { Self::Legacy(tx) => tx.gas_limit = gas_limit.into(), Self::Eip2930(tx) => tx.gas_limit = gas_limit, - Self::Eip1559(tx) => tx.gas_limit = gas_limit, + Self::Eip1559(tx) => tx.gas_limit = gas_limit.into(), Self::Eip4844(tx) => tx.gas_limit = gas_limit, Self::Eip7702(tx) => tx.gas_limit = gas_limit, #[cfg(feature = "optimism")] @@ -1204,9 +1212,10 @@ impl TransactionSigned { Transaction::Eip2930(access_list_tx) => { access_list_tx.payload_len_with_signature(&self.signature) } - Transaction::Eip1559(dynamic_fee_tx) => { - dynamic_fee_tx.payload_len_with_signature(&self.signature) - } + Transaction::Eip1559(dynamic_fee_tx) => dynamic_fee_tx.encoded_len_with_signature( + &self.signature.as_signature_with_boolean_parity(), + true, + ), Transaction::Eip4844(blob_tx) => blob_tx.payload_len_with_signature(&self.signature), Transaction::Eip7702(set_code_tx) => { set_code_tx.payload_len_with_signature(&self.signature) @@ -1335,7 +1344,7 @@ impl TransactionSigned { let transaction = match tx_type { TxType::Eip2930 => Transaction::Eip2930(TxEip2930::decode_inner(data)?), - TxType::Eip1559 => Transaction::Eip1559(TxEip1559::decode_inner(data)?), + TxType::Eip1559 => Transaction::Eip1559(TxEip1559::decode_fields(data)?), TxType::Eip4844 => Transaction::Eip4844(TxEip4844::decode_inner(data)?), TxType::Eip7702 => Transaction::Eip7702(TxEip7702::decode_inner(data)?), #[cfg(feature = "optimism")] @@ -1410,9 +1419,10 @@ impl TransactionSigned { Transaction::Eip2930(access_list_tx) => { access_list_tx.payload_len_with_signature_without_header(&self.signature) } - Transaction::Eip1559(dynamic_fee_tx) => { - dynamic_fee_tx.payload_len_with_signature_without_header(&self.signature) - } + Transaction::Eip1559(dynamic_fee_tx) => dynamic_fee_tx.encoded_len_with_signature( + &self.signature.as_signature_with_boolean_parity(), + false, + ), Transaction::Eip4844(blob_tx) => { blob_tx.payload_len_with_signature_without_header(&self.signature) } diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 3f6739bfd..f669d9cdd 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -312,7 +312,10 @@ impl PooledTransactionsElement { } Self::Eip1559 { transaction, signature, .. } => { // method computes the payload len without a RLP header - transaction.payload_len_with_signature_without_header(signature) + transaction.encoded_len_with_signature( + &signature.as_signature_with_boolean_parity(), + false, + ) } Self::Eip7702 { transaction, signature, .. } => { // method computes the payload len without a RLP header @@ -358,9 +361,11 @@ impl PooledTransactionsElement { Self::Eip2930 { transaction, signature, .. } => { transaction.encode_with_signature(signature, out, false) } - Self::Eip1559 { transaction, signature, .. } => { - transaction.encode_with_signature(signature, out, false) - } + Self::Eip1559 { transaction, signature, .. } => transaction.encode_with_signature( + &signature.as_signature_with_boolean_parity(), + out, + false, + ), Self::Eip7702 { transaction, signature, .. } => { transaction.encode_with_signature(signature, out, false) } @@ -494,7 +499,11 @@ impl Encodable for PooledTransactionsElement { } Self::Eip1559 { transaction, signature, .. } => { // encodes with string header - transaction.encode_with_signature(signature, out, true) + transaction.encode_with_signature( + &signature.as_signature_with_boolean_parity(), + out, + true, + ) } Self::Eip7702 { transaction, signature, .. } => { // encodes with string header @@ -523,7 +532,8 @@ impl Encodable for PooledTransactionsElement { } Self::Eip1559 { transaction, signature, .. } => { // method computes the payload len with a RLP header - transaction.payload_len_with_signature(signature) + transaction + .encoded_len_with_signature(&signature.as_signature_with_boolean_parity(), true) } Self::Eip7702 { transaction, signature, .. } => { // method computes the payload len with a RLP header diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index dad5ef522..fe03d8d71 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -188,6 +188,12 @@ impl Signature { SignatureWithParity::new(self.r, self.s, self.legacy_parity(chain_id)) } + /// Returns a signature with a boolean parity flag. This is useful when we want to encode + /// the `v` value as 0 or 1. + pub(crate) const fn as_signature_with_boolean_parity(&self) -> SignatureWithParity { + SignatureWithParity::new(self.r, self.s, Parity::Parity(self.odd_y_parity)) + } + /// Returns the signature for the optimism deposit transactions, which don't include a /// signature. #[cfg(feature = "optimism")] diff --git a/crates/storage/codecs/Cargo.toml b/crates/storage/codecs/Cargo.toml index 13292c680..d1e058000 100644 --- a/crates/storage/codecs/Cargo.toml +++ b/crates/storage/codecs/Cargo.toml @@ -16,7 +16,7 @@ reth-codecs-derive = { path = "./derive", default-features = false } # eth alloy-consensus = { workspace = true, optional = true } -alloy-eips = { workspace = true, optional = true } +alloy-eips = { workspace = true, optional = true, features = ["serde"] } alloy-genesis = { workspace = true, optional = true } alloy-primitives.workspace = true alloy-trie = { workspace = true, optional = true } diff --git a/crates/storage/codecs/src/alloy/transaction/eip1559.rs b/crates/storage/codecs/src/alloy/transaction/eip1559.rs new file mode 100644 index 000000000..a08894925 --- /dev/null +++ b/crates/storage/codecs/src/alloy/transaction/eip1559.rs @@ -0,0 +1,67 @@ +use crate::Compact; +use alloy_consensus::TxEip1559 as AlloyTxEip1559; +use alloy_eips::eip2930::AccessList; +use alloy_primitives::{Bytes, ChainId, TxKind, U256}; +use serde::{Deserialize, Serialize}; + +/// [EIP-1559 Transaction](https://eips.ethereum.org/EIPS/eip-1559) +/// +/// This is a helper type to use derive on it instead of manually managing `bitfield`. +/// +/// By deriving `Compact` here, any future changes or enhancements to the `Compact` derive +/// will automatically apply to this type. +/// +/// Notice: Make sure this struct is 1:1 with [`alloy_consensus::transaction::TxEip1559`] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Compact, Default, Serialize, Deserialize)] +#[cfg_attr(test, derive(arbitrary::Arbitrary))] +#[cfg_attr(test, crate::add_arbitrary_tests(compact))] +pub(crate) struct TxEip1559 { + chain_id: ChainId, + nonce: u64, + gas_limit: u64, + max_fee_per_gas: u128, + max_priority_fee_per_gas: u128, + to: TxKind, + value: U256, + access_list: AccessList, + input: Bytes, +} + +impl Compact for AlloyTxEip1559 { + fn to_compact(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + let tx = TxEip1559 { + chain_id: self.chain_id, + nonce: self.nonce, + gas_limit: self.gas_limit as u64, + max_fee_per_gas: self.max_fee_per_gas, + max_priority_fee_per_gas: self.max_priority_fee_per_gas, + to: self.to, + value: self.value, + access_list: self.access_list.clone(), + input: self.input.clone(), + }; + + tx.to_compact(buf) + } + + fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) { + let (tx, _) = TxEip1559::from_compact(buf, len); + + let alloy_tx = Self { + chain_id: tx.chain_id, + nonce: tx.nonce, + gas_limit: tx.gas_limit.into(), + max_fee_per_gas: tx.max_fee_per_gas, + max_priority_fee_per_gas: tx.max_priority_fee_per_gas, + to: tx.to, + value: tx.value, + access_list: tx.access_list, + input: tx.input, + }; + + (alloy_tx, buf) + } +} diff --git a/crates/storage/codecs/src/alloy/transaction.rs b/crates/storage/codecs/src/alloy/transaction/legacy.rs similarity index 83% rename from crates/storage/codecs/src/alloy/transaction.rs rename to crates/storage/codecs/src/alloy/transaction/legacy.rs index 389fef8ac..641b27bf5 100644 --- a/crates/storage/codecs/src/alloy/transaction.rs +++ b/crates/storage/codecs/src/alloy/transaction/legacy.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, PartialEq, Eq, Default, Compact, Serialize, Deserialize)] #[cfg_attr(test, derive(arbitrary::Arbitrary))] #[cfg_attr(test, crate::add_arbitrary_tests(compact))] -struct TxLegacy { +pub(crate) struct TxLegacy { /// Added as EIP-155: Simple replay attack protection chain_id: Option, /// A scalar value equal to the number of transactions sent by the sender; formally Tn. @@ -67,7 +67,7 @@ impl Compact for AlloyTxLegacy { chain_id: tx.chain_id, nonce: tx.nonce, gas_price: tx.gas_price, - gas_limit: tx.gas_limit as u128, + gas_limit: tx.gas_limit.into(), to: tx.to, value: tx.value, input: tx.input, @@ -76,19 +76,3 @@ impl Compact for AlloyTxLegacy { (alloy_tx, buf) } } - -#[cfg(test)] -mod tests { - use crate::alloy::transaction::TxLegacy; - - // each value in the database has an extra field named flags that encodes metadata about other - // fields in the value, e.g. offset and length. - // - // this check is to ensure we do not inadvertently add too many fields to a struct which would - // expand the flags field and break backwards compatibility - - #[test] - fn test_ensure_backwards_compatibility() { - assert_eq!(TxLegacy::bitflag_encoded_bytes(), 3); - } -} diff --git a/crates/storage/codecs/src/alloy/transaction/mod.rs b/crates/storage/codecs/src/alloy/transaction/mod.rs new file mode 100644 index 000000000..4a343c573 --- /dev/null +++ b/crates/storage/codecs/src/alloy/transaction/mod.rs @@ -0,0 +1,20 @@ +mod eip1559; +mod legacy; + +#[cfg(test)] +mod tests { + + // each value in the database has an extra field named flags that encodes metadata about other + // fields in the value, e.g. offset and length. + // + // this check is to ensure we do not inadvertently add too many fields to a struct which would + // expand the flags field and break backwards compatibility + + use super::{eip1559::TxEip1559, legacy::TxLegacy}; + + #[test] + fn test_ensure_backwards_compatibility() { + assert_eq!(TxLegacy::bitflag_encoded_bytes(), 3); + assert_eq!(TxEip1559::bitflag_encoded_bytes(), 4); + } +} diff --git a/crates/storage/db-api/src/models/mod.rs b/crates/storage/db-api/src/models/mod.rs index ede53d4b9..58a246fa9 100644 --- a/crates/storage/db-api/src/models/mod.rs +++ b/crates/storage/db-api/src/models/mod.rs @@ -302,8 +302,7 @@ add_wrapper_struct!((ClientVersion, CompactClientVersion)); mod tests { use super::*; use reth_primitives::{ - Account, Header, Receipt, ReceiptWithBloom, SealedHeader, TxEip1559, TxEip2930, TxEip4844, - Withdrawals, + Account, Header, Receipt, ReceiptWithBloom, SealedHeader, TxEip2930, TxEip4844, Withdrawals, }; use reth_prune_types::{PruneCheckpoint, PruneMode, PruneSegment}; use reth_stages_types::{ @@ -343,7 +342,6 @@ mod tests { assert_eq!(StoredBlockOmmers::bitflag_encoded_bytes(), 0); assert_eq!(StoredBlockWithdrawals::bitflag_encoded_bytes(), 0); assert_eq!(StorageHashingCheckpoint::bitflag_encoded_bytes(), 1); - assert_eq!(TxEip1559::bitflag_encoded_bytes(), 4); assert_eq!(TxEip2930::bitflag_encoded_bytes(), 3); assert_eq!(TxEip4844::bitflag_encoded_bytes(), 5); assert_eq!(Withdrawals::bitflag_encoded_bytes(), 0); @@ -375,7 +373,6 @@ mod tests { assert_eq!(StoredBlockOmmers::bitflag_encoded_bytes(), 0); assert_eq!(StoredBlockWithdrawals::bitflag_encoded_bytes(), 0); assert_eq!(StorageHashingCheckpoint::bitflag_encoded_bytes(), 1); - assert_eq!(TxEip1559::bitflag_encoded_bytes(), 4); assert_eq!(TxEip2930::bitflag_encoded_bytes(), 3); assert_eq!(TxEip4844::bitflag_encoded_bytes(), 5); assert_eq!(Withdrawals::bitflag_encoded_bytes(), 0); diff --git a/crates/transaction-pool/src/test_utils/gen.rs b/crates/transaction-pool/src/test_utils/gen.rs index c4069382d..e51acbfcb 100644 --- a/crates/transaction-pool/src/test_utils/gen.rs +++ b/crates/transaction-pool/src/test_utils/gen.rs @@ -160,7 +160,7 @@ impl TransactionBuilder { TxEip1559 { chain_id: self.chain_id, nonce: self.nonce, - gas_limit: self.gas_limit, + gas_limit: self.gas_limit.into(), max_fee_per_gas: self.max_fee_per_gas, max_priority_fee_per_gas: self.max_priority_fee_per_gas, to: self.to, diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index 6a0c2f8b5..ed8bc70b7 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -843,7 +843,7 @@ impl TryFrom for MockTransaction { nonce, max_fee_per_gas, max_priority_fee_per_gas, - gas_limit, + gas_limit: gas_limit as u64, to, value, input, @@ -966,7 +966,7 @@ impl From for Transaction { } => Self::Eip1559(TxEip1559 { chain_id, nonce, - gas_limit, + gas_limit: gas_limit.into(), max_fee_per_gas, max_priority_fee_per_gas, to, @@ -1077,7 +1077,7 @@ impl proptest::arbitrary::Arbitrary for MockTransaction { nonce: *nonce, max_fee_per_gas: *max_fee_per_gas, max_priority_fee_per_gas: *max_priority_fee_per_gas, - gas_limit: *gas_limit, + gas_limit: *gas_limit as u64, to: *to, value: *value, input: input.clone(),