mithril_aggregator/services/certifier/
interface.rs

1use async_trait::async_trait;
2use thiserror::Error;
3
4use mithril_common::entities::{
5    Certificate, Epoch, ProtocolMessage, SignedEntityType, SignedEntityTypeDiscriminants,
6    SingleSignature,
7};
8use mithril_common::{StdError, StdResult};
9
10use crate::entities::OpenMessage;
11
12/// Errors dedicated to the CertifierService.
13#[derive(Debug, Error)]
14pub enum CertifierServiceError {
15    /// OpenMessage not found.
16    #[error("The open message was not found for beacon {0:?}.")]
17    NotFound(SignedEntityType),
18
19    /// The open message is already certified, no more single signatures may be
20    /// attached to it nor be certified again.
21    #[error("Open message for beacon {0:?} already certified.")]
22    AlreadyCertified(SignedEntityType),
23
24    /// The open message is expired, no more single signatures may be
25    /// attached to it nor be certified again.
26    #[error("Open message for beacon {0:?} is expired.")]
27    Expired(SignedEntityType),
28
29    /// An invalid signature was provided.
30    #[error("Invalid single signature for {0:?}.")]
31    InvalidSingleSignature(SignedEntityType, #[source] StdError),
32
33    /// No parent certificate could be found, this certifier cannot create genesis certificates.
34    #[error(
35        "No parent certificate could be found, this certifier cannot create genesis certificates."
36    )]
37    NoParentCertificateFound,
38
39    /// No certificate for this epoch
40    #[error(
41        "There is an epoch gap between the last certificate epoch ({certificate_epoch:?}) and current epoch ({current_epoch:?})"
42    )]
43    CertificateEpochGap {
44        /// Epoch of the last issued certificate
45        certificate_epoch: Epoch,
46
47        /// Given current epoch
48        current_epoch: Epoch,
49    },
50
51    /// Could not verify certificate chain because could not find last certificate.
52    #[error("No certificate found.")]
53    CouldNotFindLastCertificate,
54}
55
56/// Status of a successful registration of a single signature.
57#[derive(Debug, Copy, Clone, PartialEq)]
58pub enum SignatureRegistrationStatus {
59    /// The signature was registered and will be used for the next certificate.
60    Registered,
61
62    /// The signature was buffered, it will be used later.
63    Buffered,
64}
65
66/// ## CertifierService
67///
68/// This service manages the open message and their beacon transitions. It can
69/// ultimately transform open messages into certificates.
70#[cfg_attr(test, mockall::automock)]
71#[async_trait]
72pub trait CertifierService: Sync + Send {
73    /// Inform the certifier I have detected a new epoch, it may clear its state
74    /// and prepare the new signature round. If the given Epoch is equal or less
75    /// than the previous informed Epoch, nothing is done.
76    async fn inform_epoch(&self, epoch: Epoch) -> StdResult<()>;
77
78    /// Add a new single signature for the open message at the given beacon. If
79    /// the open message does not exist or the open message has been certified
80    /// since then, an error is returned.
81    async fn register_single_signature(
82        &self,
83        signed_entity_type: &SignedEntityType,
84        signature: &SingleSignature,
85    ) -> StdResult<SignatureRegistrationStatus>;
86
87    /// Create an open message at the given beacon. If the open message does not
88    /// exist or exists at an older beacon, the older open messages are cleared
89    /// along with their associated single signatures and the new open message
90    /// is created. If the message already exists, an error is returned.
91    async fn create_open_message(
92        &self,
93        signed_entity_type: &SignedEntityType,
94        protocol_message: &ProtocolMessage,
95    ) -> StdResult<OpenMessage>;
96
97    /// Return the open message at the given Beacon. If the message does not
98    /// exist, None is returned.
99    async fn get_open_message(
100        &self,
101        signed_entity_type: &SignedEntityType,
102    ) -> StdResult<Option<OpenMessage>>;
103
104    /// Mark the open message if it has expired.
105    async fn mark_open_message_if_expired(
106        &self,
107        signed_entity_type: &SignedEntityType,
108    ) -> StdResult<Option<OpenMessage>>;
109
110    /// Create a certificate if possible. If the pointed open message does
111    /// not exist or has been already certified, an error is raised. If a multi
112    /// signature is created then the flag `is_certified` of the open
113    /// message is set to true. The Certificate is created.
114    /// If the stake quorum of the single signatures is
115    /// not reached for the multisignature to be created, the certificate is not
116    /// created and None is returned. If the certificate can be created, the
117    /// list of the registered signers for the given epoch is used.
118    async fn create_certificate(
119        &self,
120        signed_entity_type: &SignedEntityType,
121    ) -> StdResult<Option<Certificate>>;
122
123    /// Returns a certificate from its hash.
124    async fn get_certificate_by_hash(&self, hash: &str) -> StdResult<Option<Certificate>>;
125
126    /// Returns the list of the latest created certificates.
127    async fn get_latest_certificates(&self, last_n: usize) -> StdResult<Vec<Certificate>>;
128
129    /// Verify the certificate chain and epoch gap. This will return an error if
130    /// there is at least an epoch between the given epoch and the most recent
131    /// certificate.
132    async fn verify_certificate_chain(&self, epoch: Epoch) -> StdResult<()>;
133}
134
135/// ## BufferedSingleSignatureStore
136///
137/// Allow to buffer single signatures for later use when an open message isn't available yet.
138#[cfg_attr(test, mockall::automock)]
139#[async_trait]
140pub trait BufferedSingleSignatureStore: Sync + Send {
141    /// Buffer a single signature for later use.
142    async fn buffer_signature(
143        &self,
144        signed_entity_type_discriminant: SignedEntityTypeDiscriminants,
145        signature: &SingleSignature,
146    ) -> StdResult<()>;
147
148    /// Get the buffered single signatures for the given signed entity discriminant.
149    async fn get_buffered_signatures(
150        &self,
151        signed_entity_type_discriminant: SignedEntityTypeDiscriminants,
152    ) -> StdResult<Vec<SingleSignature>>;
153
154    /// Remove the given single signatures from the buffer.
155    async fn remove_buffered_signatures(
156        &self,
157        signed_entity_type_discriminant: SignedEntityTypeDiscriminants,
158        single_signatures: Vec<SingleSignature>,
159    ) -> StdResult<()>;
160}