reth_eth_wire_types/
receipts.rs1use alloc::vec::Vec;
4use alloy_consensus::{ReceiptWithBloom, RlpDecodableReceipt, RlpEncodableReceipt, TxReceipt};
5use alloy_primitives::B256;
6use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper};
7use reth_codecs_derive::add_arbitrary_tests;
8use reth_ethereum_primitives::Receipt;
9
10#[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
14#[add_arbitrary_tests(rlp)]
15pub struct GetReceipts(
16 pub Vec<B256>,
18);
19
20#[derive(Clone, Debug, PartialEq, Eq, Default)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
25#[add_arbitrary_tests(rlp)]
26pub struct Receipts<T = Receipt>(
27 pub Vec<Vec<ReceiptWithBloom<T>>>,
29);
30
31impl<T: RlpEncodableReceipt> alloy_rlp::Encodable for Receipts<T> {
32 #[inline]
33 fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
34 self.0.encode(out)
35 }
36 #[inline]
37 fn length(&self) -> usize {
38 self.0.length()
39 }
40}
41
42impl<T: RlpDecodableReceipt> alloy_rlp::Decodable for Receipts<T> {
43 #[inline]
44 fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
45 alloy_rlp::Decodable::decode(buf).map(Self)
46 }
47}
48
49#[derive(Clone, Debug, PartialEq, Eq)]
53#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
54#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
55#[add_arbitrary_tests(rlp)]
56pub struct Receipts69<T = Receipt>(pub Vec<Vec<T>>);
57
58impl<T: RlpEncodableReceipt + alloy_rlp::Encodable> alloy_rlp::Encodable for Receipts69<T> {
59 #[inline]
60 fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
61 self.0.encode(out)
62 }
63 #[inline]
64 fn length(&self) -> usize {
65 self.0.length()
66 }
67}
68
69impl<T: RlpDecodableReceipt + alloy_rlp::Decodable> alloy_rlp::Decodable for Receipts69<T> {
70 #[inline]
71 fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
72 alloy_rlp::Decodable::decode(buf).map(Self)
73 }
74}
75
76impl<T: TxReceipt> Receipts69<T> {
77 pub fn into_with_bloom(self) -> Receipts<T> {
81 Receipts(
82 self.0
83 .into_iter()
84 .map(|receipts| receipts.into_iter().map(|r| r.into_with_bloom()).collect())
85 .collect(),
86 )
87 }
88}
89
90impl<T: TxReceipt> From<Receipts69<T>> for Receipts<T> {
91 fn from(receipts: Receipts69<T>) -> Self {
92 receipts.into_with_bloom()
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99 use crate::{message::RequestPair, GetReceipts, Receipts};
100 use alloy_consensus::TxType;
101 use alloy_primitives::{hex, Log};
102 use alloy_rlp::{Decodable, Encodable};
103
104 #[test]
105 fn roundtrip_eip1559() {
106 let receipts = Receipts(vec![vec![ReceiptWithBloom {
107 receipt: Receipt { tx_type: TxType::Eip1559, ..Default::default() },
108 logs_bloom: Default::default(),
109 }]]);
110
111 let mut out = vec![];
112 receipts.encode(&mut out);
113
114 let mut out = out.as_slice();
115 let decoded = Receipts::decode(&mut out).unwrap();
116
117 assert_eq!(receipts, decoded);
118 }
119
120 #[test]
121 fn encode_get_receipts() {
123 let expected = hex!(
124 "f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"
125 );
126 let mut data = vec![];
127 let request = RequestPair {
128 request_id: 1111,
129 message: GetReceipts(vec![
130 hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(),
131 hex!("00000000000000000000000000000000000000000000000000000000feedbeef").into(),
132 ]),
133 };
134 request.encode(&mut data);
135 assert_eq!(data, expected);
136 }
137
138 #[test]
139 fn decode_get_receipts() {
141 let data = hex!(
142 "f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"
143 );
144 let request = RequestPair::<GetReceipts>::decode(&mut &data[..]).unwrap();
145 assert_eq!(
146 request,
147 RequestPair {
148 request_id: 1111,
149 message: GetReceipts(vec![
150 hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(),
151 hex!("00000000000000000000000000000000000000000000000000000000feedbeef").into(),
152 ]),
153 }
154 );
155 }
156
157 #[test]
159 fn encode_receipts() {
160 let expected = hex!(
161 "f90172820457f9016cf90169f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"
162 );
163 let mut data = vec![];
164 let request = RequestPair {
165 request_id: 1111,
166 message: Receipts(vec![vec![
167 ReceiptWithBloom {
168 receipt: Receipt {
169 tx_type: TxType::Legacy,
170 cumulative_gas_used: 0x1u64,
171 logs: vec![
172 Log::new_unchecked(
173 hex!("0000000000000000000000000000000000000011").into(),
174 vec![
175 hex!("000000000000000000000000000000000000000000000000000000000000dead").into(),
176 hex!("000000000000000000000000000000000000000000000000000000000000beef").into(),
177 ],
178 hex!("0100ff")[..].into(),
179 ),
180 ],
181 success: false,
182 },
183 logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
184 },
185 ]]),
186 };
187 request.encode(&mut data);
188 assert_eq!(data, expected);
189 }
190
191 #[test]
193 fn decode_receipts() {
194 let data = hex!(
195 "f90172820457f9016cf90169f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"
196 );
197 let request = RequestPair::<Receipts>::decode(&mut &data[..]).unwrap();
198 assert_eq!(
199 request,
200 RequestPair {
201 request_id: 1111,
202 message: Receipts(vec![
203 vec![
204 ReceiptWithBloom {
205 receipt: Receipt {
206 tx_type: TxType::Legacy,
207 cumulative_gas_used: 0x1u64,
208 logs: vec![
209 Log::new_unchecked(
210 hex!("0000000000000000000000000000000000000011").into(),
211 vec![
212 hex!("000000000000000000000000000000000000000000000000000000000000dead").into(),
213 hex!("000000000000000000000000000000000000000000000000000000000000beef").into(),
214 ],
215 hex!("0100ff")[..].into(),
216 ),
217 ],
218 success: false,
219 },
220 logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
221 },
222 ],
223 ]),
224 }
225 );
226 }
227}