Skip to main content

linera_chain/certificate/
timeout.rs

1// Copyright (c) Facebook, Inc. and its affiliates.
2// Copyright (c) Zefchain Labs, Inc.
3// SPDX-License-Identifier: Apache-2.0
4
5use std::borrow::Cow;
6
7use linera_base::{
8    crypto::{ValidatorPublicKey, ValidatorSignature},
9    data_types::Round,
10};
11use serde::{
12    ser::{Serialize, Serializer},
13    Deserialize, Deserializer,
14};
15
16use super::{generic::GenericCertificate, Certificate};
17use crate::block::{ConversionError, Timeout};
18
19/// The serialized representation of a [`TimeoutCertificate`](super::TimeoutCertificate). Deriving
20/// the (de)serialization on this single type keeps both directions in sync and free of manual
21/// field bookkeeping; the manual impls only add the strictly-ordered-signatures invariant.
22#[derive(serde::Serialize, serde::Deserialize)]
23#[serde(rename = "TimeoutCertificate")]
24struct Repr<'a> {
25    value: Cow<'a, Timeout>,
26    round: Round,
27    signatures: Cow<'a, [(ValidatorPublicKey, ValidatorSignature)]>,
28}
29
30impl TryFrom<Certificate> for GenericCertificate<Timeout> {
31    type Error = ConversionError;
32
33    fn try_from(cert: Certificate) -> Result<Self, Self::Error> {
34        match cert {
35            Certificate::Timeout(timeout) => Ok(timeout),
36            _ => Err(ConversionError::Timeout),
37        }
38    }
39}
40
41impl From<GenericCertificate<Timeout>> for Certificate {
42    fn from(cert: GenericCertificate<Timeout>) -> Certificate {
43        Certificate::Timeout(cert)
44    }
45}
46
47impl Serialize for GenericCertificate<Timeout> {
48    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
49        Repr {
50            value: Cow::Borrowed(self.inner()),
51            round: self.round(),
52            signatures: Cow::Borrowed(self.signatures().as_slice()),
53        }
54        .serialize(serializer)
55    }
56}
57
58impl<'de> Deserialize<'de> for GenericCertificate<Timeout> {
59    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60    where
61        D: Deserializer<'de>,
62    {
63        let repr = Repr::deserialize(deserializer)?;
64        let signatures = repr.signatures.into_owned();
65        if !crate::data_types::is_strictly_ordered(&signatures) {
66            Err(serde::de::Error::custom("Vector is not strictly sorted"))
67        } else {
68            Ok(Self::new(repr.value.into_owned(), repr.round, signatures))
69        }
70    }
71}