diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index f3654c42ee2c..9646ddf73115 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -419,7 +419,6 @@ mod tests { max_priority_fee_per_gas: 0x28f000fff, max_fee_per_blob_gas: 0x7, gas_limit: 10, - placeholder: Some(()), to: Address::default(), value: U256::from(3_u64), input: Bytes::from(vec![1, 2]), diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index ff6e8d59c378..74b2a0447a92 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -100,7 +100,7 @@ arbitrary = [ "reth-codec", ] secp256k1 = ["dep:secp256k1"] -c-kzg = ["dep:c-kzg", "revm-primitives/c-kzg", "dep:tempfile", "alloy-eips/kzg"] +c-kzg = ["dep:c-kzg", "revm-primitives/c-kzg", "dep:tempfile", "alloy-eips/kzg", "alloy-consensus/kzg"] optimism = [ "reth-chainspec/optimism", "reth-ethereum-forks/optimism", diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index dfaee697a708..ac3d0c551097 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -150,11 +150,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()))?, - placeholder: tx.to.map(drop), + gas_limit: tx.gas, to: tx.to.unwrap_or_default(), 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 54d29a0370df..dfe0083e48be 100644 --- a/crates/primitives/src/transaction/compat.rs +++ b/crates/primitives/src/transaction/compat.rs @@ -64,7 +64,7 @@ impl FillTxEnv for TransactionSigned { tx_env.authorization_list = None; } Transaction::Eip4844(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 = TxKind::Call(tx.to); diff --git a/crates/primitives/src/transaction/eip4844.rs b/crates/primitives/src/transaction/eip4844.rs index a3bad68805ca..e86133d813ef 100644 --- a/crates/primitives/src/transaction/eip4844.rs +++ b/crates/primitives/src/transaction/eip4844.rs @@ -1,324 +1 @@ -use super::access_list::AccessList; -use crate::{ - constants::eip4844::DATA_GAS_PER_BLOB, keccak256, Address, Bytes, ChainId, Signature, 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; - -/// To be used with `Option` to place or replace one bit on the bitflag struct. -pub(crate) type CompactPlaceholder = (); - -#[cfg(feature = "c-kzg")] -use crate::kzg::KzgSettings; - -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; -use serde::{Deserialize, Serialize}; - -/// [EIP-4844 Blob Transaction](https://eips.ethereum.org/EIPS/eip-4844#blob-transaction) -/// -/// A transaction with blob hashes and max blob fee -#[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 TxEip4844 { - /// 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, - - /// TODO(debt): this should be removed if we break the DB. - /// Makes sure that the Compact bitflag struct has one bit after the above field: - /// - pub placeholder: Option, - - /// The 160-bit address of the message call’s recipient. - pub to: Address, - - /// 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, - - /// It contains a vector of fixed size hash(32 bytes) - pub blob_versioned_hashes: Vec, - - /// Max fee per data gas - /// - /// aka BlobFeeCap or blobGasFeeCap - pub max_fee_per_blob_gas: u128, - - /// Unlike other transaction types, where the `input` field has two uses depending on whether - /// or not the `to` field is [`Create`](crate::TxKind::Create) or - /// [`Call`](crate::TxKind::Call), EIP-4844 transactions cannot be - /// [`Create`](crate::TxKind::Create) transactions. - /// - /// This means the `input` field has a single use, as data: An unlimited size byte array - /// specifying the input data of the message call, formally Td. - pub input: Bytes, -} - -impl TxEip4844 { - /// 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 - } - } - } - } - - /// Verifies that the given blob data, commitments, and proofs are all valid for this - /// transaction. - /// - /// Takes as input the [`KzgSettings`], which should contain the parameters derived from the - /// KZG trusted setup. - /// - /// This ensures that the blob transaction payload has the same number of blob data elements, - /// commitments, and proofs. Each blob data element is verified against its commitment and - /// proof. - /// - /// Returns `InvalidProof` if any blob KZG proof in the response - /// fails to verify, or if the versioned hashes in the transaction do not match the actual - /// commitment versioned hashes. - #[cfg(feature = "c-kzg")] - pub fn validate_blob( - &self, - sidecar: &crate::BlobTransactionSidecar, - proof_settings: &KzgSettings, - ) -> Result<(), alloy_eips::eip4844::BlobTransactionValidationError> { - sidecar.validate(&self.blob_versioned_hashes, proof_settings) - } - - /// Returns the total gas for all blobs in this transaction. - #[inline] - pub fn blob_gas(&self) -> u64 { - // NOTE: we don't expect u64::MAX / DATA_GAS_PER_BLOB hashes in a single transaction - self.blob_versioned_hashes.len() as u64 * DATA_GAS_PER_BLOB - } - - /// Decodes the inner [`TxEip4844`] 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` - /// - `max_fee_per_blob_gas` - /// - `blob_versioned_hashes` - pub fn decode_inner(buf: &mut &[u8]) -> alloy_rlp::Result { - let mut tx = 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)?, - placeholder: None, - to: Decodable::decode(buf)?, - value: Decodable::decode(buf)?, - input: Decodable::decode(buf)?, - access_list: Decodable::decode(buf)?, - max_fee_per_blob_gas: Decodable::decode(buf)?, - blob_versioned_hashes: Decodable::decode(buf)?, - }; - - // HACK: our arbitrary implementation sets the placeholder this way for backwards - // compatibility, and should be removed once `placeholder` can be removed - if tx.to != Address::default() { - tx.placeholder = Some(()) - } - - Ok(tx) - } - - /// Outputs the length of the transaction's fields, without a RLP header. - pub(crate) fn fields_len(&self) -> usize { - self.chain_id.length() + - self.nonce.length() + - self.gas_limit.length() + - self.max_fee_per_gas.length() + - self.max_priority_fee_per_gas.length() + - self.to.length() + - self.value.length() + - self.access_list.length() + - self.blob_versioned_hashes.length() + - self.max_fee_per_blob_gas.length() + - self.input.0.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); - self.max_fee_per_blob_gas.encode(out); - self.blob_versioned_hashes.encode(out); - } - - /// Calculates a heuristic for the in-memory size of the [`TxEip4844`] 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 - mem::size_of::
() + // to - mem::size_of::() + // value - self.access_list.size() + // access_list - self.input.len() + // input - self.blob_versioned_hashes.capacity() * mem::size_of::() + // blob hashes size - mem::size_of::() // max_fee_per_data_gas - } - - /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating - /// hash that for eip2718 does not require rlp header - 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. 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 - } - - /// Output the length of the RLP signed transaction encoding, _without_ a RLP 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 - } - - /// Get transaction type - pub(crate) const fn tx_type(&self) -> TxType { - TxType::Eip4844 - } - - /// Encodes the EIP-4844 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, max_fee_per_blob_gas, blob_versioned_hashes)` - /// - /// 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) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use alloy_primitives::{address, bytes}; - - #[test] - fn backwards_compatible_txkind_test() { - // TxEip4844 encoded with TxKind on to field - // holesky tx hash: <0xa3b1668225bf0fbfdd6c19aa6fd071fa4ff5d09a607c67ccd458b97735f745ac> - let tx = bytes!("224348a100426844cb2dc6c0b2d05e003b9aca0079c9109b764609df928d16fc4a91e9081f7e87db09310001019101fb28118ceccaabca22a47e35b9c3f12eb2dcb25e5c543d5b75e6cd841f0a05328d26ef16e8450000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000007b399987d24fc5951f3e94a4cb16e87414bf22290000000000000000000000001670090000000000000000000000000000010001302e31382e302d64657600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000009e640a6aadf4f664cf467b795c31332f44acbe6c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006614c2d1000000000000000000000000000000000000000000000000000000000014012c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000093100000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000093100000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041f06fd78f4dcdf089263524731620941747b9b93fd8f631557e25b23845a78b685bd82f9d36bce2f4cc812b6e5191df52479d349089461ffe76e9f2fa2848a0fe1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410819f04aba17677807c61ae72afdddf7737f26931ecfa8af05b7c669808b36a2587e32c90bb0ed2100266dd7797c80121a109a2b0fe941ca5a580e438988cac81c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); - let (tx, _) = TxEip4844::from_compact(&tx, tx.len()); - assert_eq!(tx.to, address!("79C9109b764609df928d16fC4a91e9081F7e87DB")); - assert_eq!(tx.placeholder, Some(())); - assert_eq!(tx.input, bytes!("ef16e8450000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000007b399987d24fc5951f3e94a4cb16e87414bf22290000000000000000000000001670090000000000000000000000000000010001302e31382e302d64657600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000009e640a6aadf4f664cf467b795c31332f44acbe6c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006614c2d1000000000000000000000000000000000000000000000000000000000014012c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000093100000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000093100000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041f06fd78f4dcdf089263524731620941747b9b93fd8f631557e25b23845a78b685bd82f9d36bce2f4cc812b6e5191df52479d349089461ffe76e9f2fa2848a0fe1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410819f04aba17677807c61ae72afdddf7737f26931ecfa8af05b7c669808b36a2587e32c90bb0ed2100266dd7797c80121a109a2b0fe941ca5a580e438988cac81c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")); - } -} +pub use alloy_consensus::transaction::TxEip4844; diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 6665100ce7da..b580258f3622 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -159,7 +159,12 @@ impl<'a> arbitrary::Arbitrary<'a> for Transaction { tx.gas_limit = (tx.gas_limit as u64).into(); Self::Eip1559(tx) } - TxType::Eip4844 => Self::Eip4844(TxEip4844::arbitrary(u)?), + TxType::Eip4844 => { + let mut tx = TxEip4844::arbitrary(u)?; + tx.gas_limit = (tx.gas_limit as u64).into(); + Self::Eip4844(tx) + } + TxType::Eip7702 => Self::Eip7702(TxEip7702::arbitrary(u)?), #[cfg(feature = "optimism")] TxType::Deposit => Self::Deposit(TxDeposit::arbitrary(u)?), @@ -238,7 +243,7 @@ impl Transaction { Self::Legacy(_) => TxType::Legacy, Self::Eip2930(_) => TxType::Eip2930, Self::Eip1559(_) => TxType::Eip1559, - Self::Eip4844(blob_tx) => blob_tx.tx_type(), + Self::Eip4844(_) => TxType::Eip4844, Self::Eip7702(set_code_tx) => set_code_tx.tx_type(), #[cfg(feature = "optimism")] Self::Deposit(deposit_tx) => deposit_tx.tx_type(), @@ -302,7 +307,7 @@ impl Transaction { match self { Self::Legacy(TxLegacy { gas_limit, .. }) => *gas_limit as u64, Self::Eip1559(TxEip1559 { gas_limit, .. }) => *gas_limit as u64, - Self::Eip4844(TxEip4844 { gas_limit, .. }) | + Self::Eip4844(TxEip4844 { gas_limit, .. }) => *gas_limit as u64, Self::Eip7702(TxEip7702 { gas_limit, .. }) => *gas_limit, Self::Eip2930(TxEip2930 { gas_limit, .. }) => *gas_limit as u64, #[cfg(feature = "optimism")] @@ -536,7 +541,11 @@ impl Transaction { out, with_header, ), - Self::Eip4844(blob_tx) => blob_tx.encode_with_signature(signature, out, with_header), + Self::Eip4844(blob_tx) => blob_tx.encode_with_signature( + &signature.as_signature_with_boolean_parity(), + out, + with_header, + ), Self::Eip7702(set_code_tx) => { set_code_tx.encode_with_signature(signature, out, with_header) } @@ -551,7 +560,7 @@ impl Transaction { Self::Legacy(tx) => tx.gas_limit = gas_limit.into(), Self::Eip2930(tx) => tx.gas_limit = gas_limit.into(), Self::Eip1559(tx) => tx.gas_limit = gas_limit.into(), - Self::Eip4844(tx) => tx.gas_limit = gas_limit, + Self::Eip4844(tx) => tx.gas_limit = gas_limit.into(), Self::Eip7702(tx) => tx.gas_limit = gas_limit, #[cfg(feature = "optimism")] Self::Deposit(tx) => tx.gas_limit = gas_limit, @@ -1219,7 +1228,10 @@ impl TransactionSigned { &self.signature.as_signature_with_boolean_parity(), true, ), - Transaction::Eip4844(blob_tx) => blob_tx.payload_len_with_signature(&self.signature), + Transaction::Eip4844(blob_tx) => blob_tx.encoded_len_with_signature( + &self.signature.as_signature_with_boolean_parity(), + true, + ), Transaction::Eip7702(set_code_tx) => { set_code_tx.payload_len_with_signature(&self.signature) } @@ -1348,7 +1360,7 @@ impl TransactionSigned { let transaction = match tx_type { TxType::Eip2930 => Transaction::Eip2930(TxEip2930::decode_fields(data)?), TxType::Eip1559 => Transaction::Eip1559(TxEip1559::decode_fields(data)?), - TxType::Eip4844 => Transaction::Eip4844(TxEip4844::decode_inner(data)?), + TxType::Eip4844 => Transaction::Eip4844(TxEip4844::decode_fields(data)?), TxType::Eip7702 => Transaction::Eip7702(TxEip7702::decode_inner(data)?), #[cfg(feature = "optimism")] TxType::Deposit => Transaction::Deposit(TxDeposit::decode_inner(data)?), @@ -1427,9 +1439,10 @@ impl TransactionSigned { &self.signature.as_signature_with_boolean_parity(), false, ), - Transaction::Eip4844(blob_tx) => { - blob_tx.payload_len_with_signature_without_header(&self.signature) - } + Transaction::Eip4844(blob_tx) => blob_tx.encoded_len_with_signature( + &self.signature.as_signature_with_boolean_parity(), + false, + ), Transaction::Eip7702(set_code_tx) => { set_code_tx.payload_len_with_signature_without_header(&self.signature) } @@ -1533,11 +1546,6 @@ impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned { transaction.set_chain_id(chain_id % (u64::MAX / 2 - 36)); } - if let Transaction::Eip4844(ref mut tx_eip_4844) = transaction { - tx_eip_4844.placeholder = - if tx_eip_4844.to == Address::default() { None } else { Some(()) }; - } - #[cfg(feature = "optimism")] // Both `Some(0)` and `None` values are encoded as empty string byte. This introduces // ambiguity in roundtrip tests. Patch the mint value of deposit transaction here, so that diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 32e9a9db544a..5e0efcbffee3 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -7,7 +7,7 @@ use crate::{ TransactionSigned, TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxEip4844, TxHash, TxLegacy, B256, EIP4844_TX_TYPE_ID, }; -use alloy_consensus::SignableTransaction; +use alloy_consensus::{SignableTransaction, TxEip4844WithSidecar}; use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header, EMPTY_LIST_CODE}; use bytes::Buf; use derive_more::{AsRef, Deref}; @@ -102,7 +102,11 @@ impl PooledTransactionsElement { // If the transaction is an EIP-4844 transaction... TransactionSigned { transaction: Transaction::Eip4844(tx), signature, hash } => { // Construct a `PooledTransactionsElement::BlobTransaction` with provided sidecar. - Self::BlobTransaction(BlobTransaction { transaction: tx, signature, hash, sidecar }) + Self::BlobTransaction(BlobTransaction { + signature, + hash, + transaction: TxEip4844WithSidecar { tx, sidecar }, + }) } // If the transaction is not EIP-4844, return an error with the original // transaction. @@ -151,7 +155,7 @@ impl PooledTransactionsElement { Self::Eip2930 { transaction, .. } => transaction.nonce, Self::Eip1559 { transaction, .. } => transaction.nonce, Self::Eip7702 { transaction, .. } => transaction.nonce, - Self::BlobTransaction(blob_tx) => blob_tx.transaction.nonce, + Self::BlobTransaction(blob_tx) => blob_tx.transaction.tx.nonce, } } @@ -416,7 +420,7 @@ impl PooledTransactionsElement { /// Returns the [`TxEip4844`] variant if the transaction is an EIP-4844 transaction. pub const fn as_eip4844(&self) -> Option<&TxEip4844> { match self { - Self::BlobTransaction(tx) => Some(&tx.transaction), + Self::BlobTransaction(tx) => Some(&tx.transaction.tx), _ => None, } } @@ -445,7 +449,7 @@ impl PooledTransactionsElement { /// This is also commonly referred to as the "Blob Gas Fee Cap" (`BlobGasFeeCap`). pub const fn max_fee_per_blob_gas(&self) -> Option { match self { - Self::BlobTransaction(tx) => Some(tx.transaction.max_fee_per_blob_gas), + Self::BlobTransaction(tx) => Some(tx.transaction.tx.max_fee_per_blob_gas), _ => None, } } @@ -459,7 +463,7 @@ impl PooledTransactionsElement { Self::Legacy { .. } | Self::Eip2930 { .. } => None, Self::Eip1559 { transaction, .. } => Some(transaction.max_priority_fee_per_gas), Self::Eip7702 { transaction, .. } => Some(transaction.max_priority_fee_per_gas), - Self::BlobTransaction(tx) => Some(tx.transaction.max_priority_fee_per_gas), + Self::BlobTransaction(tx) => Some(tx.transaction.tx.max_priority_fee_per_gas), } } @@ -472,7 +476,7 @@ impl PooledTransactionsElement { Self::Eip2930 { transaction, .. } => transaction.gas_price, Self::Eip1559 { transaction, .. } => transaction.max_fee_per_gas, Self::Eip7702 { transaction, .. } => transaction.max_fee_per_gas, - Self::BlobTransaction(tx) => tx.transaction.max_fee_per_gas, + Self::BlobTransaction(tx) => tx.transaction.tx.max_fee_per_gas, } } } @@ -691,7 +695,7 @@ impl<'a> arbitrary::Arbitrary<'a> for PooledTransactionsElement { match Self::try_from(tx_signed) { Ok(Self::BlobTransaction(mut tx)) => { // Successfully converted to a BlobTransaction, now generate a sidecar. - tx.sidecar = crate::BlobTransactionSidecar::arbitrary(u)?; + tx.transaction.sidecar = crate::BlobTransactionSidecar::arbitrary(u)?; Ok(Self::BlobTransaction(tx)) } Ok(tx) => Ok(tx), // Successfully converted, but not a BlobTransaction. diff --git a/crates/primitives/src/transaction/sidecar.rs b/crates/primitives/src/transaction/sidecar.rs index 2c6f4598a513..b9583a349db3 100644 --- a/crates/primitives/src/transaction/sidecar.rs +++ b/crates/primitives/src/transaction/sidecar.rs @@ -3,7 +3,8 @@ use crate::{ keccak256, Signature, Transaction, TransactionSigned, TxEip4844, TxHash, EIP4844_TX_TYPE_ID, }; -use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header}; +use alloy_consensus::TxEip4844WithSidecar; +use alloy_rlp::{Decodable, Error as RlpError, Header}; use serde::{Deserialize, Serialize}; #[doc(inline)] @@ -24,12 +25,10 @@ use alloc::vec::Vec; pub struct BlobTransaction { /// The transaction hash. pub hash: TxHash, - /// The transaction payload. - pub transaction: TxEip4844, /// The transaction signature. pub signature: Signature, - /// The transaction's blob sidecar. - pub sidecar: BlobTransactionSidecar, + /// The transaction payload with the sidecar. + pub transaction: TxEip4844WithSidecar, } impl BlobTransaction { @@ -43,7 +42,11 @@ impl BlobTransaction { ) -> Result { let TransactionSigned { transaction, signature, hash } = tx; match transaction { - Transaction::Eip4844(transaction) => Ok(Self { hash, transaction, signature, sidecar }), + Transaction::Eip4844(transaction) => Ok(Self { + hash, + transaction: TxEip4844WithSidecar { tx: transaction, sidecar }, + signature, + }), transaction => { let tx = TransactionSigned { transaction, signature, hash }; Err((tx, sidecar)) @@ -59,19 +62,19 @@ impl BlobTransaction { &self, proof_settings: &c_kzg::KzgSettings, ) -> Result<(), BlobTransactionValidationError> { - self.transaction.validate_blob(&self.sidecar, proof_settings) + self.transaction.validate_blob(proof_settings) } /// Splits the [`BlobTransaction`] into its [`TransactionSigned`] and [`BlobTransactionSidecar`] /// components. pub fn into_parts(self) -> (TransactionSigned, BlobTransactionSidecar) { let transaction = TransactionSigned { - transaction: Transaction::Eip4844(self.transaction), + transaction: Transaction::Eip4844(self.transaction.tx), hash: self.hash, signature: self.signature, }; - (transaction, self.sidecar) + (transaction, self.transaction.sidecar) } /// Encodes the [`BlobTransaction`] fields as RLP, with a tx type. If `with_header` is `false`, @@ -111,36 +114,8 @@ impl BlobTransaction { /// Note: this should be used only when implementing other RLP encoding methods, and does not /// represent the full RLP encoding of the blob transaction. pub(crate) fn encode_inner(&self, out: &mut dyn bytes::BufMut) { - // First we construct both required list headers. - // - // The `transaction_payload_body` length is the length of the fields, plus the length of - // its list header. - let tx_header = Header { - list: true, - payload_length: self.transaction.fields_len() + self.signature.payload_len(), - }; - - let tx_length = tx_header.length() + tx_header.payload_length; - - // The payload length is the length of the `tranascation_payload_body` list, plus the - // length of the blobs, commitments, and proofs. - let payload_length = tx_length + self.sidecar.fields_len(); - - // First we use the payload len to construct the first list header - let blob_tx_header = Header { list: true, payload_length }; - - // Encode the blob tx header first - blob_tx_header.encode(out); - - // Encode the inner tx list header, then its fields - tx_header.encode(out); - self.transaction.encode_fields(out); - - // Encode the signature - self.signature.encode(out); - - // Encode the blobs, commitments, and proofs - self.sidecar.encode(out); + self.transaction + .encode_with_signature_fields(&self.signature.as_signature_with_boolean_parity(), out); } /// Outputs the length of the RLP encoding of the blob transaction, including the tx type byte, @@ -181,14 +156,14 @@ impl BlobTransaction { // its list header. let tx_header = Header { list: true, - payload_length: self.transaction.fields_len() + self.signature.payload_len(), + payload_length: self.transaction.tx.fields_len() + self.signature.payload_len(), }; let tx_length = tx_header.length() + tx_header.payload_length; // The payload length is the length of the `tranascation_payload_body` list, plus the // length of the blobs, commitments, and proofs. - let payload_length = tx_length + self.sidecar.fields_len(); + let payload_length = tx_length + self.transaction.sidecar.fields_len(); // We use the calculated payload len to construct the first list header, which encompasses // everything in the tx - the length of the second, inner list header is part of @@ -234,7 +209,7 @@ impl BlobTransaction { let inner_remaining_len = data.len(); // inner transaction - let transaction = TxEip4844::decode_inner(data)?; + let transaction = TxEip4844::decode(data)?; // signature let signature = Signature::decode(data)?; @@ -265,7 +240,11 @@ impl BlobTransaction { // Instead, we use `encode_with_signature`, which RLP encodes the transaction with a // signature for hashing without a header. We then hash the result. let mut buf = Vec::new(); - transaction.encode_with_signature(&signature, &mut buf, false); + transaction.encode_with_signature( + &signature.as_signature_with_boolean_parity(), + &mut buf, + false, + ); let hash = keccak256(&buf); // the outer header is for the entire transaction, so we check the length here @@ -274,7 +253,7 @@ impl BlobTransaction { return Err(RlpError::UnexpectedLength) } - Ok(Self { transaction, hash, signature, sidecar }) + Ok(Self { transaction: TxEip4844WithSidecar { tx: transaction, sidecar }, hash, signature }) } } @@ -311,6 +290,7 @@ mod tests { use super::*; use crate::{hex, kzg::Blob}; use alloy_eips::eip4844::Bytes48; + use alloy_rlp::Encodable; use std::{fs, path::PathBuf, str::FromStr}; #[test] diff --git a/crates/rpc/rpc-types-compat/src/transaction/typed.rs b/crates/rpc/rpc-types-compat/src/transaction/typed.rs index 21e492218a4a..ffed5117e91e 100644 --- a/crates/rpc/rpc-types-compat/src/transaction/typed.rs +++ b/crates/rpc/rpc-types-compat/src/transaction/typed.rs @@ -47,7 +47,6 @@ pub fn to_primitive_transaction( gas_limit: tx.gas_limit.to(), max_fee_per_gas: tx.max_fee_per_gas.to(), max_priority_fee_per_gas: tx.max_priority_fee_per_gas.to(), - placeholder: Some(()), to: tx.to, value: tx.value, access_list: tx.access_list, diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index 9cabc1f6f5fd..4731de20d035 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -87,7 +87,7 @@ where .iter() .filter_map(|(tx, _)| { if let PooledTransactionsElement::BlobTransaction(tx) = tx { - Some(tx.transaction.blob_gas()) + Some(tx.transaction.tx.blob_gas()) } else { None } diff --git a/crates/storage/codecs/src/alloy/transaction/eip4844.rs b/crates/storage/codecs/src/alloy/transaction/eip4844.rs new file mode 100644 index 000000000000..7ac815820dee --- /dev/null +++ b/crates/storage/codecs/src/alloy/transaction/eip4844.rs @@ -0,0 +1,96 @@ +use crate::{Compact, CompactPlaceholder}; +use alloy_consensus::transaction::TxEip4844 as AlloyTxEip4844; +use alloy_eips::eip2930::AccessList; +use alloy_primitives::{Address, Bytes, ChainId, B256, U256}; +use reth_codecs_derive::add_arbitrary_tests; +use serde::{Deserialize, Serialize}; + +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; + +/// [EIP-4844 Blob Transaction](https://eips.ethereum.org/EIPS/eip-4844#blob-transaction) +/// +/// 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::TxEip4844`] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Serialize, Deserialize, Compact)] +#[cfg_attr(test, derive(arbitrary::Arbitrary))] +#[add_arbitrary_tests(compact)] +pub(crate) struct TxEip4844 { + chain_id: ChainId, + nonce: u64, + gas_limit: u64, + max_fee_per_gas: u128, + max_priority_fee_per_gas: u128, + /// TODO(debt): this should be removed if we break the DB. + /// Makes sure that the Compact bitflag struct has one bit after the above field: + /// + placeholder: Option, + to: Address, + value: U256, + access_list: AccessList, + blob_versioned_hashes: Vec, + max_fee_per_blob_gas: u128, + input: Bytes, +} + +impl Compact for AlloyTxEip4844 { + fn to_compact(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + let tx = TxEip4844 { + 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, + placeholder: Some(()), + to: self.to, + value: self.value, + access_list: self.access_list.clone(), + blob_versioned_hashes: self.blob_versioned_hashes.clone(), + max_fee_per_blob_gas: self.max_fee_per_blob_gas, + input: self.input.clone(), + }; + tx.to_compact(buf) + } + + fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) { + let (tx, _) = TxEip4844::from_compact(buf, len); + let alloy_tx = Self { + chain_id: tx.chain_id, + nonce: tx.nonce, + gas_limit: tx.gas_limit as u128, + 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, + blob_versioned_hashes: tx.blob_versioned_hashes, + max_fee_per_blob_gas: tx.max_fee_per_blob_gas, + input: tx.input, + }; + (alloy_tx, buf) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloy_primitives::{address, bytes}; + + #[test] + fn backwards_compatible_txkind_test() { + // TxEip4844 encoded with TxKind on to field + // holesky tx hash: <0xa3b1668225bf0fbfdd6c19aa6fd071fa4ff5d09a607c67ccd458b97735f745ac> + let tx = bytes!("224348a100426844cb2dc6c0b2d05e003b9aca0079c9109b764609df928d16fc4a91e9081f7e87db09310001019101fb28118ceccaabca22a47e35b9c3f12eb2dcb25e5c543d5b75e6cd841f0a05328d26ef16e8450000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000007b399987d24fc5951f3e94a4cb16e87414bf22290000000000000000000000001670090000000000000000000000000000010001302e31382e302d64657600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000009e640a6aadf4f664cf467b795c31332f44acbe6c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006614c2d1000000000000000000000000000000000000000000000000000000000014012c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000093100000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000093100000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041f06fd78f4dcdf089263524731620941747b9b93fd8f631557e25b23845a78b685bd82f9d36bce2f4cc812b6e5191df52479d349089461ffe76e9f2fa2848a0fe1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410819f04aba17677807c61ae72afdddf7737f26931ecfa8af05b7c669808b36a2587e32c90bb0ed2100266dd7797c80121a109a2b0fe941ca5a580e438988cac81c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + let (tx, _) = TxEip4844::from_compact(&tx, tx.len()); + assert_eq!(tx.to, address!("79C9109b764609df928d16fC4a91e9081F7e87DB")); + assert_eq!(tx.placeholder, Some(())); + assert_eq!(tx.input, bytes!("ef16e8450000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000007b399987d24fc5951f3e94a4cb16e87414bf22290000000000000000000000001670090000000000000000000000000000010001302e31382e302d64657600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000009e640a6aadf4f664cf467b795c31332f44acbe6c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006614c2d1000000000000000000000000000000000000000000000000000000000014012c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000093100000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000093100000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041f06fd78f4dcdf089263524731620941747b9b93fd8f631557e25b23845a78b685bd82f9d36bce2f4cc812b6e5191df52479d349089461ffe76e9f2fa2848a0fe1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410819f04aba17677807c61ae72afdddf7737f26931ecfa8af05b7c669808b36a2587e32c90bb0ed2100266dd7797c80121a109a2b0fe941ca5a580e438988cac81c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")); + } +} diff --git a/crates/storage/codecs/src/alloy/transaction/mod.rs b/crates/storage/codecs/src/alloy/transaction/mod.rs index af00e90eafac..65ac7be57e66 100644 --- a/crates/storage/codecs/src/alloy/transaction/mod.rs +++ b/crates/storage/codecs/src/alloy/transaction/mod.rs @@ -1,5 +1,6 @@ mod eip1559; mod eip2930; +mod eip4844; mod legacy; #[cfg(test)] @@ -11,10 +12,11 @@ mod tests { // 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, eip2930::TxEip2930, legacy::TxLegacy}; + use super::{eip1559::TxEip1559, eip2930::TxEip2930, eip4844::TxEip4844, legacy::TxLegacy}; #[test] fn test_ensure_backwards_compatibility() { + assert_eq!(TxEip4844::bitflag_encoded_bytes(), 5); assert_eq!(TxLegacy::bitflag_encoded_bytes(), 3); assert_eq!(TxEip1559::bitflag_encoded_bytes(), 4); assert_eq!(TxEip2930::bitflag_encoded_bytes(), 3); diff --git a/crates/storage/db-api/src/models/mod.rs b/crates/storage/db-api/src/models/mod.rs index 72668354ff2c..07f69402ef5c 100644 --- a/crates/storage/db-api/src/models/mod.rs +++ b/crates/storage/db-api/src/models/mod.rs @@ -301,9 +301,7 @@ add_wrapper_struct!((ClientVersion, CompactClientVersion)); #[cfg(test)] mod tests { use super::*; - use reth_primitives::{ - Account, Header, Receipt, ReceiptWithBloom, SealedHeader, TxEip4844, Withdrawals, - }; + use reth_primitives::{Account, Header, Receipt, ReceiptWithBloom, SealedHeader, Withdrawals}; use reth_prune_types::{PruneCheckpoint, PruneMode, PruneSegment}; use reth_stages_types::{ AccountHashingCheckpoint, CheckpointBlockRange, EntitiesCheckpoint, ExecutionCheckpoint, @@ -342,7 +340,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!(TxEip4844::bitflag_encoded_bytes(), 5); assert_eq!(Withdrawals::bitflag_encoded_bytes(), 0); } @@ -372,7 +369,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!(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 e51acbfcbd52..72636f2f7b3e 100644 --- a/crates/transaction-pool/src/test_utils/gen.rs +++ b/crates/transaction-pool/src/test_utils/gen.rs @@ -178,10 +178,9 @@ impl TransactionBuilder { TxEip4844 { chain_id: self.chain_id, nonce: self.nonce, - gas_limit: self.gas_limit, + gas_limit: self.gas_limit as u128, max_fee_per_gas: self.max_fee_per_gas, max_priority_fee_per_gas: self.max_priority_fee_per_gas, - placeholder: None, to: match self.to { TxKind::Call(to) => to, TxKind::Create => Address::default(), diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index 18597715d3dc..4d030f852fe0 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -186,8 +186,6 @@ pub enum MockTransaction { max_fee_per_blob_gas: u128, /// The gas limit for the transaction. gas_limit: u64, - /// Placeholder for backwards compatibility. - placeholder: Option<()>, /// The transaction's destination. to: Address, /// The value of the transaction. @@ -278,7 +276,6 @@ impl MockTransaction { max_priority_fee_per_gas: MIN_PROTOCOL_BASE_FEE as u128, max_fee_per_blob_gas: DATA_GAS_PER_BLOB as u128, gas_limit: 0, - placeholder: Some(()), to: Address::random(), value: Default::default(), input: Bytes::new(), @@ -856,7 +853,6 @@ impl TryFrom for MockTransaction { gas_limit, max_fee_per_gas, max_priority_fee_per_gas, - placeholder, to, value, input, @@ -871,8 +867,7 @@ impl TryFrom for MockTransaction { max_fee_per_gas, max_priority_fee_per_gas, max_fee_per_blob_gas, - gas_limit, - placeholder, + gas_limit: gas_limit as u64, to, value, input, @@ -989,14 +984,12 @@ impl From for Transaction { input, sidecar, size: _, - placeholder, } => Self::Eip4844(TxEip4844 { chain_id, nonce, - gas_limit, + gas_limit: gas_limit.into(), max_fee_per_gas, max_priority_fee_per_gas, - placeholder, to, value, access_list, @@ -1096,7 +1089,6 @@ impl proptest::arbitrary::Arbitrary for MockTransaction { max_fee_per_blob_gas, access_list, blob_versioned_hashes: _, - placeholder, }) => Self::Eip4844 { chain_id: *chain_id, sender, @@ -1105,8 +1097,7 @@ impl proptest::arbitrary::Arbitrary for MockTransaction { max_fee_per_gas: *max_fee_per_gas, max_priority_fee_per_gas: *max_priority_fee_per_gas, max_fee_per_blob_gas: *max_fee_per_blob_gas, - gas_limit: *gas_limit, - placeholder: *placeholder, + gas_limit: *gas_limit as u64, to: *to, value: *value, input: input.clone(),