alloy_consensus_any/receipt/
envelope.rs1use alloc::vec::Vec;
2use alloy_consensus::{Eip658Value, Receipt, ReceiptWithBloom, TxReceipt};
3use alloy_eips::{
4 eip2718::{Decodable2718, Eip2718Result, Encodable2718},
5 Typed2718,
6};
7use alloy_primitives::{bytes::BufMut, Bloom, Log};
8use alloy_rlp::{Decodable, Encodable};
9use core::fmt;
10
11#[derive(Clone, Debug, PartialEq, Eq)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23#[doc(alias = "AnyTransactionReceiptEnvelope", alias = "AnyTxReceiptEnvelope")]
24pub struct AnyReceiptEnvelope<T = Log> {
25 #[cfg_attr(feature = "serde", serde(flatten))]
27 pub inner: ReceiptWithBloom<Receipt<T>>,
28 #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
30 pub r#type: u8,
31}
32
33impl<T> AnyReceiptEnvelope<T> {
34 pub const fn is_legacy(&self) -> bool {
36 self.r#type == 0
37 }
38}
39
40impl<T: Encodable> AnyReceiptEnvelope<T> {
41 pub fn rlp_payload_length(&self) -> usize {
43 let length = self.inner.length();
44 if self.is_legacy() {
45 length
46 } else {
47 length + 1
48 }
49 }
50}
51
52impl<T> AnyReceiptEnvelope<T> {
53 pub const fn is_success(&self) -> bool {
62 self.status()
63 }
64
65 pub const fn status(&self) -> bool {
74 self.inner.receipt.status.coerce_status()
75 }
76
77 pub const fn bloom(&self) -> Bloom {
79 self.inner.logs_bloom
80 }
81
82 pub const fn bloom_ref(&self) -> &Bloom {
84 &self.inner.logs_bloom
85 }
86
87 pub const fn cumulative_gas_used(&self) -> u64 {
89 self.inner.receipt.cumulative_gas_used
90 }
91
92 pub fn logs(&self) -> &[T] {
94 &self.inner.receipt.logs
95 }
96}
97
98impl<T> TxReceipt for AnyReceiptEnvelope<T>
99where
100 T: Clone + fmt::Debug + PartialEq + Eq + Send + Sync,
101{
102 type Log = T;
103
104 fn status_or_post_state(&self) -> Eip658Value {
105 self.inner.receipt.status
106 }
107
108 fn status(&self) -> bool {
109 self.status()
110 }
111
112 fn bloom(&self) -> Bloom {
113 self.bloom()
114 }
115
116 fn cumulative_gas_used(&self) -> u64 {
117 self.cumulative_gas_used()
118 }
119
120 fn logs(&self) -> &[T] {
121 Self::logs(self)
122 }
123
124 fn into_logs(self) -> Vec<Self::Log>
125 where
126 Self::Log: Clone,
127 {
128 self.inner.receipt.logs
129 }
130}
131
132impl Typed2718 for AnyReceiptEnvelope {
133 fn ty(&self) -> u8 {
134 self.r#type
135 }
136}
137
138impl Encodable2718 for AnyReceiptEnvelope {
139 fn encode_2718_len(&self) -> usize {
140 self.inner.length() + !self.is_legacy() as usize
141 }
142
143 fn encode_2718(&self, out: &mut dyn BufMut) {
144 match self.type_flag() {
145 None => {}
146 Some(ty) => out.put_u8(ty),
147 }
148 self.inner.encode(out);
149 }
150}
151
152impl Decodable2718 for AnyReceiptEnvelope {
153 fn typed_decode(ty: u8, buf: &mut &[u8]) -> Eip2718Result<Self> {
154 let receipt = Decodable::decode(buf)?;
155 Ok(Self { inner: receipt, r#type: ty })
156 }
157
158 fn fallback_decode(buf: &mut &[u8]) -> Eip2718Result<Self> {
159 Self::typed_decode(0, buf)
160 }
161}