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