reth_primitives_traits/transaction/
signed.rs1use crate::{InMemorySize, MaybeCompact, MaybeSerde, MaybeSerdeBincodeCompat};
4use alloc::fmt;
5use alloy_consensus::{
6 transaction::{Recovered, RlpEcdsaEncodableTx, SignerRecoverable, TxHashRef},
7 EthereumTxEnvelope, SignableTransaction,
8};
9use alloy_eips::eip2718::{Decodable2718, Encodable2718, IsTyped2718};
10use alloy_primitives::{keccak256, Address, Signature, B256};
11use alloy_rlp::{Decodable, Encodable};
12use core::hash::Hash;
13
14pub use alloy_consensus::crypto::RecoveryError;
15
16pub trait FullSignedTx: SignedTransaction + MaybeCompact + MaybeSerdeBincodeCompat {}
18impl<T> FullSignedTx for T where T: SignedTransaction + MaybeCompact + MaybeSerdeBincodeCompat {}
19
20#[auto_impl::auto_impl(&, Arc)]
31pub trait SignedTransaction:
32 Send
33 + Sync
34 + Unpin
35 + Clone
36 + fmt::Debug
37 + PartialEq
38 + Eq
39 + Hash
40 + Encodable
41 + Decodable
42 + Encodable2718
43 + Decodable2718
44 + alloy_consensus::Transaction
45 + MaybeSerde
46 + InMemorySize
47 + SignerRecoverable
48 + TxHashRef
49 + IsTyped2718
50{
51 fn is_broadcastable_in_full(&self) -> bool {
57 !self.is_eip4844()
59 }
60
61 fn try_recover(&self) -> Result<Address, RecoveryError> {
65 self.recover_signer()
66 }
67
68 fn try_recover_unchecked(&self) -> Result<Address, RecoveryError> {
73 self.recover_signer_unchecked()
74 }
75
76 fn recalculate_hash(&self) -> B256 {
79 keccak256(self.encoded_2718())
80 }
81
82 #[auto_impl(keep_default_for(&, Arc))]
84 fn try_clone_into_recovered(&self) -> Result<Recovered<Self>, RecoveryError> {
85 self.recover_signer().map(|signer| Recovered::new_unchecked(self.clone(), signer))
86 }
87
88 #[auto_impl(keep_default_for(&, Arc))]
90 fn try_clone_into_recovered_unchecked(&self) -> Result<Recovered<Self>, RecoveryError> {
91 self.recover_signer_unchecked().map(|signer| Recovered::new_unchecked(self.clone(), signer))
92 }
93
94 #[auto_impl(keep_default_for(&, Arc))]
99 fn try_into_recovered(self) -> Result<Recovered<Self>, Self> {
100 match self.recover_signer() {
101 Ok(signer) => Ok(Recovered::new_unchecked(self, signer)),
102 Err(_) => Err(self),
103 }
104 }
105
106 #[deprecated(note = "Use try_into_recovered_unchecked instead")]
111 #[auto_impl(keep_default_for(&, Arc))]
112 fn into_recovered_unchecked(self) -> Result<Recovered<Self>, RecoveryError> {
113 self.recover_signer_unchecked().map(|signer| Recovered::new_unchecked(self, signer))
114 }
115
116 #[auto_impl(keep_default_for(&, Arc))]
120 fn with_signer(self, signer: Address) -> Recovered<Self> {
121 Recovered::new_unchecked(self, signer)
122 }
123
124 #[auto_impl(keep_default_for(&, Arc))]
128 fn with_signer_ref(&self, signer: Address) -> Recovered<&Self> {
129 Recovered::new_unchecked(self, signer)
130 }
131}
132
133impl<T> SignedTransaction for EthereumTxEnvelope<T>
134where
135 T: RlpEcdsaEncodableTx + SignableTransaction<Signature> + Unpin,
136 Self: Clone + PartialEq + Eq + Decodable + Decodable2718 + MaybeSerde + InMemorySize,
137{
138}
139
140#[cfg(feature = "op")]
141mod op {
142 use super::*;
143 use op_alloy_consensus::{OpPooledTransaction, OpTxEnvelope};
144
145 impl SignedTransaction for OpPooledTransaction {}
146
147 impl SignedTransaction for OpTxEnvelope {}
148}