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