alloy_zksync/network/
receipt_envelope.rs

1use alloy::consensus::{TxReceipt, TxType};
2use alloy::network::AnyReceiptEnvelope;
3use alloy::network::eip2718::{Decodable2718, Eip2718Error, Encodable2718, Typed2718};
4use alloy::primitives::Log;
5use core::convert::TryInto;
6use core::fmt;
7use serde::{Deserialize, Serialize};
8
9/// Receipt envelope is a wrapper around the receipt data.
10#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(untagged)]
12pub enum ReceiptEnvelope<T = Log> {
13    /// Receipt for an Ethereum-native transaction.
14    Native(alloy::consensus::ReceiptEnvelope<T>),
15    /// Receipt for ZKsync-native EIP712 transaction.
16    ///
17    /// For now AnyReceiptEnvelope is used due to the fact that
18    /// alloy::consensus::ReceiptEnvelope cannot be decoded because of different transaction type,
19    /// but for now we don't need any custom functionality for EIP712 receipt
20    Eip712(AnyReceiptEnvelope<T>),
21}
22
23impl<T> TxReceipt for ReceiptEnvelope<T>
24where
25    T: Clone + fmt::Debug + PartialEq + Eq + Send + Sync,
26{
27    type Log = T;
28
29    fn status_or_post_state(&self) -> alloy::consensus::Eip658Value {
30        match self {
31            ReceiptEnvelope::Native(re) => re.status_or_post_state(),
32            ReceiptEnvelope::Eip712(re) => re.status_or_post_state(),
33        }
34    }
35
36    fn status(&self) -> bool {
37        match self {
38            ReceiptEnvelope::Native(re) => re.status(),
39            ReceiptEnvelope::Eip712(re) => re.status(),
40        }
41    }
42
43    fn bloom(&self) -> alloy::primitives::Bloom {
44        match self {
45            ReceiptEnvelope::Native(re) => re.bloom(),
46            ReceiptEnvelope::Eip712(re) => re.bloom(),
47        }
48    }
49
50    fn cumulative_gas_used(&self) -> u64 {
51        match self {
52            ReceiptEnvelope::Native(re) => re.cumulative_gas_used(),
53            ReceiptEnvelope::Eip712(re) => re.cumulative_gas_used(),
54        }
55    }
56
57    fn logs(&self) -> &[T] {
58        match self {
59            ReceiptEnvelope::Native(re) => re.logs(),
60            ReceiptEnvelope::Eip712(re) => re.logs(),
61        }
62    }
63}
64
65impl Typed2718 for ReceiptEnvelope {
66    fn ty(&self) -> u8 {
67        match self {
68            ReceiptEnvelope::Native(re) => re.ty(),
69            ReceiptEnvelope::Eip712(re) => re.ty(),
70        }
71    }
72}
73
74impl Encodable2718 for ReceiptEnvelope {
75    fn type_flag(&self) -> Option<u8> {
76        match self {
77            ReceiptEnvelope::Native(re) => re.type_flag(),
78            ReceiptEnvelope::Eip712(re) => re.type_flag(),
79        }
80    }
81
82    fn encode_2718_len(&self) -> usize {
83        match self {
84            ReceiptEnvelope::Native(re) => re.encode_2718_len(),
85            ReceiptEnvelope::Eip712(re) => re.encode_2718_len(),
86        }
87    }
88
89    fn encode_2718(&self, out: &mut dyn alloy::primitives::bytes::BufMut) {
90        match self {
91            ReceiptEnvelope::Native(re) => re.encode_2718(out),
92            ReceiptEnvelope::Eip712(re) => re.encode_2718(out),
93        }
94    }
95}
96
97impl Decodable2718 for ReceiptEnvelope {
98    fn typed_decode(ty: u8, buf: &mut &[u8]) -> alloy::network::eip2718::Eip2718Result<Self> {
99        let tx_type_result: Result<TxType, Eip2718Error> = ty.try_into();
100        match tx_type_result {
101            Ok(_) => alloy::consensus::ReceiptEnvelope::typed_decode(ty, buf)
102                .map(ReceiptEnvelope::Native),
103            Err(_) => AnyReceiptEnvelope::typed_decode(ty, buf).map(ReceiptEnvelope::Eip712),
104        }
105    }
106
107    fn fallback_decode(buf: &mut &[u8]) -> alloy::network::eip2718::Eip2718Result<Self> {
108        // there is no type available to assume what kind of envelope it is
109        // try to decode as a native envelope then as Eip712
110        match alloy::consensus::ReceiptEnvelope::fallback_decode(buf) {
111            Ok(envelope) => Ok(ReceiptEnvelope::Native(envelope)),
112            Err(_) => Ok(ReceiptEnvelope::Eip712(
113                AnyReceiptEnvelope::fallback_decode(buf).unwrap(),
114            )),
115        }
116    }
117}