linera_chain/certificate/
validated.rs

1// Copyright (c) Facebook, Inc. and its affiliates.
2// Copyright (c) Zefchain Labs, Inc.
3// SPDX-License-Identifier: Apache-2.0
4
5use linera_base::{
6    crypto::{ValidatorPublicKey, ValidatorSignature},
7    data_types::Round,
8};
9use serde::{
10    ser::{Serialize, SerializeStruct, Serializer},
11    Deserialize, Deserializer,
12};
13
14use super::{generic::GenericCertificate, Certificate};
15use crate::block::{Block, ConversionError, ValidatedBlock};
16
17impl GenericCertificate<ValidatedBlock> {
18    #[cfg(with_testing)]
19    pub fn outgoing_message_count(&self) -> usize {
20        self.block().messages().iter().map(Vec::len).sum()
21    }
22
23    /// Returns reference to the [`Block`] contained in this certificate.
24    pub fn block(&self) -> &Block {
25        self.inner().block()
26    }
27}
28
29impl TryFrom<Certificate> for GenericCertificate<ValidatedBlock> {
30    type Error = ConversionError;
31
32    fn try_from(cert: Certificate) -> Result<Self, Self::Error> {
33        match cert {
34            Certificate::Validated(validated) => Ok(validated),
35            _ => Err(ConversionError::ValidatedBlock),
36        }
37    }
38}
39
40impl From<GenericCertificate<ValidatedBlock>> for Certificate {
41    fn from(cert: GenericCertificate<ValidatedBlock>) -> Certificate {
42        Certificate::Validated(cert)
43    }
44}
45
46impl Serialize for GenericCertificate<ValidatedBlock> {
47    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
48        let mut state = serializer.serialize_struct("ValidatedBlockCertificate", 3)?;
49        state.serialize_field("value", self.inner())?;
50        state.serialize_field("round", &self.round)?;
51        state.serialize_field("signatures", self.signatures())?;
52        state.end()
53    }
54}
55
56impl<'de> Deserialize<'de> for GenericCertificate<ValidatedBlock> {
57    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
58    where
59        D: Deserializer<'de>,
60    {
61        #[derive(Deserialize)]
62        #[serde(rename = "ValidatedBlockCertificate")]
63        struct Inner {
64            value: ValidatedBlock,
65            round: Round,
66            signatures: Vec<(ValidatorPublicKey, ValidatorSignature)>,
67        }
68        let inner = Inner::deserialize(deserializer)?;
69        if !crate::data_types::is_strictly_ordered(&inner.signatures) {
70            Err(serde::de::Error::custom(
71                "Signatures are not strictly ordered",
72            ))
73        } else {
74            Ok(Self::new(inner.value, inner.round, inner.signatures))
75        }
76    }
77}