From a6bee7286bb2a583b300549782844f138f56e2ca Mon Sep 17 00:00:00 2001 From: "Supernovahs.eth" <91280922+supernovahs@users.noreply.github.com> Date: Fri, 20 Oct 2023 18:55:00 +0530 Subject: [PATCH] feat(rpc):transaction variant for all available transaction formats (#5098) Co-authored-by: Matthias Seitz --- crates/primitives/src/transaction/mod.rs | 2 + crates/primitives/src/transaction/variant.rs | 132 +++++++++++++++++++ crates/rpc/rpc/src/lib.rs | 2 - 3 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 crates/primitives/src/transaction/variant.rs diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 5c9cccaebd..b37ef1360f 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -28,6 +28,7 @@ pub use tx_type::{ TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, LEGACY_TX_TYPE_ID, }; pub use tx_value::TxValue; +pub use variant::TransactionSignedVariant; mod access_list; mod eip1559; @@ -41,6 +42,7 @@ mod signature; mod tx_type; mod tx_value; pub(crate) mod util; +mod variant; // Expected number of transactions where we can expect a speed-up by recovering the senders in // parallel. diff --git a/crates/primitives/src/transaction/variant.rs b/crates/primitives/src/transaction/variant.rs new file mode 100644 index 0000000000..2ab2667222 --- /dev/null +++ b/crates/primitives/src/transaction/variant.rs @@ -0,0 +1,132 @@ +//! Helper enum functions for `Transaction`, `TransactionSigned` and +//! `TransactionSignedEcRecovered` +use crate::{ + Transaction, TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, +}; + +/// Represents various different transaction formats used in reth. +/// +/// All variants are based on a the raw [Transaction] data and can contain additional information +/// extracted (expensive) from that transaction, like the hash and the signer. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum TransactionSignedVariant { + /// A signed transaction without a hash. + SignedNoHash(TransactionSignedNoHash), + /// Contains the plain transaction data its signature and hash. + Signed(TransactionSigned), + /// Contains the plain transaction data its signature and hash and the successfully recovered + /// signer. + SignedEcRecovered(TransactionSignedEcRecovered), +} + +impl TransactionSignedVariant { + /// Returns the raw transaction object + pub fn as_raw(&self) -> &Transaction { + match self { + TransactionSignedVariant::SignedNoHash(tx) => &tx.transaction, + TransactionSignedVariant::Signed(tx) => &tx.transaction, + TransactionSignedVariant::SignedEcRecovered(tx) => &tx.signed_transaction.transaction, + } + } + + /// Returns [TransactionSigned] type + /// else None + pub fn as_signed(&self) -> Option<&TransactionSigned> { + match self { + TransactionSignedVariant::Signed(tx) => Some(tx), + _ => None, + } + } + + /// Returns `TransactionSignedEcRecovered` type + /// else None + pub fn as_signed_ec_recovered(&self) -> Option<&TransactionSignedEcRecovered> { + match self { + TransactionSignedVariant::SignedEcRecovered(tx) => Some(tx), + _ => None, + } + } + + /// Returns true if the transaction is of [TransactionSigned] variant + pub fn is_signed(&self) -> bool { + matches!(self, TransactionSignedVariant::Signed(_)) + } + + /// Returns true if the transaction is of [TransactionSignedNoHash] variant + pub fn is_signed_no_hash(&self) -> bool { + matches!(self, TransactionSignedVariant::SignedNoHash(_)) + } + + /// Returns true if the transaction is of [TransactionSignedEcRecovered] variant + pub fn is_signed_ec_recovered(&self) -> bool { + matches!(self, TransactionSignedVariant::SignedEcRecovered(_)) + } + + /// Consumes the [TransactionSignedVariant] and returns the consumed [Transaction] + pub fn into_raw(self) -> Transaction { + match self { + TransactionSignedVariant::SignedNoHash(tx) => tx.transaction, + TransactionSignedVariant::Signed(tx) => tx.transaction, + TransactionSignedVariant::SignedEcRecovered(tx) => tx.signed_transaction.transaction, + } + } + + /// Consumes the [TransactionSignedVariant] and returns the consumed [TransactionSigned] + pub fn into_signed(self) -> TransactionSigned { + match self { + TransactionSignedVariant::SignedNoHash(tx) => tx.with_hash(), + TransactionSignedVariant::Signed(tx) => tx, + TransactionSignedVariant::SignedEcRecovered(tx) => tx.signed_transaction, + } + } + + /// Consumes the [TransactionSignedVariant] and converts it into a + /// [TransactionSignedEcRecovered] + /// + /// If the variants is not a [TransactionSignedEcRecovered] it will recover the sender. + /// + /// Returns `None` if the transaction's signature is invalid + pub fn into_signed_ec_recovered(self) -> Option { + self.try_into_signed_ec_recovered().ok() + } + + /// Consumes the [TransactionSignedVariant] and converts it into a + /// [TransactionSignedEcRecovered] + /// + /// If the variants is not a [TransactionSignedEcRecovered] it will recover the sender. + /// + /// Returns an error if the transaction's signature is invalid. + pub fn try_into_signed_ec_recovered( + self, + ) -> Result { + match self { + TransactionSignedVariant::SignedEcRecovered(tx) => Ok(tx), + TransactionSignedVariant::Signed(tx) => tx.try_into_ecrecovered(), + TransactionSignedVariant::SignedNoHash(tx) => tx.with_hash().try_into_ecrecovered(), + } + } +} + +impl From for TransactionSignedVariant { + fn from(tx: TransactionSignedNoHash) -> Self { + TransactionSignedVariant::SignedNoHash(tx) + } +} + +impl From for TransactionSignedVariant { + fn from(tx: TransactionSigned) -> Self { + TransactionSignedVariant::Signed(tx) + } +} + +impl From for TransactionSignedVariant { + fn from(tx: TransactionSignedEcRecovered) -> Self { + TransactionSignedVariant::SignedEcRecovered(tx) + } +} + +impl AsRef for TransactionSignedVariant { + fn as_ref(&self) -> &Transaction { + self.as_raw() + } +} diff --git a/crates/rpc/rpc/src/lib.rs b/crates/rpc/rpc/src/lib.rs index 68259610a8..340886dab9 100644 --- a/crates/rpc/rpc/src/lib.rs +++ b/crates/rpc/rpc/src/lib.rs @@ -38,7 +38,6 @@ mod rpc; mod trace; mod txpool; mod web3; - pub use admin::AdminApi; pub use blocking_pool::{BlockingTaskGuard, BlockingTaskPool}; pub use debug::DebugApi; @@ -52,6 +51,5 @@ pub use rpc::RPCApi; pub use trace::TraceApi; pub use txpool::TxPoolApi; pub use web3::Web3Api; - pub mod blocking_pool; pub mod result;