massa_models/
block.rs

1//! Copyright (c) 2022 MASSA LABS <info@massa.net>
2
3// use crate::config::THREAD_COUNT;
4// use crate::endorsement::{EndorsementId, EndorsementSerializer, EndorsementSerializerLW};
5// use crate::prehash::PreHashed;
6use crate::secure_share::{
7    Id, SecureShare, SecureShareContent, SecureShareDeserializer, SecureShareSerializer,
8};
9use crate::{
10    // endorsement::{Endorsement, EndorsementDeserializerLW, SecureShareEndorsement},
11    error::ModelsError,
12    operation::{
13        compute_operations_hash, OperationId, OperationIdSerializer, OperationIdsDeserializer,
14        OperationIdsSerializer, SecureShareOperation,
15    },
16    // slot::{Slot, SlotDeserializer, SlotSerializer},
17};
18// use massa_hash::{Hash, HashDeserializer};
19use massa_hash::Hash;
20use massa_serialization::{
21    // DeserializeError,
22    Deserializer,
23    SerializeError,
24    Serializer,
25    // U32VarIntDeserializer,
26    // U32VarIntSerializer, U64VarIntDeserializer, U64VarIntSerializer,
27};
28use massa_signature::{KeyPair, PublicKey, Signature};
29// use nom::branch::alt;
30// use nom::bytes::complete::tag;
31use nom::error::context;
32// use nom::multi::{count, length_count};
33use nom::sequence::tuple;
34use nom::Parser;
35use nom::{
36    error::{ContextError, ParseError},
37    IResult,
38};
39use serde::{Deserialize, Serialize};
40// use serde_with::{DeserializeFromStr, SerializeDisplay};
41// use std::collections::HashSet;
42// use std::convert::TryInto;
43use std::fmt::Formatter;
44// use std::ops::Bound::{Excluded, Included};
45// use std::str::FromStr;
46use crate::block_header::{BlockHeader, BlockHeaderDeserializer, SecuredHeader};
47use crate::block_id::BlockId;
48
49/// block
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct Block {
52    /// signed header
53    pub header: SecuredHeader,
54    /// operations ids
55    pub operations: Vec<OperationId>,
56}
57
58/// filled block
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct FilledBlock {
61    /// signed header
62    pub header: SecuredHeader,
63    /// operations
64    pub operations: Vec<(OperationId, Option<SecureShareOperation>)>,
65}
66
67/// Block with associated meta-data and interfaces allowing trust of data in untrusted network
68pub type SecureShareBlock = SecureShare<Block, BlockId>;
69
70/// Blocks are not signed at the block level: authentication lives in the nested
71/// [`SecuredHeader`]. The outer [`SecureShareBlock`] copies the header's signature,
72/// creator key, and id for transport convenience, while `serialized_data` holds
73/// the full block bytes (header + operation ids).
74impl SecureShareContent for Block {
75    /// Delegates to the nested signed header signing domain.
76    ///
77    /// Outer auth fields are copies of the header's; the default
78    /// [`SecureShareContent::verify_signature`] would verify against the wrong domain.
79    fn verify_signature(
80        &self,
81        public_key: &PublicKey,
82        content_hash: &Hash,
83        signature: &Signature,
84    ) -> Result<(), ModelsError> {
85        self.header
86            .content
87            .verify_signature(public_key, content_hash, signature)
88    }
89
90    fn new_verifiable<SC: Serializer<Self>, U: Id>(
91        self,
92        content_serializer: SC,
93        _keypair: &KeyPair,
94        _chain_id: u64,
95    ) -> Result<SecureShare<Self, U>, ModelsError> {
96        let mut content_serialized = Vec::new();
97        content_serializer.serialize(&self, &mut content_serialized)?;
98        Ok(SecureShare {
99            signature: self.header.signature,
100            content_creator_pub_key: self.header.content_creator_pub_key,
101            content_creator_address: self.header.content_creator_address,
102            id: U::new(*self.header.id.get_hash()),
103            content: self,
104            serialized_data: content_serialized,
105        })
106    }
107
108    fn serialize(
109        _signature: &Signature,
110        _creator_public_key: &PublicKey,
111        serialized_content: &[u8],
112        buffer: &mut Vec<u8>,
113    ) -> Result<(), SerializeError> {
114        buffer.extend(serialized_content);
115        Ok(())
116    }
117
118    fn deserialize<
119        'a,
120        E: ParseError<&'a [u8]> + ContextError<&'a [u8]>,
121        DC: Deserializer<Self>,
122        U: Id,
123    >(
124        _content_serializer: Option<&dyn Serializer<Self>>,
125        _signature_deserializer: &massa_signature::SignatureDeserializer,
126        _creator_public_key_deserializer: &massa_signature::PublicKeyDeserializer,
127        content_deserializer: &DC,
128        buffer: &'a [u8],
129        _chain_id: u64,
130    ) -> IResult<&'a [u8], SecureShare<Self, U>, E> {
131        let (rest, content) = content_deserializer.deserialize(buffer)?;
132        Ok((
133            rest,
134            SecureShare {
135                signature: content.header.signature,
136                content_creator_pub_key: content.header.content_creator_pub_key,
137                content_creator_address: content.header.content_creator_address,
138                id: U::new(*content.header.id.get_hash()),
139                content,
140                serialized_data: buffer[..buffer.len() - rest.len()].to_vec(),
141            },
142        ))
143    }
144}
145/// Serializer for `Block`
146pub struct BlockSerializer {
147    header_serializer: SecureShareSerializer,
148    op_ids_serializer: OperationIdsSerializer,
149}
150
151impl BlockSerializer {
152    /// Creates a new `BlockSerializer`
153    pub fn new() -> Self {
154        BlockSerializer {
155            header_serializer: SecureShareSerializer::new(),
156            op_ids_serializer: OperationIdsSerializer::new(),
157        }
158    }
159}
160
161impl Default for BlockSerializer {
162    fn default() -> Self {
163        Self::new()
164    }
165}
166
167impl Serializer<Block> for BlockSerializer {
168    /// ## Example:
169    /// ```rust
170    /// use massa_models::{block::{Block, BlockSerializer}, config::THREAD_COUNT, slot::Slot, endorsement::{Endorsement, EndorsementSerializer}, secure_share::SecureShareContent, prehash::PreHashSet};
171    /// use massa_models::block_header::{BlockHeader, BlockHeaderSerializer};
172    /// use massa_models::block_id::{BlockId};
173    /// use massa_hash::Hash;
174    /// use massa_models::config::CHAINID;
175    /// use massa_signature::KeyPair;
176    /// use massa_models::operation::{compute_operations_hash, OperationIdSerializer};
177    /// use massa_serialization::Serializer;
178    /// let keypair = KeyPair::generate(0).unwrap();
179    /// let parents = (0..THREAD_COUNT)
180    ///     .map(|i| BlockId::generate_from_hash(Hash::compute_from(&[i])))
181    ///     .collect();
182    ///
183    /// // create block header
184    /// let orig_header = BlockHeader::new_verifiable(
185    ///     BlockHeader {
186    ///         current_version: 0,
187    ///         announced_version: None,
188    ///         slot: Slot::new(1, 1),
189    ///         parents,
190    ///         operation_merkle_root: compute_operations_hash(&[], &OperationIdSerializer::new()),
191    ///         endorsements: vec![
192    ///             Endorsement::new_verifiable(
193    ///                 Endorsement {
194    ///                     slot: Slot::new(1, 1),
195    ///                     index: 1,
196    ///                     endorsed_block: BlockId::generate_from_hash(Hash::compute_from("blk1".as_bytes())),
197    ///                 },
198    ///                 EndorsementSerializer::new(),
199    ///                 &keypair,
200    ///                 *CHAINID
201    ///             )
202    ///             .unwrap(),
203    ///             Endorsement::new_verifiable(
204    ///                 Endorsement {
205    ///                     slot: Slot::new(4, 0),
206    ///                     index: 3,
207    ///                     endorsed_block: BlockId::generate_from_hash(Hash::compute_from("blk2".as_bytes())),
208    ///                 },
209    ///                 EndorsementSerializer::new(),
210    ///                 &keypair,
211    ///                 *CHAINID
212    ///             )
213    ///             .unwrap(),
214    ///         ],
215    ///         denunciations: Vec::new(),
216    ///     },
217    ///     BlockHeaderSerializer::new(),
218    ///     &keypair,
219    ///     *CHAINID
220    /// )
221    /// .unwrap();
222    ///
223    /// // create block
224    /// let orig_block = Block {
225    ///     header: orig_header,
226    ///     operations: Vec::new(),
227    /// };
228    ///
229    /// let mut buffer = Vec::new();
230    /// BlockSerializer::new().serialize(&orig_block, &mut buffer).unwrap();
231    /// ```
232    fn serialize(&self, value: &Block, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
233        self.header_serializer.serialize(&value.header, buffer)?;
234        self.op_ids_serializer
235            .serialize(&value.operations, buffer)?;
236        Ok(())
237    }
238}
239
240/// Parameters for the deserializer of a block
241pub struct BlockDeserializerArgs {
242    /// Number of threads in Massa
243    pub thread_count: u8,
244    /// Maximum of operations in a block
245    pub max_operations_per_block: u32,
246    /// Number of endorsements in a block
247    pub endorsement_count: u32,
248    /// Max denunciations in a block
249    pub max_denunciations_per_block_header: u32,
250    /// If Some(lsp), this will through if trying to deserialize a block with a period before the genesis blocks
251    pub last_start_period: Option<u64>,
252    /// chain id
253    pub chain_id: u64,
254}
255
256/// Deserializer for `Block`
257pub struct BlockDeserializer {
258    header_deserializer: SecureShareDeserializer<BlockHeader, BlockHeaderDeserializer>,
259    op_ids_deserializer: OperationIdsDeserializer,
260    op_id_serializer: OperationIdSerializer,
261}
262
263impl BlockDeserializer {
264    /// Creates a new `BlockDeserializer`
265    pub fn new(args: BlockDeserializerArgs) -> Self {
266        BlockDeserializer {
267            header_deserializer: SecureShareDeserializer::new(
268                BlockHeaderDeserializer::new(
269                    args.thread_count,
270                    args.endorsement_count,
271                    args.max_denunciations_per_block_header,
272                    args.last_start_period,
273                    args.chain_id,
274                ),
275                args.chain_id,
276            ),
277            op_ids_deserializer: OperationIdsDeserializer::new(args.max_operations_per_block),
278            op_id_serializer: OperationIdSerializer::new(),
279        }
280    }
281}
282
283impl Deserializer<Block> for BlockDeserializer {
284    /// ## Example:
285    /// ```rust
286    /// use massa_models::{block::{Block, BlockSerializer, BlockDeserializer, BlockDeserializerArgs}, config::THREAD_COUNT, slot::Slot, endorsement::{Endorsement, EndorsementSerializer}, secure_share::SecureShareContent, prehash::PreHashSet};
287    /// use massa_models::block_id::BlockId;
288    /// use massa_models::block_header::{BlockHeader, BlockHeaderSerializer};
289    /// use massa_hash::Hash;
290    /// use massa_models::config::CHAINID;
291    /// use massa_signature::KeyPair;
292    /// use massa_models::operation::{compute_operations_hash, OperationIdSerializer};
293    /// use massa_serialization::{Serializer, Deserializer, DeserializeError};
294    /// let keypair = KeyPair::generate(0).unwrap();
295    /// let parents: Vec<BlockId> = (0..THREAD_COUNT)
296    ///     .map(|i| BlockId::generate_from_hash(Hash::compute_from(&[i])))
297    ///     .collect();
298    ///
299    /// // create block header
300    /// let orig_header = BlockHeader::new_verifiable(
301    ///     BlockHeader {
302    ///         current_version: 0,
303    ///         announced_version: None,
304    ///         slot: Slot::new(1, 1),
305    ///         parents: parents.clone(),
306    ///         operation_merkle_root: compute_operations_hash(&[], &OperationIdSerializer::new()),
307    ///         endorsements: vec![
308    ///             Endorsement::new_verifiable(
309    ///                 Endorsement {
310    ///                     slot: Slot::new(1, 1),
311    ///                     index: 0,
312    ///                     endorsed_block: parents[1].clone(),
313    ///                 },
314    ///                 EndorsementSerializer::new(),
315    ///                 &keypair,
316    ///                 *CHAINID
317    ///             )
318    ///             .unwrap(),
319    ///             Endorsement::new_verifiable(
320    ///                 Endorsement {
321    ///                     slot: Slot::new(1, 1),
322    ///                     index: 1,
323    ///                     endorsed_block: parents[1].clone(),
324    ///                 },
325    ///                 EndorsementSerializer::new(),
326    ///                 &keypair,
327    ///                 *CHAINID
328    ///             )
329    ///             .unwrap(),
330    ///         ],
331    ///         denunciations: Vec::new(),
332    ///     },
333    ///     BlockHeaderSerializer::new(),
334    ///     &keypair,
335    ///     *CHAINID
336    /// )
337    /// .unwrap();
338    ///
339    /// // create block
340    /// let orig_block = Block {
341    ///     header: orig_header,
342    ///     operations: Vec::new(),
343    /// };
344    ///
345    /// let mut buffer = Vec::new();
346    /// BlockSerializer::new().serialize(&orig_block, &mut buffer).unwrap();
347    /// let args = BlockDeserializerArgs {
348    ///     thread_count: THREAD_COUNT,
349    ///     max_operations_per_block: 100,
350    ///     endorsement_count: 9,
351    ///     max_denunciations_per_block_header: 10,
352    ///     last_start_period: Some(0),
353    ///     chain_id: *CHAINID
354    /// };
355    /// let (rest, res_block) = BlockDeserializer::new(args).deserialize::<DeserializeError>(&mut buffer).unwrap();
356    ///
357    /// assert!(rest.is_empty());
358    /// // check equality
359    /// assert_eq!(orig_block.header.id, res_block.header.id);
360    /// assert_eq!(
361    ///     orig_block.header.content.slot,
362    ///     res_block.header.content.slot
363    /// );
364    /// assert_eq!(
365    ///     orig_block.header.serialized_data,
366    ///     res_block.header.serialized_data
367    /// );
368    /// assert_eq!(
369    ///     orig_block.header.signature,
370    ///     res_block.header.signature
371    /// );
372    /// ```
373    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
374        &self,
375        buffer: &'a [u8],
376    ) -> IResult<&'a [u8], Block, E> {
377        let (rest, (header, operations)) = context(
378            "Failed Block deserialization",
379            tuple((
380                context("Failed header deserialization", |input| {
381                    self.header_deserializer.deserialize(input)
382                }),
383                context("Failed operations deserialization", |input| {
384                    self.op_ids_deserializer.deserialize(input)
385                }),
386            )),
387        )
388        .parse(buffer)?;
389
390        let computed_operations_hash = compute_operations_hash(&operations, &self.op_id_serializer);
391
392        if header.content.operation_merkle_root != computed_operations_hash {
393            return Err(nom::Err::Failure(ContextError::add_context(
394                rest,
395                "operation list hash does not match header operation_merkle_root",
396                ParseError::from_error_kind(rest, nom::error::ErrorKind::Verify),
397            )));
398        }
399
400        Ok((rest, Block { header, operations }))
401    }
402}
403
404impl SecureShareBlock {
405    /// size in bytes of the whole block
406    pub fn bytes_count(&self) -> u64 {
407        self.serialized_data.len() as u64
408    }
409
410    /// true if given operation is included in the block
411    pub fn contains_operation(&self, op: SecureShareOperation) -> bool {
412        self.content.operations.contains(&op.id)
413    }
414
415    /// returns the fitness of the block
416    pub fn get_fitness(&self) -> u64 {
417        self.content.header.get_fitness()
418    }
419}
420
421impl std::fmt::Display for Block {
422    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
423        writeln!(f, "{}", self.header)?;
424        writeln!(
425            f,
426            "Operations: {}",
427            self.operations
428                .iter()
429                .map(|op| format!("{}", op))
430                .collect::<Vec<String>>()
431                .join(" ")
432        )?;
433        Ok(())
434    }
435}
436
437// NOTE: TODO
438// impl Signable<BlockId> for BlockHeader {
439//     fn get_signature_message(&self) -> Result<Hash, ModelsError> {
440//         let hash = self.compute_hash()?;
441//         let mut res = [0u8; SLOT_KEY_SIZE + BLOCK_ID_SIZE_BYTES];
442//         res[..SLOT_KEY_SIZE].copy_from_slice(&self.slot.to_bytes_key());
443//         res[SLOT_KEY_SIZE..].copy_from_slice(hash.to_bytes());
444//         // rehash for safety
445//         Ok(Hash::compute_from(&res))
446//     }
447// }
448
449/// Block status within the graph
450#[derive(Eq, PartialEq, Debug, Deserialize, Serialize)]
451pub enum BlockGraphStatus {
452    /// received but not yet graph-processed
453    Incoming,
454    /// waiting for its slot
455    WaitingForSlot,
456    /// waiting for a missing dependency
457    WaitingForDependencies,
458    /// active in alternative cliques
459    ActiveInAlternativeCliques,
460    /// active in blockclique
461    ActiveInBlockclique,
462    /// forever applies
463    Final,
464    /// discarded for any reason
465    Discarded,
466    /// not found in graph
467    NotFound,
468}
469
470#[cfg(test)]
471mod test {
472    use super::*;
473    use crate::config::{CHAINID, MAX_DENUNCIATIONS_PER_BLOCK_HEADER};
474    use crate::{
475        block_header::BlockHeaderSerializer,
476        config::{ENDORSEMENT_COUNT, MAX_OPERATIONS_PER_BLOCK, THREAD_COUNT},
477        endorsement::Endorsement,
478        endorsement::EndorsementSerializer,
479        slot::Slot,
480    };
481    use massa_hash::Hash;
482    use massa_serialization::{DeserializeError, Deserializer, Serializer};
483    use massa_signature::KeyPair;
484    use serde_json::Value;
485    use serial_test::serial;
486    use std::str::FromStr;
487
488    fn empty_operations_merkle_root() -> Hash {
489        compute_operations_hash(&[], &OperationIdSerializer::new())
490    }
491
492    #[test]
493    #[serial]
494    fn test_block_serialization() {
495        let keypair =
496            KeyPair::from_str("S1bXjyPwrssNmG4oUG5SEqaUhQkVArQi7rzQDWpCprTSmEgZDGG").unwrap();
497        let parents = (0..THREAD_COUNT)
498            .map(|_i| {
499                BlockId::generate_from_hash(
500                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
501                        .unwrap(),
502                )
503            })
504            .collect();
505
506        let endo1 = Endorsement::new_verifiable(
507            Endorsement {
508                slot: Slot::new(1, 0),
509                index: 0,
510                endorsed_block: BlockId::generate_from_hash(
511                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
512                        .unwrap(),
513                ),
514            },
515            EndorsementSerializer::new(),
516            &keypair,
517            *CHAINID,
518        )
519        .unwrap();
520        let endo2 = Endorsement::new_verifiable(
521            Endorsement {
522                slot: Slot::new(1, 0),
523                index: ENDORSEMENT_COUNT - 1,
524                endorsed_block: BlockId::generate_from_hash(
525                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
526                        .unwrap(),
527                ),
528            },
529            EndorsementSerializer::new(),
530            &keypair,
531            *CHAINID,
532        )
533        .unwrap();
534
535        // create block header
536        let orig_header = BlockHeader::new_verifiable(
537            BlockHeader {
538                current_version: 0,
539                announced_version: None,
540                slot: Slot::new(1, 0),
541                parents,
542                operation_merkle_root: empty_operations_merkle_root(),
543                endorsements: vec![endo1, endo2],
544                denunciations: Vec::new(), // FIXME
545            },
546            BlockHeaderSerializer::new(),
547            &keypair,
548            *CHAINID,
549        )
550        .unwrap();
551
552        // create block
553        let orig_block = Block {
554            header: orig_header.clone(),
555            operations: Default::default(),
556        };
557
558        // serialize block
559        let secured_block: SecureShareBlock = Block::new_verifiable(
560            orig_block.clone(),
561            BlockSerializer::new(),
562            &keypair,
563            *CHAINID,
564        )
565        .unwrap();
566        let mut ser_block = Vec::new();
567        SecureShareSerializer::new()
568            .serialize(&secured_block, &mut ser_block)
569            .unwrap();
570
571        // deserialize
572        let args = BlockDeserializerArgs {
573            thread_count: THREAD_COUNT,
574            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
575            endorsement_count: ENDORSEMENT_COUNT,
576            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
577            last_start_period: Some(0),
578            chain_id: *CHAINID,
579        };
580        let (rest, res_block): (&[u8], SecureShareBlock) =
581            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
582                .deserialize::<DeserializeError>(&ser_block)
583                .unwrap();
584
585        assert!(rest.is_empty());
586        // check equality
587        assert_eq!(orig_block.header.id, res_block.content.header.id);
588        assert_eq!(orig_block.header.id, res_block.id);
589        assert_eq!(
590            orig_block.header.content.slot,
591            res_block.content.header.content.slot
592        );
593        assert_eq!(
594            orig_block.header.serialized_data,
595            res_block.content.header.serialized_data
596        );
597        assert_eq!(
598            orig_block.header.signature,
599            res_block.content.header.signature
600        );
601
602        assert_eq!(
603            orig_block.header.content.endorsements,
604            res_block.content.header.content.endorsements
605        );
606
607        assert_eq!(orig_block.header.signature, res_block.signature);
608        res_block.verify_signature().unwrap();
609        for ed in orig_block.header.content.endorsements.iter() {
610            ed.verify_signature().unwrap();
611        }
612
613        res_block
614            .content
615            .header
616            .assert_invariants(THREAD_COUNT, ENDORSEMENT_COUNT)
617            .unwrap();
618    }
619
620    #[test]
621    #[serial]
622    fn test_block_deserialization_merkle_root_mismatch() {
623        let keypair = KeyPair::generate(0).unwrap();
624        let parents: Vec<BlockId> = (0..THREAD_COUNT)
625            .map(|i| BlockId::generate_from_hash(Hash::compute_from(&[i])))
626            .collect();
627
628        let orig_header = BlockHeader::new_verifiable(
629            BlockHeader {
630                current_version: 0,
631                announced_version: None,
632                slot: Slot::new(1, 0),
633                parents,
634                operation_merkle_root: Hash::compute_from("mno".as_bytes()),
635                endorsements: vec![],
636                denunciations: Vec::new(),
637            },
638            BlockHeaderSerializer::new(),
639            &keypair,
640            *CHAINID,
641        )
642        .unwrap();
643
644        let orig_block = Block {
645            header: orig_header,
646            operations: Default::default(),
647        };
648
649        let secured_block: SecureShareBlock =
650            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
651        let mut ser_block = Vec::new();
652        SecureShareSerializer::new()
653            .serialize(&secured_block, &mut ser_block)
654            .unwrap();
655
656        let args = BlockDeserializerArgs {
657            thread_count: THREAD_COUNT,
658            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
659            endorsement_count: ENDORSEMENT_COUNT,
660            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
661            last_start_period: Some(0),
662            chain_id: *CHAINID,
663        };
664        let res: Result<(&[u8], SecureShareBlock), _> =
665            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
666                .deserialize::<DeserializeError>(&ser_block);
667
668        assert!(res.is_err());
669    }
670
671    #[test]
672    #[serial]
673    fn test_genesis_block_serialization() {
674        let keypair = KeyPair::generate(0).unwrap();
675        let parents: Vec<BlockId> = vec![];
676
677        // create block header
678        let orig_header = BlockHeader::new_verifiable(
679            BlockHeader {
680                current_version: 0,
681                announced_version: None,
682                slot: Slot::new(0, 1),
683                parents,
684                operation_merkle_root: empty_operations_merkle_root(),
685                endorsements: vec![],
686                denunciations: vec![],
687            },
688            BlockHeaderSerializer::new(),
689            &keypair,
690            *CHAINID,
691        )
692        .unwrap();
693
694        // create block
695        let orig_block = Block {
696            header: orig_header,
697            operations: Default::default(),
698        };
699
700        // serialize block
701        let secured_block: SecureShareBlock = Block::new_verifiable(
702            orig_block.clone(),
703            BlockSerializer::new(),
704            &keypair,
705            *CHAINID,
706        )
707        .unwrap();
708        let mut ser_block = Vec::new();
709        SecureShareSerializer::new()
710            .serialize(&secured_block, &mut ser_block)
711            .unwrap();
712
713        // deserialize
714        let args = BlockDeserializerArgs {
715            thread_count: THREAD_COUNT,
716            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
717            endorsement_count: ENDORSEMENT_COUNT,
718            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
719            last_start_period: Some(0),
720            chain_id: *CHAINID,
721        };
722        let (rest, res_block): (&[u8], SecureShareBlock) =
723            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
724                .deserialize::<DeserializeError>(&ser_block)
725                .unwrap();
726
727        res_block
728            .content
729            .header
730            .assert_invariants(THREAD_COUNT, ENDORSEMENT_COUNT)
731            .unwrap();
732
733        // check equality
734
735        assert!(rest.is_empty());
736        assert_eq!(orig_block.header.id, res_block.content.header.id);
737        // assert_eq!(orig_block.header.id, res_block.id);
738        assert_eq!(
739            orig_block.header.content.slot,
740            res_block.content.header.content.slot
741        );
742        assert_eq!(
743            orig_block.header.serialized_data,
744            res_block.content.header.serialized_data
745        );
746        assert_eq!(
747            orig_block.header.signature,
748            res_block.content.header.signature
749        );
750
751        assert_eq!(
752            orig_block.header.content.endorsements,
753            res_block.content.header.content.endorsements
754        );
755
756        assert_eq!(orig_block.header.signature, res_block.signature);
757    }
758
759    #[test]
760    #[serial]
761    fn test_invalid_genesis_block_serialization_with_endorsements() {
762        let keypair = KeyPair::generate(0).unwrap();
763        let parents: Vec<BlockId> = vec![];
764
765        // Genesis block do not have any parents and thus cannot embed endorsements
766        let endorsement = Endorsement {
767            slot: Slot::new(0, 1),
768            index: 1,
769            endorsed_block: BlockId::generate_from_hash(Hash::compute_from(&[1])),
770        };
771
772        // create block header
773        let orig_header = BlockHeader::new_verifiable(
774            BlockHeader {
775                current_version: 0,
776                announced_version: None,
777                slot: Slot::new(0, 1),
778                parents,
779                operation_merkle_root: empty_operations_merkle_root(),
780                endorsements: vec![Endorsement::new_verifiable(
781                    endorsement,
782                    EndorsementSerializer::new(),
783                    &keypair,
784                    *CHAINID,
785                )
786                .unwrap()],
787                denunciations: vec![],
788            },
789            BlockHeaderSerializer::new(),
790            &keypair,
791            *CHAINID,
792        )
793        .unwrap();
794
795        // create block
796        let orig_block = Block {
797            header: orig_header,
798            operations: Default::default(),
799        };
800
801        // serialize block
802        let secured_block: SecureShareBlock =
803            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
804        let mut ser_block = Vec::new();
805        SecureShareSerializer::new()
806            .serialize(&secured_block, &mut ser_block)
807            .unwrap();
808
809        // deserialize
810        let args = BlockDeserializerArgs {
811            thread_count: THREAD_COUNT,
812            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
813            endorsement_count: ENDORSEMENT_COUNT,
814            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
815            last_start_period: Some(0),
816            chain_id: *CHAINID,
817        };
818        let res: Result<(&[u8], SecureShareBlock), _> =
819            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
820                .deserialize::<DeserializeError>(&ser_block);
821
822        // TODO: Catch an failed deser being a fail, instead of a recoverable error
823        // TODO: assert that the error variant/context/etc. matches the expected failure
824        assert!(res.is_err());
825        // let nom::Err::Failure(_) = res.unwrap_err() else {
826        //     panic!("Deserialisation with invalid endorsements should be total fail");
827        // };
828    }
829    #[test]
830    #[serial]
831    fn test_invalid_genesis_block_serialization_with_parents() {
832        let keypair = KeyPair::generate(0).unwrap();
833        let parents = (0..THREAD_COUNT)
834            .map(|i| BlockId::generate_from_hash(Hash::compute_from(&[i])))
835            .collect();
836
837        // create block header
838        let orig_header = BlockHeader::new_verifiable(
839            BlockHeader {
840                current_version: 0,
841                announced_version: None,
842                slot: Slot::new(0, 1),
843                parents,
844                operation_merkle_root: empty_operations_merkle_root(),
845                endorsements: vec![],
846                denunciations: vec![],
847            },
848            BlockHeaderSerializer::new(),
849            &keypair,
850            *CHAINID,
851        )
852        .unwrap();
853
854        // create block
855        let orig_block = Block {
856            header: orig_header,
857            operations: Default::default(),
858        };
859
860        // serialize block
861        let secured_block: SecureShareBlock =
862            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
863        let mut ser_block = Vec::new();
864        SecureShareSerializer::new()
865            .serialize(&secured_block, &mut ser_block)
866            .unwrap();
867
868        // deserialize
869        let args = BlockDeserializerArgs {
870            thread_count: THREAD_COUNT,
871            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
872            endorsement_count: ENDORSEMENT_COUNT,
873            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
874            last_start_period: Some(0),
875            chain_id: *CHAINID,
876        };
877        let res: Result<(&[u8], SecureShareBlock), _> =
878            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
879                .deserialize::<DeserializeError>(&ser_block);
880
881        // TODO: Catch an failed deser being a fail, instead of a recoverable error
882        // TODO: assert that the error variant/context/etc. matches the expected failure
883        assert!(res.is_err());
884    }
885    #[test]
886    #[serial]
887    fn test_invalid_block_serialization_no_parents() {
888        let keypair = KeyPair::generate(0).unwrap();
889        // Non genesis block must have THREAD_COUNT parents
890
891        // create block header
892        let orig_header = BlockHeader::new_verifiable(
893            BlockHeader {
894                current_version: 0,
895                announced_version: None,
896                slot: Slot::new(1, 1),
897                parents: vec![],
898                operation_merkle_root: empty_operations_merkle_root(),
899                endorsements: vec![],
900                denunciations: vec![],
901            },
902            BlockHeaderSerializer::new(),
903            &keypair,
904            *CHAINID,
905        )
906        .unwrap();
907
908        // create block
909        let orig_block = Block {
910            header: orig_header,
911            operations: Default::default(),
912        };
913
914        // serialize block
915        let secured_block: SecureShareBlock =
916            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
917        let mut ser_block = Vec::new();
918        SecureShareSerializer::new()
919            .serialize(&secured_block, &mut ser_block)
920            .unwrap();
921
922        // deserialize
923        let args = BlockDeserializerArgs {
924            thread_count: THREAD_COUNT,
925            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
926            endorsement_count: ENDORSEMENT_COUNT,
927            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
928            last_start_period: Some(0),
929            chain_id: *CHAINID,
930        };
931        let res: Result<(&[u8], SecureShareBlock), _> =
932            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
933                .deserialize::<DeserializeError>(&ser_block);
934
935        // TODO: Catch an failed deser being a fail, instead of a recoverable error
936        // TODO: assert that the error variant/context/etc. matches the expected failure
937        assert!(res.is_err());
938    }
939    #[test]
940    #[serial]
941    fn test_invalid_block_serialization_obo_high_parent_count() {
942        let keypair = KeyPair::generate(0).unwrap();
943        // Non genesis block must have THREAD_COUNT parents
944        let parents = (0..=THREAD_COUNT)
945            .map(|i| BlockId::generate_from_hash(Hash::compute_from(&[i])))
946            .collect();
947
948        // create block header
949        let orig_header = BlockHeader::new_verifiable(
950            BlockHeader {
951                current_version: 0,
952                announced_version: None,
953                slot: Slot::new(1, 1),
954                parents,
955                operation_merkle_root: empty_operations_merkle_root(),
956                endorsements: vec![],
957                denunciations: vec![],
958            },
959            BlockHeaderSerializer::new(),
960            &keypair,
961            *CHAINID,
962        )
963        .unwrap();
964
965        // create block
966        let orig_block = Block {
967            header: orig_header,
968            operations: Default::default(),
969        };
970
971        // serialize block
972        let secured_block: SecureShareBlock =
973            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
974        let mut ser_block = Vec::new();
975        SecureShareSerializer::new()
976            .serialize(&secured_block, &mut ser_block)
977            .unwrap();
978
979        // deserialize
980        let args = BlockDeserializerArgs {
981            thread_count: THREAD_COUNT,
982            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
983            endorsement_count: ENDORSEMENT_COUNT,
984            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
985            last_start_period: Some(0),
986            chain_id: *CHAINID,
987        };
988        let res: Result<(&[u8], SecureShareBlock), _> =
989            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
990                .deserialize::<DeserializeError>(&ser_block);
991
992        // TODO: Catch an failed deser being a fail, instead of a recoverable error
993        // TODO: assert that the error variant/context/etc. matches the expected failure
994        assert!(res.is_err());
995    }
996
997    #[test]
998    #[serial]
999    fn test_block_serialization_max_endo_count() {
1000        let keypair =
1001            KeyPair::from_str("S1bXjyPwrssNmG4oUG5SEqaUhQkVArQi7rzQDWpCprTSmEgZDGG").unwrap();
1002        let endorsed = BlockId::generate_from_hash(
1003            Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf").unwrap(),
1004        );
1005        let fillers =
1006            (1..THREAD_COUNT).map(|i| BlockId::generate_from_hash(Hash::compute_from(&[i])));
1007        let parents = std::iter::once(endorsed).chain(fillers).collect();
1008
1009        let endorsements = (0..ENDORSEMENT_COUNT)
1010            .map(|i| {
1011                Endorsement::new_verifiable(
1012                    Endorsement {
1013                        slot: Slot::new(1, 0),
1014                        index: i,
1015                        endorsed_block: BlockId::generate_from_hash(
1016                            Hash::from_bs58_check(
1017                                "bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf",
1018                            )
1019                            .unwrap(),
1020                        ),
1021                    },
1022                    EndorsementSerializer::new(),
1023                    &keypair,
1024                    *CHAINID,
1025                )
1026                .unwrap()
1027            })
1028            .collect();
1029        // create block header
1030        let orig_header = BlockHeader::new_verifiable(
1031            BlockHeader {
1032                current_version: 0,
1033                announced_version: None,
1034                slot: Slot::new(1, 0),
1035                parents,
1036                operation_merkle_root: empty_operations_merkle_root(),
1037                endorsements,
1038                denunciations: vec![],
1039            },
1040            BlockHeaderSerializer::new(),
1041            &keypair,
1042            *CHAINID,
1043        )
1044        .unwrap();
1045
1046        // create block
1047        let orig_block = Block {
1048            header: orig_header,
1049            operations: Default::default(),
1050        };
1051
1052        // serialize block
1053        let secured_block: SecureShareBlock =
1054            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
1055        let mut ser_block = Vec::new();
1056        SecureShareSerializer::new()
1057            .serialize(&secured_block, &mut ser_block)
1058            .unwrap();
1059
1060        // deserialize
1061        let args = BlockDeserializerArgs {
1062            thread_count: THREAD_COUNT,
1063            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
1064            endorsement_count: ENDORSEMENT_COUNT,
1065            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
1066            last_start_period: Some(0),
1067            chain_id: *CHAINID,
1068        };
1069        let (_, res): (&[u8], SecureShareBlock) =
1070            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
1071                .deserialize::<DeserializeError>(&ser_block)
1072                .unwrap();
1073
1074        res.content
1075            .header
1076            .assert_invariants(THREAD_COUNT, ENDORSEMENT_COUNT)
1077            .unwrap();
1078    }
1079    #[test]
1080    #[serial]
1081    fn test_invalid_block_serialization_obo_low_parent_count() {
1082        let keypair = KeyPair::generate(0).unwrap();
1083        // Non genesis block must have THREAD_COUNT parents
1084        let parents = (1..THREAD_COUNT)
1085            .map(|i| BlockId::generate_from_hash(Hash::compute_from(&[i])))
1086            .collect();
1087
1088        // create block header
1089        let orig_header = BlockHeader::new_verifiable(
1090            BlockHeader {
1091                current_version: 0,
1092                announced_version: None,
1093                slot: Slot::new(1, 1),
1094                parents,
1095                operation_merkle_root: empty_operations_merkle_root(),
1096                endorsements: vec![],
1097                denunciations: vec![],
1098            },
1099            BlockHeaderSerializer::new(),
1100            &keypair,
1101            *CHAINID,
1102        )
1103        .unwrap();
1104
1105        // create block
1106        let orig_block = Block {
1107            header: orig_header,
1108            operations: Default::default(),
1109        };
1110
1111        // serialize block
1112        let secured_block: SecureShareBlock =
1113            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
1114        let mut ser_block = Vec::new();
1115        SecureShareSerializer::new()
1116            .serialize(&secured_block, &mut ser_block)
1117            .unwrap();
1118
1119        // deserialize
1120        let args = BlockDeserializerArgs {
1121            thread_count: THREAD_COUNT,
1122            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
1123            endorsement_count: ENDORSEMENT_COUNT,
1124            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
1125            last_start_period: Some(0),
1126            chain_id: *CHAINID,
1127        };
1128        let res: Result<(&[u8], SecureShareBlock), _> =
1129            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
1130                .deserialize::<DeserializeError>(&ser_block);
1131
1132        // TODO: Catch an failed deser being a fail, instead of a recoverable error
1133        // TODO: assert that the error variant/context/etc. matches the expected failure
1134        assert!(res.is_err());
1135    }
1136    #[test]
1137    #[serial]
1138    fn test_invalid_block_serialization_obo_high_endo_count() {
1139        let keypair = KeyPair::generate(0).unwrap();
1140        // Non genesis block must have THREAD_COUNT parents
1141        let parents = (0..THREAD_COUNT)
1142            .map(|i| BlockId::generate_from_hash(Hash::compute_from(&[i])))
1143            .collect();
1144
1145        let endorsements = (0..=ENDORSEMENT_COUNT)
1146            .map(|i| {
1147                Endorsement::new_verifiable(
1148                    Endorsement {
1149                        slot: Slot::new(0, 1),
1150                        index: i,
1151                        endorsed_block: BlockId::generate_from_hash(Hash::compute_from(&[i as u8])),
1152                    },
1153                    EndorsementSerializer::new(),
1154                    &keypair,
1155                    *CHAINID,
1156                )
1157                .unwrap()
1158            })
1159            .collect();
1160        // create block header
1161        let orig_header = BlockHeader::new_verifiable(
1162            BlockHeader {
1163                current_version: 0,
1164                announced_version: None,
1165                slot: Slot::new(1, 1),
1166                parents,
1167                operation_merkle_root: empty_operations_merkle_root(),
1168                endorsements,
1169                denunciations: vec![],
1170            },
1171            BlockHeaderSerializer::new(),
1172            &keypair,
1173            *CHAINID,
1174        )
1175        .unwrap();
1176
1177        // create block
1178        let orig_block = Block {
1179            header: orig_header,
1180            operations: Default::default(),
1181        };
1182
1183        // serialize block
1184        let secured_block: SecureShareBlock =
1185            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
1186        let mut ser_block = Vec::new();
1187        SecureShareSerializer::new()
1188            .serialize(&secured_block, &mut ser_block)
1189            .unwrap();
1190
1191        // deserialize
1192        let args = BlockDeserializerArgs {
1193            thread_count: THREAD_COUNT,
1194            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
1195            endorsement_count: ENDORSEMENT_COUNT,
1196            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
1197            last_start_period: Some(0),
1198            chain_id: *CHAINID,
1199        };
1200        let res: Result<(&[u8], SecureShareBlock), _> =
1201            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
1202                .deserialize::<DeserializeError>(&ser_block);
1203
1204        // TODO: Catch an failed deser being a fail, instead of a recoverable error
1205        // TODO: see issue #3400
1206        assert!(res.is_err());
1207    }
1208    #[test]
1209    #[serial]
1210    fn test_invalid_endorsement_idx() {
1211        let keypair =
1212            KeyPair::from_str("S1bXjyPwrssNmG4oUG5SEqaUhQkVArQi7rzQDWpCprTSmEgZDGG").unwrap();
1213        let parents = (0..THREAD_COUNT)
1214            .map(|_i| {
1215                BlockId::generate_from_hash(
1216                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
1217                        .unwrap(),
1218                )
1219            })
1220            .collect();
1221
1222        let endo1 = Endorsement::new_verifiable(
1223            Endorsement {
1224                slot: Slot::new(1, 0),
1225                index: ENDORSEMENT_COUNT,
1226                endorsed_block: BlockId::generate_from_hash(
1227                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
1228                        .unwrap(),
1229                ),
1230            },
1231            EndorsementSerializer::new(),
1232            &keypair,
1233            *CHAINID,
1234        )
1235        .unwrap();
1236
1237        // create block header
1238        let orig_header = BlockHeader::new_verifiable(
1239            BlockHeader {
1240                current_version: 0,
1241                announced_version: None,
1242                slot: Slot::new(1, 0),
1243                parents,
1244                operation_merkle_root: empty_operations_merkle_root(),
1245                endorsements: vec![endo1],
1246                denunciations: vec![],
1247            },
1248            BlockHeaderSerializer::new(),
1249            &keypair,
1250            *CHAINID,
1251        )
1252        .unwrap();
1253
1254        // create block
1255        let orig_block = Block {
1256            header: orig_header,
1257            operations: Default::default(),
1258        };
1259
1260        // serialize block
1261        let secured_block: SecureShareBlock =
1262            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
1263        let mut ser_block = Vec::new();
1264        SecureShareSerializer::new()
1265            .serialize(&secured_block, &mut ser_block)
1266            .unwrap();
1267
1268        // deserialize
1269        let args = BlockDeserializerArgs {
1270            thread_count: THREAD_COUNT,
1271            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
1272            endorsement_count: ENDORSEMENT_COUNT,
1273            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
1274            last_start_period: Some(0),
1275            chain_id: *CHAINID,
1276        };
1277        let res: Result<(&[u8], SecureShareBlock), _> =
1278            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
1279                .deserialize::<DeserializeError>(&ser_block);
1280        // TODO: Catch an failed deser being a fail, instead of a recoverable error
1281        // TODO: assert that the error variant/context/etc. matches the expected failure
1282        assert!(res.is_err());
1283    }
1284    #[test]
1285    #[serial]
1286    fn test_invalid_dupe_endo_idx() {
1287        let keypair =
1288            KeyPair::from_str("S1bXjyPwrssNmG4oUG5SEqaUhQkVArQi7rzQDWpCprTSmEgZDGG").unwrap();
1289        let parents = (0..THREAD_COUNT)
1290            .map(|_i| {
1291                BlockId::generate_from_hash(
1292                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
1293                        .unwrap(),
1294                )
1295            })
1296            .collect();
1297
1298        let endo1 = Endorsement::new_verifiable(
1299            Endorsement {
1300                slot: Slot::new(1, 0),
1301                index: 0,
1302                endorsed_block: BlockId::generate_from_hash(
1303                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
1304                        .unwrap(),
1305                ),
1306            },
1307            EndorsementSerializer::new(),
1308            &keypair,
1309            *CHAINID,
1310        )
1311        .unwrap();
1312        let endo2 = Endorsement::new_verifiable(
1313            Endorsement {
1314                slot: Slot::new(1, 0),
1315                index: 0,
1316                endorsed_block: BlockId::generate_from_hash(
1317                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
1318                        .unwrap(),
1319                ),
1320            },
1321            EndorsementSerializer::new(),
1322            &keypair,
1323            *CHAINID,
1324        )
1325        .unwrap();
1326
1327        // create block header
1328        let orig_header = BlockHeader::new_verifiable(
1329            BlockHeader {
1330                current_version: 0,
1331                announced_version: None,
1332                slot: Slot::new(1, 0),
1333                parents,
1334                operation_merkle_root: empty_operations_merkle_root(),
1335                endorsements: vec![endo1, endo2],
1336                denunciations: vec![],
1337            },
1338            BlockHeaderSerializer::new(),
1339            &keypair,
1340            *CHAINID,
1341        )
1342        .unwrap();
1343
1344        // create block
1345        let orig_block = Block {
1346            header: orig_header,
1347            operations: Default::default(),
1348        };
1349
1350        // serialize block
1351        let secured_block: SecureShareBlock =
1352            Block::new_verifiable(orig_block, BlockSerializer::new(), &keypair, *CHAINID).unwrap();
1353        let mut ser_block = Vec::new();
1354        SecureShareSerializer::new()
1355            .serialize(&secured_block, &mut ser_block)
1356            .unwrap();
1357
1358        // deserialize
1359        let args = BlockDeserializerArgs {
1360            thread_count: THREAD_COUNT,
1361            max_operations_per_block: MAX_OPERATIONS_PER_BLOCK,
1362            endorsement_count: ENDORSEMENT_COUNT,
1363            max_denunciations_per_block_header: MAX_DENUNCIATIONS_PER_BLOCK_HEADER,
1364            last_start_period: Some(0),
1365            chain_id: *CHAINID,
1366        };
1367        let res: Result<(&[u8], SecureShareBlock), _> =
1368            SecureShareDeserializer::new(BlockDeserializer::new(args), *CHAINID)
1369                .deserialize::<DeserializeError>(&ser_block);
1370
1371        // TODO: Catch an failed deser being a fail, instead of a recoverable error
1372        // TODO: assert that the error variant/context/etc. matches the expected failure
1373        assert!(res.is_err());
1374    }
1375
1376    #[test]
1377    #[serial]
1378    fn test_block_serde() {
1379        let keypair =
1380            KeyPair::from_str("S1bXjyPwrssNmG4oUG5SEqaUhQkVArQi7rzQDWpCprTSmEgZDGG").unwrap();
1381        let parents = (0..THREAD_COUNT)
1382            .map(|_i| {
1383                BlockId::generate_from_hash(
1384                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
1385                        .unwrap(),
1386                )
1387            })
1388            .collect();
1389
1390        let endo1 = Endorsement::new_verifiable(
1391            Endorsement {
1392                slot: Slot::new(1, 0),
1393                index: 0,
1394                endorsed_block: BlockId::generate_from_hash(
1395                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
1396                        .unwrap(),
1397                ),
1398            },
1399            EndorsementSerializer::new(),
1400            &keypair,
1401            *CHAINID,
1402        )
1403        .unwrap();
1404        let endo2 = Endorsement::new_verifiable(
1405            Endorsement {
1406                slot: Slot::new(1, 0),
1407                index: ENDORSEMENT_COUNT - 1,
1408                endorsed_block: BlockId::generate_from_hash(
1409                    Hash::from_bs58_check("bq1NsaCBAfseMKSjNBYLhpK7M5eeef2m277MYS2P2k424GaDf")
1410                        .unwrap(),
1411                ),
1412            },
1413            EndorsementSerializer::new(),
1414            &keypair,
1415            *CHAINID,
1416        )
1417        .unwrap();
1418
1419        // create block header
1420        let orig_header = BlockHeader::new_verifiable(
1421            BlockHeader {
1422                current_version: 0,
1423                announced_version: None,
1424                slot: Slot::new(1, 0),
1425                parents,
1426                operation_merkle_root: empty_operations_merkle_root(),
1427                endorsements: vec![endo1, endo2],
1428                denunciations: Vec::new(), // FIXME
1429            },
1430            BlockHeaderSerializer::new(),
1431            &keypair,
1432            *CHAINID,
1433        )
1434        .unwrap();
1435
1436        // create block
1437        let orig_block = Block {
1438            header: orig_header.clone(),
1439            operations: Default::default(),
1440        };
1441
1442        let serialized_block = serde_json::to_string(&orig_block).unwrap();
1443        let res_block: Value = serde_json::from_str(&serialized_block).unwrap();
1444        // check equality
1445        assert_eq!(orig_block.header.id.to_string(), res_block["header"]["id"]);
1446        assert_eq!(
1447            orig_block.header.signature.to_string(),
1448            res_block["header"]["signature"]
1449        );
1450    }
1451}