massa_consensus_exports/
bootstrapable_graph.rs

1use crate::export_active_block::{
2    ExportActiveBlock, ExportActiveBlockDeserializer, ExportActiveBlockSerializer,
3};
4use massa_models::block::BlockDeserializerArgs;
5use massa_serialization::{
6    Deserializer, SerializeError, Serializer, U32VarIntDeserializer, U32VarIntSerializer,
7};
8use nom::error::{ContextError, ParseError};
9use nom::{error::context, multi::length_count, sequence::tuple, IResult, Parser};
10use serde::{Deserialize, Serialize};
11use std::ops::Bound::Included;
12
13/// Bootstrap graph
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct BootstrapableGraph {
16    /// list of final blocks
17    pub final_blocks: Vec<ExportActiveBlock>,
18}
19
20/// Basic serializer for `BootstrapableGraph`
21#[derive(Default)]
22pub struct BootstrapableGraphSerializer {
23    block_count_serializer: U32VarIntSerializer,
24    export_active_block_serializer: ExportActiveBlockSerializer,
25}
26
27impl BootstrapableGraphSerializer {
28    /// Creates a `BootstrapableGraphSerializer`
29    pub fn new() -> Self {
30        Self {
31            block_count_serializer: U32VarIntSerializer::new(),
32            export_active_block_serializer: ExportActiveBlockSerializer::new(),
33        }
34    }
35}
36
37impl Serializer<BootstrapableGraph> for BootstrapableGraphSerializer {
38    /// ## Example
39    /// ```rust
40    /// use massa_consensus_exports::bootstrapable_graph::{BootstrapableGraph, BootstrapableGraphSerializer};
41    /// use massa_serialization::Serializer;
42    /// use massa_hash::Hash;
43    /// use massa_models::{prehash::PreHashMap, block_id::BlockId, config::THREAD_COUNT};
44    /// let mut bootstrapable_graph = BootstrapableGraph {
45    ///   final_blocks: Vec::new(),
46    /// };
47    /// let mut buffer = Vec::new();
48    /// BootstrapableGraphSerializer::new().serialize(&bootstrapable_graph, &mut buffer).unwrap();
49    /// ```
50    fn serialize(
51        &self,
52        value: &BootstrapableGraph,
53        buffer: &mut Vec<u8>,
54    ) -> Result<(), SerializeError> {
55        // block count
56        self.block_count_serializer.serialize(
57            &value
58                .final_blocks
59                .len()
60                .try_into()
61                .map_err(|_| SerializeError::NumberTooBig("Too many final blocks".to_string()))?,
62            buffer,
63        )?;
64
65        // final blocks
66        for export_active_block in &value.final_blocks {
67            self.export_active_block_serializer
68                .serialize(export_active_block, buffer)?;
69        }
70
71        Ok(())
72    }
73}
74
75/// Basic deserializer for `BootstrapableGraph`
76pub struct BootstrapableGraphDeserializer {
77    block_count_deserializer: U32VarIntDeserializer,
78    export_active_block_deserializer: ExportActiveBlockDeserializer,
79}
80
81impl BootstrapableGraphDeserializer {
82    /// Creates a `BootstrapableGraphDeserializer`
83    #[allow(clippy::too_many_arguments)]
84    pub fn new(block_der_args: BlockDeserializerArgs, max_bootstrap_blocks: u32) -> Self {
85        Self {
86            block_count_deserializer: U32VarIntDeserializer::new(
87                Included(0),
88                Included(max_bootstrap_blocks),
89            ),
90            export_active_block_deserializer: ExportActiveBlockDeserializer::new(block_der_args),
91        }
92    }
93}
94
95impl Deserializer<BootstrapableGraph> for BootstrapableGraphDeserializer {
96    /// ## Example
97    /// ```rust
98    /// use massa_consensus_exports::bootstrapable_graph::{BootstrapableGraph, BootstrapableGraphDeserializer, BootstrapableGraphSerializer};
99    /// use massa_serialization::{Deserializer, Serializer, DeserializeError};
100    /// use massa_hash::Hash;
101    /// use massa_models::{prehash::PreHashMap, block_id::BlockId, config::THREAD_COUNT};
102    /// use massa_models::block::BlockDeserializerArgs;
103    /// use massa_models::config::CHAINID;
104    /// let mut bootstrapable_graph = BootstrapableGraph {
105    ///   final_blocks: Vec::new(),
106    /// };
107    /// let mut buffer = Vec::new();
108    /// BootstrapableGraphSerializer::new().serialize(&bootstrapable_graph, &mut buffer).unwrap();
109    /// let args = BlockDeserializerArgs {
110    /// thread_count: 32,max_operations_per_block: 16,endorsement_count: 10,max_denunciations_per_block_header: 128,last_start_period: Some(0),chain_id: *CHAINID};
111    /// let (rest, bootstrapable_graph_deserialized) = BootstrapableGraphDeserializer::new(args, 10).deserialize::<DeserializeError>(&buffer).unwrap();
112    /// let mut buffer2 = Vec::new();
113    /// BootstrapableGraphSerializer::new().serialize(&bootstrapable_graph_deserialized, &mut buffer2).unwrap();
114    /// assert_eq!(buffer, buffer2);
115    /// assert_eq!(rest.len(), 0);
116    /// ```
117    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
118        &self,
119        buffer: &'a [u8],
120    ) -> IResult<&'a [u8], BootstrapableGraph, E> {
121        context(
122            "Failed BootstrapableGraph deserialization",
123            tuple((context(
124                "Failed active_blocks deserialization",
125                length_count(
126                    context("Failed final block count deserialization", |input| {
127                        self.block_count_deserializer.deserialize(input)
128                    }),
129                    context("Failed export_active_block deserialization", |input| {
130                        self.export_active_block_deserializer.deserialize(input)
131                    }),
132                ),
133            ),)),
134        )
135        .map(|(final_blocks,)| BootstrapableGraph { final_blocks })
136        .parse(buffer)
137    }
138}