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