diff --git a/crates/primitives/src/transaction/eip1559.rs b/crates/primitives/src/transaction/eip1559.rs index 31072cd326..c446da2e16 100644 --- a/crates/primitives/src/transaction/eip1559.rs +++ b/crates/primitives/src/transaction/eip1559.rs @@ -162,6 +162,14 @@ impl TxEip1559 { 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 payload_length = self.fields_len() + signature.payload_len(); + // 'transaction type byte length' + 'header length' + 'payload length' + let len = 1 + length_of_length(payload_length) + payload_length; + length_of_length(len) + len + } + /// Get transaction type pub(crate) fn tx_type(&self) -> TxType { TxType::EIP1559 diff --git a/crates/primitives/src/transaction/eip2930.rs b/crates/primitives/src/transaction/eip2930.rs index 074b2fc5b3..3f2a8f8fa6 100644 --- a/crates/primitives/src/transaction/eip2930.rs +++ b/crates/primitives/src/transaction/eip2930.rs @@ -141,6 +141,14 @@ impl TxEip2930 { 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 payload_length = self.fields_len() + signature.payload_len(); + // 'transaction type byte length' + 'header length' + 'payload length' + let len = 1 + length_of_length(payload_length) + payload_length; + length_of_length(len) + len + } + /// Get transaction type pub(crate) fn tx_type(&self) -> TxType { TxType::EIP2930 diff --git a/crates/primitives/src/transaction/eip4844.rs b/crates/primitives/src/transaction/eip4844.rs index 31573d4919..90246031e5 100644 --- a/crates/primitives/src/transaction/eip4844.rs +++ b/crates/primitives/src/transaction/eip4844.rs @@ -214,6 +214,14 @@ impl TxEip4844 { 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 payload_length = self.fields_len() + signature.payload_len(); + // 'transaction type byte length' + 'header length' + 'payload length' + let len = 1 + length_of_length(payload_length) + payload_length; + length_of_length(len) + len + } + /// Get transaction type pub(crate) fn tx_type(&self) -> TxType { TxType::EIP4844 diff --git a/crates/primitives/src/transaction/legacy.rs b/crates/primitives/src/transaction/legacy.rs index ad9d4b141f..fcbb627268 100644 --- a/crates/primitives/src/transaction/legacy.rs +++ b/crates/primitives/src/transaction/legacy.rs @@ -1,6 +1,6 @@ use crate::{Bytes, ChainId, Signature, TransactionKind, TxType}; use reth_codecs::{main_codec, Compact}; -use reth_rlp::{Encodable, Header}; +use reth_rlp::{length_of_length, Encodable, Header}; use std::mem; /// Legacy transaction. @@ -93,6 +93,14 @@ impl TxLegacy { signature.encode_with_eip155_chain_id(out, self.chain_id); } + /// Output the length of the RLP signed transaction encoding. + pub(crate) fn payload_len_with_signature(&self, signature: &Signature) -> usize { + let payload_length = + self.fields_len() + signature.payload_len_with_eip155_chain_id(self.chain_id); + // 'header length' + 'payload length' + length_of_length(payload_length) + payload_length + } + /// Get transaction type pub(crate) fn tx_type(&self) -> TxType { TxType::Legacy diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index e771c5ab23..962bd7e5bc 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -847,19 +847,15 @@ impl TransactionSigned { /// Output the length of the encode_inner(out, true). Note to assume that `with_header` is only /// `true`. pub(crate) fn payload_len_inner(&self) -> usize { - match self.transaction { - Transaction::Legacy(TxLegacy { chain_id, .. }) => { - let payload_length = self.transaction.fields_len() + - self.signature.payload_len_with_eip155_chain_id(chain_id); - // 'header length' + 'payload length' - length_of_length(payload_length) + payload_length + match &self.transaction { + Transaction::Legacy(legacy_tx) => legacy_tx.payload_len_with_signature(&self.signature), + Transaction::Eip2930(access_list_tx) => { + access_list_tx.payload_len_with_signature(&self.signature) } - _ => { - let payload_length = self.transaction.fields_len() + self.signature.payload_len(); - // 'transaction type byte length' + 'header length' + 'payload length' - let len = 1 + length_of_length(payload_length) + payload_length; - length_of_length(len) + len + Transaction::Eip1559(dynamic_fee_tx) => { + dynamic_fee_tx.payload_len_with_signature(&self.signature) } + Transaction::Eip4844(blob_tx) => blob_tx.payload_len_with_signature(&self.signature), } } diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index da4fcf47c1..ebaf5ce144 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -142,38 +142,16 @@ impl Encodable for PooledTransactionsElement { /// Encodes an enveloped post EIP-4844 [PooledTransactionsElement]. fn encode(&self, out: &mut dyn bytes::BufMut) { match self { - Self::Legacy { transaction, signature, hash } => { - // construct signed transaction - let signed_tx = TransactionSigned { - transaction: Transaction::Legacy(transaction.clone()), - signature: *signature, - hash: *hash, - }; - - // encode signed transaction - signed_tx.encode(out); + Self::Legacy { transaction, signature, .. } => { + transaction.encode_with_signature(signature, out) } - Self::Eip2930 { transaction, signature, hash } => { - // construct signed transaction - let signed_tx = TransactionSigned { - transaction: Transaction::Eip2930(transaction.clone()), - signature: *signature, - hash: *hash, - }; - - // encode signed transaction - signed_tx.encode(out); + Self::Eip2930 { transaction, signature, .. } => { + // encodes with header + transaction.encode_with_signature(signature, out, true) } - Self::Eip1559 { transaction, signature, hash } => { - // construct signed transaction - let signed_tx = TransactionSigned { - transaction: Transaction::Eip1559(transaction.clone()), - signature: *signature, - hash: *hash, - }; - - // encode signed transaction - signed_tx.encode(out); + Self::Eip1559 { transaction, signature, .. } => { + // encodes with header + transaction.encode_with_signature(signature, out, true) } Self::BlobTransaction(blob_tx) => { // The inner encoding is used with `with_header` set to true, making the final @@ -186,35 +164,17 @@ impl Encodable for PooledTransactionsElement { fn length(&self) -> usize { match self { - Self::Legacy { transaction, signature, hash } => { - // construct signed transaction - let signed_tx = TransactionSigned { - transaction: Transaction::Legacy(transaction.clone()), - signature: *signature, - hash: *hash, - }; - - signed_tx.length() + Self::Legacy { transaction, signature, .. } => { + // method computes the payload len with a RLP header + transaction.payload_len_with_signature(signature) } - Self::Eip2930 { transaction, signature, hash } => { - // construct signed transaction - let signed_tx = TransactionSigned { - transaction: Transaction::Eip2930(transaction.clone()), - signature: *signature, - hash: *hash, - }; - - signed_tx.length() + Self::Eip2930 { transaction, signature, .. } => { + // method computes the payload len with a RLP header + transaction.payload_len_with_signature(signature) } - Self::Eip1559 { transaction, signature, hash } => { - // construct signed transaction - let signed_tx = TransactionSigned { - transaction: Transaction::Eip1559(transaction.clone()), - signature: *signature, - hash: *hash, - }; - - signed_tx.length() + Self::Eip1559 { transaction, signature, .. } => { + // method computes the payload len with a RLP header + transaction.payload_len_with_signature(signature) } Self::BlobTransaction(blob_tx) => { // the encoding uses a header, so we set `with_header` to true