diff --git a/crates/ethereum/primitives/src/transaction.rs b/crates/ethereum/primitives/src/transaction.rs index 59f738c9ce..c90a537b7c 100644 --- a/crates/ethereum/primitives/src/transaction.rs +++ b/crates/ethereum/primitives/src/transaction.rs @@ -2,7 +2,8 @@ use alloc::vec::Vec; pub use alloy_consensus::{transaction::PooledTransaction, TxType}; use alloy_consensus::{ transaction::RlpEcdsaTx, BlobTransactionSidecar, SignableTransaction, Signed, TxEip1559, - TxEip2930, TxEip4844, TxEip4844WithSidecar, TxEip7702, TxLegacy, Typed2718, TypedTransaction, + TxEip2930, TxEip4844, TxEip4844Variant, TxEip4844WithSidecar, TxEip7702, TxEnvelope, TxLegacy, + Typed2718, TypedTransaction, }; use alloy_eips::{ eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, @@ -39,6 +40,19 @@ macro_rules! delegate { }; } +macro_rules! impl_from_signed { + ($($tx:ident),*) => { + $( + impl From> for TransactionSigned { + fn from(value: Signed<$tx>) -> Self { + let(tx,sig,hash) = value.into_parts(); + Self::new(tx.into(), sig, hash) + } + } + )* + }; +} + /// A raw transaction. /// /// Transaction types were introduced in [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718). @@ -404,6 +418,12 @@ impl TransactionSigned { pub fn transaction_mut(&mut self) -> &mut Transaction { &mut self.transaction } + + /// Splits the transaction into parts. + pub fn into_parts(self) -> (Transaction, Signature, B256) { + let hash = *self.hash.get_or_init(|| self.recalculate_hash()); + (self.transaction, self.signature, hash) + } } impl Typed2718 for TransactionSigned { @@ -482,6 +502,59 @@ impl alloy_consensus::Transaction for TransactionSigned { } } +impl_from_signed!(TxLegacy, TxEip2930, TxEip1559, TxEip7702, TxEip4844, TypedTransaction); + +impl From> for TransactionSigned { + fn from(value: Signed) -> Self { + let (tx, sig, hash) = value.into_parts(); + Self::new(tx, sig, hash) + } +} + +impl From> for TransactionSigned { + fn from(value: Signed) -> Self { + let (tx, sig, hash) = value.into_parts(); + Self::new(tx.tx.into(), sig, hash) + } +} + +impl From for Transaction { + fn from(variant: TxEip4844Variant) -> Self { + match variant { + TxEip4844Variant::TxEip4844(tx) => Self::Eip4844(tx), + TxEip4844Variant::TxEip4844WithSidecar(tx_with_sidecar) => { + Self::Eip4844(tx_with_sidecar.tx) + } + } + } +} + +impl From> for TransactionSigned { + fn from(value: Signed) -> Self { + let (tx, sig, hash) = value.into_parts(); + Self::new(tx.into(), sig, hash) + } +} + +impl From for TransactionSigned { + fn from(value: TxEnvelope) -> Self { + match value { + TxEnvelope::Legacy(tx) => tx.into(), + TxEnvelope::Eip2930(tx) => tx.into(), + TxEnvelope::Eip1559(tx) => tx.into(), + TxEnvelope::Eip4844(tx) => tx.into(), + TxEnvelope::Eip7702(tx) => tx.into(), + } + } +} + +impl From for Signed { + fn from(value: TransactionSigned) -> Self { + let (tx, sig, hash) = value.into_parts(); + Self::new_unchecked(tx, sig, hash) + } +} + #[cfg(any(test, feature = "arbitrary"))] impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { @@ -797,16 +870,6 @@ impl TryFrom for PooledTransaction { } } -impl From> for TransactionSigned -where - T: Into, -{ - fn from(value: Signed) -> Self { - let (tx, signature, hash) = value.into_parts(); - Self { transaction: tx.into(), signature, hash: hash.into() } - } -} - impl From for TransactionSigned { fn from(value: PooledTransaction) -> Self { match value {