Skip to content

Commit 156d7d9

Browse files
committed
refactor: break out more files
1 parent bc158e1 commit 156d7d9

File tree

3 files changed

+638
-581
lines changed

3 files changed

+638
-581
lines changed

crates/network/src/any/either.rs

+360
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
use crate::{UnknownTxEnvelope, UnknownTypedTransaction};
2+
use alloy_consensus::{Transaction as TransactionTrait, TxEnvelope, TypedTransaction};
3+
use alloy_eips::{
4+
eip2718::{Decodable2718, Encodable2718},
5+
eip7702::SignedAuthorization,
6+
};
7+
use alloy_primitives::{Bytes, B256, U256};
8+
use alloy_rpc_types_eth::{AccessList, TransactionRequest};
9+
use alloy_serde::{OtherFields, WithOtherFields};
10+
11+
/// Unsigned transaction type for a catch-all network.
12+
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
13+
#[serde(untagged)]
14+
#[doc(alias = "AnyTypedTx")]
15+
pub enum AnyTypedTransaction {
16+
/// An Ethereum transaction.
17+
Ethereum(TypedTransaction),
18+
/// A transaction with unknown type.
19+
Unknown(UnknownTypedTransaction),
20+
}
21+
22+
impl AnyTypedTransaction {
23+
/// Select a field by key and attempt to deserialize it.
24+
///
25+
/// This method will return `None` if the key is not present in the fields,
26+
/// or if the transaction is already fully deserialized (i.e. it is an
27+
/// Ethereum [`TxEnvelope`]). Otherwise, it will attempt to deserialize the
28+
/// field and return the result wrapped in a `Some`.
29+
pub fn deser_by_key<T: serde::de::DeserializeOwned>(
30+
&self,
31+
key: &str,
32+
) -> Option<serde_json::Result<T>> {
33+
match self {
34+
Self::Ethereum(_) => None,
35+
Self::Unknown(inner) => inner.deser_by_key(key),
36+
}
37+
}
38+
}
39+
40+
impl From<UnknownTypedTransaction> for AnyTypedTransaction {
41+
fn from(value: UnknownTypedTransaction) -> Self {
42+
Self::Unknown(value)
43+
}
44+
}
45+
46+
impl From<TypedTransaction> for AnyTypedTransaction {
47+
fn from(value: TypedTransaction) -> Self {
48+
Self::Ethereum(value)
49+
}
50+
}
51+
52+
impl From<AnyTxEnvelope> for AnyTypedTransaction {
53+
fn from(value: AnyTxEnvelope) -> Self {
54+
match value {
55+
AnyTxEnvelope::Ethereum(tx) => Self::Ethereum(tx.into()),
56+
AnyTxEnvelope::Unknown(UnknownTxEnvelope { inner, .. }) => inner.into(),
57+
}
58+
}
59+
}
60+
61+
impl From<AnyTypedTransaction> for WithOtherFields<TransactionRequest> {
62+
fn from(value: AnyTypedTransaction) -> Self {
63+
match value {
64+
AnyTypedTransaction::Ethereum(tx) => Self::new(tx.into()),
65+
AnyTypedTransaction::Unknown(UnknownTypedTransaction { ty, mut fields, .. }) => {
66+
fields.insert("type".to_string(), serde_json::Value::Number(ty.0.into()));
67+
Self { inner: Default::default(), other: OtherFields::new(fields) }
68+
}
69+
}
70+
}
71+
}
72+
73+
impl From<AnyTxEnvelope> for WithOtherFields<TransactionRequest> {
74+
fn from(value: AnyTxEnvelope) -> Self {
75+
AnyTypedTransaction::from(value).into()
76+
}
77+
}
78+
79+
impl TransactionTrait for AnyTypedTransaction {
80+
fn chain_id(&self) -> Option<alloy_primitives::ChainId> {
81+
match self {
82+
Self::Ethereum(inner) => inner.chain_id(),
83+
Self::Unknown(inner) => inner.chain_id(),
84+
}
85+
}
86+
87+
fn nonce(&self) -> u64 {
88+
match self {
89+
Self::Ethereum(inner) => inner.nonce(),
90+
Self::Unknown(inner) => inner.nonce(),
91+
}
92+
}
93+
94+
fn gas_limit(&self) -> u64 {
95+
match self {
96+
Self::Ethereum(inner) => inner.gas_limit(),
97+
Self::Unknown(inner) => inner.gas_limit(),
98+
}
99+
}
100+
101+
fn gas_price(&self) -> Option<u128> {
102+
match self {
103+
Self::Ethereum(inner) => inner.gas_price(),
104+
Self::Unknown(inner) => inner.gas_price(),
105+
}
106+
}
107+
108+
fn max_fee_per_gas(&self) -> u128 {
109+
match self {
110+
Self::Ethereum(inner) => inner.max_fee_per_gas(),
111+
Self::Unknown(inner) => inner.max_fee_per_gas(),
112+
}
113+
}
114+
115+
fn max_priority_fee_per_gas(&self) -> Option<u128> {
116+
match self {
117+
Self::Ethereum(inner) => inner.max_priority_fee_per_gas(),
118+
Self::Unknown(inner) => inner.max_priority_fee_per_gas(),
119+
}
120+
}
121+
122+
fn max_fee_per_blob_gas(&self) -> Option<u128> {
123+
match self {
124+
Self::Ethereum(inner) => inner.max_fee_per_blob_gas(),
125+
Self::Unknown(inner) => inner.max_fee_per_blob_gas(),
126+
}
127+
}
128+
129+
fn priority_fee_or_price(&self) -> u128 {
130+
self.max_priority_fee_per_gas().or_else(|| self.gas_price()).unwrap_or_default()
131+
}
132+
133+
fn kind(&self) -> alloy_primitives::TxKind {
134+
match self {
135+
Self::Ethereum(inner) => inner.kind(),
136+
Self::Unknown(inner) => inner.kind(),
137+
}
138+
}
139+
140+
fn value(&self) -> U256 {
141+
match self {
142+
Self::Ethereum(inner) => inner.value(),
143+
Self::Unknown(inner) => inner.value(),
144+
}
145+
}
146+
147+
fn input(&self) -> &Bytes {
148+
match self {
149+
Self::Ethereum(inner) => inner.input(),
150+
Self::Unknown(inner) => inner.input(),
151+
}
152+
}
153+
154+
fn ty(&self) -> u8 {
155+
match self {
156+
Self::Ethereum(inner) => inner.ty(),
157+
Self::Unknown(inner) => inner.ty(),
158+
}
159+
}
160+
161+
fn access_list(&self) -> Option<&AccessList> {
162+
match self {
163+
Self::Ethereum(inner) => inner.access_list(),
164+
Self::Unknown(inner) => inner.access_list(),
165+
}
166+
}
167+
168+
fn blob_versioned_hashes(&self) -> Option<&[B256]> {
169+
match self {
170+
Self::Ethereum(inner) => inner.blob_versioned_hashes(),
171+
Self::Unknown(inner) => inner.blob_versioned_hashes(),
172+
}
173+
}
174+
175+
fn authorization_list(&self) -> Option<&[SignedAuthorization]> {
176+
match self {
177+
Self::Ethereum(inner) => inner.authorization_list(),
178+
Self::Unknown(inner) => inner.authorization_list(),
179+
}
180+
}
181+
}
182+
183+
/// Transaction envelope for a catch-all network.
184+
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
185+
#[serde(untagged)]
186+
#[doc(alias = "AnyTransactionEnvelope")]
187+
pub enum AnyTxEnvelope {
188+
/// An Ethereum transaction.
189+
Ethereum(TxEnvelope),
190+
/// A transaction with unknown type.
191+
Unknown(UnknownTxEnvelope),
192+
}
193+
194+
impl AnyTxEnvelope {
195+
/// Select a field by key and attempt to deserialize it.
196+
///
197+
/// This method will return `None` if the key is not present in the fields,
198+
/// or if the transaction is already fully deserialized (i.e. it is an
199+
/// Ethereum [`TxEnvelope`]). Otherwise, it will attempt to deserialize the
200+
/// field and return the result wrapped in a `Some`.
201+
pub fn deser_by_key<T: serde::de::DeserializeOwned>(
202+
&self,
203+
key: &str,
204+
) -> Option<serde_json::Result<T>> {
205+
match self {
206+
Self::Ethereum(_) => None,
207+
Self::Unknown(inner) => inner.inner.deser_by_key(key),
208+
}
209+
}
210+
}
211+
212+
impl Encodable2718 for AnyTxEnvelope {
213+
fn type_flag(&self) -> Option<u8> {
214+
match self {
215+
Self::Ethereum(t) => t.type_flag(),
216+
Self::Unknown(inner) => Some(inner.ty()),
217+
}
218+
}
219+
220+
fn encode_2718_len(&self) -> usize {
221+
match self {
222+
Self::Ethereum(t) => t.encode_2718_len(),
223+
Self::Unknown(_) => 1,
224+
}
225+
}
226+
227+
#[track_caller]
228+
fn encode_2718(&self, out: &mut dyn alloy_primitives::bytes::BufMut) {
229+
match self {
230+
Self::Ethereum(t) => t.encode_2718(out),
231+
Self::Unknown(inner) => {
232+
panic!(
233+
"Attempted to encode unknown transaction type: {}. This is not a bug in alloy. To encode or decode unknown transaction types, use a custom Transaction type and a custom Network implementation. See https://docs.rs/alloy-network/latest/alloy_network/ for network documentation.",
234+
inner.as_ref().ty
235+
)
236+
}
237+
}
238+
}
239+
240+
fn trie_hash(&self) -> B256 {
241+
match self {
242+
Self::Ethereum(tx) => tx.trie_hash(),
243+
Self::Unknown(inner) => inner.hash,
244+
}
245+
}
246+
}
247+
248+
impl Decodable2718 for AnyTxEnvelope {
249+
fn typed_decode(ty: u8, buf: &mut &[u8]) -> alloy_eips::eip2718::Eip2718Result<Self> {
250+
TxEnvelope::typed_decode(ty, buf).map(Self::Ethereum)
251+
}
252+
253+
fn fallback_decode(buf: &mut &[u8]) -> alloy_eips::eip2718::Eip2718Result<Self> {
254+
TxEnvelope::fallback_decode(buf).map(Self::Ethereum)
255+
}
256+
}
257+
258+
impl TransactionTrait for AnyTxEnvelope {
259+
fn chain_id(&self) -> Option<alloy_primitives::ChainId> {
260+
match self {
261+
Self::Ethereum(inner) => inner.chain_id(),
262+
Self::Unknown(inner) => inner.chain_id(),
263+
}
264+
}
265+
266+
fn nonce(&self) -> u64 {
267+
match self {
268+
Self::Ethereum(inner) => inner.nonce(),
269+
Self::Unknown(inner) => inner.nonce(),
270+
}
271+
}
272+
273+
fn gas_limit(&self) -> u64 {
274+
match self {
275+
Self::Ethereum(inner) => inner.gas_limit(),
276+
Self::Unknown(inner) => inner.gas_limit(),
277+
}
278+
}
279+
280+
fn gas_price(&self) -> Option<u128> {
281+
match self {
282+
Self::Ethereum(inner) => inner.gas_price(),
283+
Self::Unknown(inner) => inner.gas_price(),
284+
}
285+
}
286+
287+
fn max_fee_per_gas(&self) -> u128 {
288+
match self {
289+
Self::Ethereum(inner) => inner.max_fee_per_gas(),
290+
Self::Unknown(inner) => inner.max_fee_per_gas(),
291+
}
292+
}
293+
294+
fn max_priority_fee_per_gas(&self) -> Option<u128> {
295+
match self {
296+
Self::Ethereum(inner) => inner.max_priority_fee_per_gas(),
297+
Self::Unknown(inner) => inner.max_priority_fee_per_gas(),
298+
}
299+
}
300+
301+
fn max_fee_per_blob_gas(&self) -> Option<u128> {
302+
match self {
303+
Self::Ethereum(inner) => inner.max_fee_per_blob_gas(),
304+
Self::Unknown(inner) => inner.max_fee_per_blob_gas(),
305+
}
306+
}
307+
308+
fn priority_fee_or_price(&self) -> u128 {
309+
self.max_priority_fee_per_gas().or_else(|| self.gas_price()).unwrap_or_default()
310+
}
311+
312+
fn kind(&self) -> alloy_primitives::TxKind {
313+
match self {
314+
Self::Ethereum(inner) => inner.kind(),
315+
Self::Unknown(inner) => inner.kind(),
316+
}
317+
}
318+
319+
fn value(&self) -> U256 {
320+
match self {
321+
Self::Ethereum(inner) => inner.value(),
322+
Self::Unknown(inner) => inner.value(),
323+
}
324+
}
325+
326+
fn input(&self) -> &Bytes {
327+
match self {
328+
Self::Ethereum(inner) => inner.input(),
329+
Self::Unknown(inner) => inner.input(),
330+
}
331+
}
332+
333+
fn ty(&self) -> u8 {
334+
match self {
335+
Self::Ethereum(inner) => inner.ty(),
336+
Self::Unknown(inner) => inner.ty(),
337+
}
338+
}
339+
340+
fn access_list(&self) -> Option<&AccessList> {
341+
match self {
342+
Self::Ethereum(inner) => inner.access_list(),
343+
Self::Unknown(inner) => inner.access_list(),
344+
}
345+
}
346+
347+
fn blob_versioned_hashes(&self) -> Option<&[B256]> {
348+
match self {
349+
Self::Ethereum(inner) => inner.blob_versioned_hashes(),
350+
Self::Unknown(inner) => inner.blob_versioned_hashes(),
351+
}
352+
}
353+
354+
fn authorization_list(&self) -> Option<&[SignedAuthorization]> {
355+
match self {
356+
Self::Ethereum(inner) => inner.authorization_list(),
357+
Self::Unknown(inner) => inner.authorization_list(),
358+
}
359+
}
360+
}

0 commit comments

Comments
 (0)