1use crate::HeadersDirection;
5use alloy_eips::BlockHashOrNumber;
6use alloy_primitives::B256;
7use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
8use reth_codecs_derive::{add_arbitrary_tests, generate_tests};
9
10#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RlpEncodable, RlpDecodable)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
22#[add_arbitrary_tests(rlp)]
23pub struct GetBlockHeaders {
24 pub start_block: BlockHashOrNumber,
26
27 pub limit: u64,
29
30 pub skip: u32,
35
36 pub direction: HeadersDirection,
38}
39
40#[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)]
42#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
43#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
44pub struct BlockHeaders<H = alloy_consensus::Header>(
45 pub Vec<H>,
47);
48
49generate_tests!(#[rlp, 10] BlockHeaders<alloy_consensus::Header>, EthBlockHeadersTests);
50
51impl<H> From<Vec<H>> for BlockHeaders<H> {
52 fn from(headers: Vec<H>) -> Self {
53 Self(headers)
54 }
55}
56
57#[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)]
59#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
61#[add_arbitrary_tests(rlp)]
62pub struct GetBlockBodies(
63 pub Vec<B256>,
65);
66
67impl From<Vec<B256>> for GetBlockBodies {
68 fn from(hashes: Vec<B256>) -> Self {
69 Self(hashes)
70 }
71}
72
73#[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)]
76#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
77#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
78pub struct BlockBodies<B = reth_primitives::BlockBody>(
79 pub Vec<B>,
81);
82
83generate_tests!(#[rlp, 16] BlockBodies<reth_primitives::BlockBody>, EthBlockBodiesTests);
84
85impl<B> From<Vec<B>> for BlockBodies<B> {
86 fn from(bodies: Vec<B>) -> Self {
87 Self(bodies)
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use crate::{
94 message::RequestPair, BlockBodies, BlockHeaders, GetBlockBodies, GetBlockHeaders,
95 HeadersDirection,
96 };
97 use alloy_consensus::{Header, TxLegacy};
98 use alloy_eips::BlockHashOrNumber;
99 use alloy_primitives::{hex, PrimitiveSignature as Signature, TxKind, U256};
100 use alloy_rlp::{Decodable, Encodable};
101 use reth_primitives::{BlockBody, Transaction, TransactionSigned};
102 use std::str::FromStr;
103
104 #[test]
105 fn decode_hash() {
106 let rlp = hex!("a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
108 let decoded_number = BlockHashOrNumber::decode(&mut &rlp[..]).unwrap();
109 let full_bytes = [0xff; 32].into();
110 let expected = BlockHashOrNumber::Hash(full_bytes);
111 assert_eq!(expected, decoded_number);
112 }
113
114 #[test]
115 fn decode_number() {
116 let rlp = hex!("88ffffffffffffffff");
118 let decoded_number = BlockHashOrNumber::decode(&mut &rlp[..]).unwrap();
119 let expected = BlockHashOrNumber::Number(u64::MAX);
120 assert_eq!(expected, decoded_number);
121 }
122
123 #[test]
124 fn decode_largest_single_byte() {
125 let rlp = hex!("7f");
127 let decoded_number = BlockHashOrNumber::decode(&mut &rlp[..]).unwrap();
128 let expected = BlockHashOrNumber::Number(0x7fu64);
129 assert_eq!(expected, decoded_number);
130 }
131
132 #[test]
133 fn decode_long_hash() {
134 let long_rlp = hex!("a1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
137 let decode_result = BlockHashOrNumber::decode(&mut &long_rlp[..]);
138 assert!(
139 decode_result.is_err(),
140 "Decoding a bytestring longer than 32 bytes should not decode successfully"
141 );
142 }
143
144 #[test]
145 fn decode_long_number() {
146 let long_number = hex!("89ffffffffffffffffff");
149 let decode_result = BlockHashOrNumber::decode(&mut &long_number[..]);
150 assert!(decode_result.is_err(), "Decoding a number longer than 64 bits (but not exactly 32 bytes) should not decode successfully");
151 }
152
153 #[test]
155 fn encode_get_block_header() {
156 let expected = hex!(
157 "e8820457e4a000000000000000000000000000000000000000000000000000000000deadc0de050580"
158 );
159 let mut data = vec![];
160 RequestPair::<GetBlockHeaders> {
161 request_id: 1111,
162 message: GetBlockHeaders {
163 start_block: BlockHashOrNumber::Hash(
164 hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(),
165 ),
166 limit: 5,
167 skip: 5,
168 direction: HeadersDirection::Rising,
169 },
170 }
171 .encode(&mut data);
172 assert_eq!(data, expected);
173 }
174
175 #[test]
177 fn decode_get_block_header() {
178 let data = hex!(
179 "e8820457e4a000000000000000000000000000000000000000000000000000000000deadc0de050580"
180 );
181 let expected = RequestPair::<GetBlockHeaders> {
182 request_id: 1111,
183 message: GetBlockHeaders {
184 start_block: BlockHashOrNumber::Hash(
185 hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(),
186 ),
187 limit: 5,
188 skip: 5,
189 direction: HeadersDirection::Rising,
190 },
191 };
192 let result = RequestPair::decode(&mut &data[..]);
193 assert_eq!(result.unwrap(), expected);
194 }
195
196 #[test]
198 fn encode_get_block_header_number() {
199 let expected = hex!("ca820457c682270f050580");
200 let mut data = vec![];
201 RequestPair {
202 request_id: 1111,
203 message: GetBlockHeaders {
204 start_block: BlockHashOrNumber::Number(9999),
205 limit: 5,
206 skip: 5,
207 direction: HeadersDirection::Rising,
208 },
209 }
210 .encode(&mut data);
211 assert_eq!(data, expected);
212 }
213
214 #[test]
216 fn decode_get_block_header_number() {
217 let data = hex!("ca820457c682270f050580");
218 let expected = RequestPair {
219 request_id: 1111,
220 message: GetBlockHeaders {
221 start_block: BlockHashOrNumber::Number(9999),
222 limit: 5,
223 skip: 5,
224 direction: HeadersDirection::Rising,
225 },
226 };
227 let result = RequestPair::decode(&mut &data[..]);
228 assert_eq!(result.unwrap(), expected);
229 }
230
231 #[test]
233 fn encode_block_header() {
234 let expected = hex!("f90202820457f901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000");
236 let mut data = vec![];
237 RequestPair {
238 request_id: 1111,
239 message: BlockHeaders(vec![
240 Header {
241 parent_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
242 ommers_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
243 beneficiary: hex!("0000000000000000000000000000000000000000").into(),
244 state_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
245 transactions_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
246 receipts_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
247 logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
248 difficulty: U256::from(0x8aeu64),
249 number: 0xd05u64,
250 gas_limit: 0x115c,
251 gas_used: 0x15b3,
252 timestamp: 0x1a0au64,
253 extra_data: hex!("7788")[..].into(),
254 mix_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
255 nonce: 0x0000000000000000u64.into(),
256 base_fee_per_gas: None,
257 withdrawals_root: None,
258 blob_gas_used: None,
259 excess_blob_gas: None,
260 parent_beacon_block_root: None,
261 requests_hash: None,
262 target_blobs_per_block: None,
263 },
264 ]),
265 }.encode(&mut data);
266 assert_eq!(data, expected);
267 }
268
269 #[test]
271 fn decode_block_header() {
272 let data = hex!("f90202820457f901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000");
273 let expected = RequestPair {
274 request_id: 1111,
275 message: BlockHeaders(vec![
276 Header {
277 parent_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
278 ommers_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
279 beneficiary: hex!("0000000000000000000000000000000000000000").into(),
280 state_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
281 transactions_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
282 receipts_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
283 logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
284 difficulty: U256::from(0x8aeu64),
285 number: 0xd05u64,
286 gas_limit: 0x115c,
287 gas_used: 0x15b3,
288 timestamp: 0x1a0au64,
289 extra_data: hex!("7788")[..].into(),
290 mix_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
291 nonce: 0x0000000000000000u64.into(),
292 base_fee_per_gas: None,
293 withdrawals_root: None,
294 blob_gas_used: None,
295 excess_blob_gas: None,
296 parent_beacon_block_root: None,
297 requests_hash: None,
298 target_blobs_per_block: None,
299 },
300 ]),
301 };
302 let result = RequestPair::decode(&mut &data[..]);
303 assert_eq!(result.unwrap(), expected);
304 }
305
306 #[test]
308 fn encode_get_block_bodies() {
309 let expected = hex!("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef");
310 let mut data = vec![];
311 RequestPair {
312 request_id: 1111,
313 message: GetBlockBodies(vec![
314 hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(),
315 hex!("00000000000000000000000000000000000000000000000000000000feedbeef").into(),
316 ]),
317 }
318 .encode(&mut data);
319 assert_eq!(data, expected);
320 }
321
322 #[test]
324 fn decode_get_block_bodies() {
325 let data = hex!("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef");
326 let expected = RequestPair {
327 request_id: 1111,
328 message: GetBlockBodies(vec![
329 hex!("00000000000000000000000000000000000000000000000000000000deadc0de").into(),
330 hex!("00000000000000000000000000000000000000000000000000000000feedbeef").into(),
331 ]),
332 };
333 let result = RequestPair::decode(&mut &data[..]);
334 assert_eq!(result.unwrap(), expected);
335 }
336
337 #[test]
339 fn encode_block_bodies() {
340 let expected = hex!("f902dc820457f902d6f902d3f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afbf901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000");
341 let mut data = vec![];
342 let request = RequestPair {
343 request_id: 1111,
344 message: BlockBodies(vec![
345 BlockBody {
346 transactions: vec![
347 TransactionSigned::new_unhashed(Transaction::Legacy(TxLegacy {
348 chain_id: Some(1),
349 nonce: 0x8u64,
350 gas_price: 0x4a817c808,
351 gas_limit: 0x2e248,
352 to: TxKind::Call(hex!("3535353535353535353535353535353535353535").into()),
353 value: U256::from(0x200u64),
354 input: Default::default(),
355 }), Signature::new(
356 U256::from_str("0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12").unwrap(),
357 U256::from_str("0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10").unwrap(),
358 false,
359 ),
360 ),
361 TransactionSigned::new_unhashed(Transaction::Legacy(TxLegacy {
362 chain_id: Some(1),
363 nonce: 0x9u64,
364 gas_price: 0x4a817c809,
365 gas_limit: 0x33450,
366 to: TxKind::Call(hex!("3535353535353535353535353535353535353535").into()),
367 value: U256::from(0x2d9u64),
368 input: Default::default(),
369 }), Signature::new(
370 U256::from_str("0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb").unwrap(),
371 U256::from_str("0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb").unwrap(),
372 false,
373 ),
374 ),
375 ],
376 ommers: vec![
377 Header {
378 parent_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
379 ommers_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
380 beneficiary: hex!("0000000000000000000000000000000000000000").into(),
381 state_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
382 transactions_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
383 receipts_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
384 logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
385 difficulty: U256::from(0x8aeu64),
386 number: 0xd05u64,
387 gas_limit: 0x115c,
388 gas_used: 0x15b3,
389 timestamp: 0x1a0au64,
390 extra_data: hex!("7788")[..].into(),
391 mix_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
392 nonce: 0x0000000000000000u64.into(),
393 base_fee_per_gas: None,
394 withdrawals_root: None,
395 blob_gas_used: None,
396 excess_blob_gas: None,
397 parent_beacon_block_root: None,
398 requests_hash: None,
399 target_blobs_per_block: None,
400 },
401 ],
402 withdrawals: None,
403 }
404 ]),
405 };
406 request.encode(&mut data);
407 assert_eq!(data, expected);
408 }
409
410 #[test]
412 fn decode_block_bodies() {
413 let data = hex!("f902dc820457f902d6f902d3f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afbf901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000");
414 let expected = RequestPair {
415 request_id: 1111,
416 message: BlockBodies(vec![
417 BlockBody {
418 transactions: vec![
419 TransactionSigned::new_unhashed(Transaction::Legacy(
420 TxLegacy {
421 chain_id: Some(1),
422 nonce: 0x8u64,
423 gas_price: 0x4a817c808,
424 gas_limit: 0x2e248,
425 to: TxKind::Call(hex!("3535353535353535353535353535353535353535").into()),
426 value: U256::from(0x200u64),
427 input: Default::default(),
428 }),
429 Signature::new(
430 U256::from_str("0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12").unwrap(),
431 U256::from_str("0x64b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10").unwrap(),
432 false,
433 ),
434 ),
435 TransactionSigned::new_unhashed(
436 Transaction::Legacy(TxLegacy {
437 chain_id: Some(1),
438 nonce: 0x9u64,
439 gas_price: 0x4a817c809,
440 gas_limit: 0x33450,
441 to: TxKind::Call(hex!("3535353535353535353535353535353535353535").into()),
442 value: U256::from(0x2d9u64),
443 input: Default::default(),
444 }),
445 Signature::new(
446 U256::from_str("0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb").unwrap(),
447 U256::from_str("0x52f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb").unwrap(),
448 false,
449 ),
450 ),
451 ],
452 ommers: vec![
453 Header {
454 parent_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
455 ommers_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
456 beneficiary: hex!("0000000000000000000000000000000000000000").into(),
457 state_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
458 transactions_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
459 receipts_root: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
460 logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
461 difficulty: U256::from(0x8aeu64),
462 number: 0xd05u64,
463 gas_limit: 0x115c,
464 gas_used: 0x15b3,
465 timestamp: 0x1a0au64,
466 extra_data: hex!("7788")[..].into(),
467 mix_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
468 nonce: 0x0000000000000000u64.into(),
469 base_fee_per_gas: None,
470 withdrawals_root: None,
471 blob_gas_used: None,
472 excess_blob_gas: None,
473 parent_beacon_block_root: None,
474 requests_hash: None,
475 target_blobs_per_block: None,
476 },
477 ],
478 withdrawals: None,
479 }
480 ]),
481 };
482 let result = RequestPair::decode(&mut &data[..]).unwrap();
483 assert_eq!(result, expected);
484 }
485
486 #[test]
487 fn empty_block_bodies_rlp() {
488 let body = BlockBodies::default();
489 let mut buf = Vec::new();
490 body.encode(&mut buf);
491 let decoded = BlockBodies::<BlockBody>::decode(&mut buf.as_slice()).unwrap();
492 assert_eq!(body, decoded);
493 }
494}