linera_chain/certificate/
confirmed.rs1use linera_base::{
6 crypto::{ValidatorPublicKey, ValidatorSignature},
7 data_types::{Epoch, Round},
8 identifiers::ChainId,
9};
10use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize};
11
12use super::{generic::GenericCertificate, Certificate};
13use crate::{
14 block::{Block, ConfirmedBlock, ConversionError},
15 data_types::MessageBundle,
16};
17
18impl GenericCertificate<ConfirmedBlock> {
19 pub fn block(&self) -> &Block {
21 self.inner().block()
22 }
23
24 pub fn message_bundles_for(
28 &self,
29 recipient: ChainId,
30 ) -> impl Iterator<Item = (Epoch, MessageBundle)> + '_ {
31 let certificate_hash = self.hash();
32 self.block()
33 .message_bundles_for(recipient, certificate_hash)
34 }
35
36 #[cfg(with_testing)]
37 pub fn outgoing_message_count(&self) -> usize {
38 self.block().messages().iter().map(Vec::len).sum()
39 }
40}
41
42impl TryFrom<Certificate> for GenericCertificate<ConfirmedBlock> {
43 type Error = ConversionError;
44
45 fn try_from(cert: Certificate) -> Result<Self, Self::Error> {
46 match cert {
47 Certificate::Confirmed(confirmed) => Ok(confirmed),
48 _ => Err(ConversionError::ConfirmedBlock),
49 }
50 }
51}
52
53impl From<GenericCertificate<ConfirmedBlock>> for Certificate {
54 fn from(cert: GenericCertificate<ConfirmedBlock>) -> Certificate {
55 Certificate::Confirmed(cert)
56 }
57}
58
59impl From<&GenericCertificate<ConfirmedBlock>> for Certificate {
60 fn from(cert: &GenericCertificate<ConfirmedBlock>) -> Certificate {
61 Certificate::Confirmed(cert.clone())
62 }
63}
64
65impl Serialize for GenericCertificate<ConfirmedBlock> {
66 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
67 where
68 S: serde::Serializer,
69 {
70 let mut state = serializer.serialize_struct("ConfirmedBlockCertificate", 3)?;
71 state.serialize_field("value", self.inner())?;
72 state.serialize_field("round", &self.round)?;
73 state.serialize_field("signatures", self.signatures())?;
74 state.end()
75 }
76}
77
78impl<'de> Deserialize<'de> for GenericCertificate<ConfirmedBlock> {
79 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
80 where
81 D: Deserializer<'de>,
82 {
83 #[derive(Debug, Deserialize)]
84 #[serde(rename = "ConfirmedBlockCertificate")]
85 struct Helper {
86 value: ConfirmedBlock,
87 round: Round,
88 signatures: Vec<(ValidatorPublicKey, ValidatorSignature)>,
89 }
90
91 let helper = Helper::deserialize(deserializer)?;
92 if !crate::data_types::is_strictly_ordered(&helper.signatures) {
93 Err(serde::de::Error::custom("Vector is not strictly sorted"))
94 } else {
95 Ok(Self::new(helper.value, helper.round, helper.signatures))
96 }
97 }
98}