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