snarkos_node_router_messages/
block_response.rs1use super::*;
17
18use snarkvm::{
19 ledger::narwhal::Data,
20 prelude::{FromBytes, ToBytes},
21};
22
23use std::borrow::Cow;
24
25#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct BlockResponse<N: Network> {
27 pub request: BlockRequest,
29 pub blocks: Data<DataBlocks<N>>,
31}
32
33impl<N: Network> MessageTrait for BlockResponse<N> {
34 #[inline]
36 fn name(&self) -> Cow<'static, str> {
37 let start = self.request.start_height;
38 let end = self.request.end_height;
39 match start + 1 == end {
40 true => format!("BlockResponse {start}"),
41 false => format!("BlockResponse {start}..{end}"),
42 }
43 .into()
44 }
45}
46
47impl<N: Network> ToBytes for BlockResponse<N> {
48 fn write_le<W: io::Write>(&self, mut writer: W) -> io::Result<()> {
49 self.request.write_le(&mut writer)?;
50 self.blocks.write_le(writer)
51 }
52}
53
54impl<N: Network> FromBytes for BlockResponse<N> {
55 fn read_le<R: io::Read>(mut reader: R) -> io::Result<Self> {
56 let request = BlockRequest::read_le(&mut reader)?;
57 let blocks = Data::read_le(reader)?;
58 Ok(Self { request, blocks })
59 }
60}
61
62#[cfg(test)]
63pub mod prop_tests {
64 use crate::{BlockResponse, DataBlocks, block_request::prop_tests::any_block_request};
65 use snarkvm::{
66 ledger::test_helpers::sample_genesis_block,
67 prelude::{block::Block, narwhal::Data},
68 utilities::{FromBytes, TestRng, ToBytes},
69 };
70
71 use bytes::{Buf, BufMut, BytesMut};
72 use proptest::{
73 collection::vec,
74 prelude::{BoxedStrategy, Strategy, any},
75 };
76 use test_strategy::proptest;
77
78 type CurrentNetwork = snarkvm::prelude::MainnetV0;
79
80 pub fn any_block() -> BoxedStrategy<Block<CurrentNetwork>> {
81 any::<u64>().prop_map(|seed| sample_genesis_block(&mut TestRng::fixed(seed))).boxed()
82 }
83
84 pub fn any_data_blocks() -> BoxedStrategy<DataBlocks<CurrentNetwork>> {
85 vec(any_block(), 0..=1).prop_map(DataBlocks).boxed()
86 }
87
88 pub fn any_block_response() -> BoxedStrategy<BlockResponse<CurrentNetwork>> {
89 (any_block_request(), any_data_blocks())
90 .prop_map(|(request, data_blocks)| BlockResponse { request, blocks: Data::Object(data_blocks) })
91 .boxed()
92 }
93
94 #[proptest]
95 fn block_response_roundtrip(#[strategy(any_block_response())] block_response: BlockResponse<CurrentNetwork>) {
96 let mut bytes = BytesMut::default().writer();
97 block_response.write_le(&mut bytes).unwrap();
98 let decoded = BlockResponse::<CurrentNetwork>::read_le(&mut bytes.into_inner().reader()).unwrap();
99 assert_eq!(block_response.request, decoded.request);
100 assert_eq!(
101 block_response.blocks.deserialize_blocking().unwrap(),
102 decoded.blocks.deserialize_blocking().unwrap(),
103 );
104 }
105}