mithril_client/certificate_client/
api.rs

1use async_trait::async_trait;
2use std::sync::Arc;
3
4use mithril_common::logging::LoggerExtensions;
5
6use crate::certificate_client::fetch::InternalCertificateRetriever;
7use crate::certificate_client::{fetch, verify};
8use crate::{MithrilCertificate, MithrilCertificateListItem, MithrilResult};
9
10/// Aggregator client for the Certificate
11pub struct CertificateClient {
12    pub(super) aggregator_requester: Arc<dyn CertificateAggregatorRequest>,
13    pub(super) retriever: Arc<InternalCertificateRetriever>,
14    pub(super) verifier: Arc<dyn CertificateVerifier>,
15}
16
17/// Define the requests against an aggregator related to Mithril certificate.
18#[cfg_attr(test, mockall::automock)]
19#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
20#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
21pub trait CertificateAggregatorRequest: Send + Sync {
22    /// Get the list of latest Mithril Certificates from the aggregator.
23    async fn list_latest(&self) -> MithrilResult<Vec<MithrilCertificateListItem>>;
24
25    /// Get a Mithril Certificate for a given hash from the aggregator.
26    async fn get_by_hash(&self, hash: &str) -> MithrilResult<Option<MithrilCertificate>>;
27}
28
29impl CertificateClient {
30    /// Constructs a new `CertificateClient`.
31    pub fn new(
32        aggregator_requester: Arc<dyn CertificateAggregatorRequest>,
33        verifier: Arc<dyn CertificateVerifier>,
34        logger: slog::Logger,
35    ) -> Self {
36        let _logger = logger.new_with_component_name::<Self>();
37        let retriever = Arc::new(InternalCertificateRetriever::new(
38            aggregator_requester.clone(),
39        ));
40
41        Self {
42            aggregator_requester,
43            retriever,
44            verifier,
45        }
46    }
47
48    /// Fetch a list of certificates
49    pub async fn list(&self) -> MithrilResult<Vec<MithrilCertificateListItem>> {
50        fetch::list(self).await
51    }
52
53    /// Get a single certificate full information from the aggregator.
54    pub async fn get(&self, certificate_hash: &str) -> MithrilResult<Option<MithrilCertificate>> {
55        fetch::get(self, certificate_hash).await
56    }
57
58    /// Validate the chain starting with the certificate with given `certificate_hash`, return the certificate if
59    /// the chain is valid.
60    ///
61    /// This method will fail if no certificate exists for the given `certificate_hash`.
62    pub async fn verify_chain(&self, certificate_hash: &str) -> MithrilResult<MithrilCertificate> {
63        verify::verify_chain(self, certificate_hash).await
64    }
65}
66
67/// API that defines how to validate certificates.
68#[cfg_attr(test, mockall::automock)]
69#[cfg_attr(target_family = "wasm", async_trait(?Send))]
70#[cfg_attr(not(target_family = "wasm"), async_trait)]
71pub trait CertificateVerifier: Sync + Send {
72    /// Validate the chain starting with the given certificate.
73    async fn verify_chain(&self, certificate: &MithrilCertificate) -> MithrilResult<()>;
74}
75
76#[cfg(feature = "unstable")]
77/// API that defines how to cache certificates validation results.
78#[cfg_attr(test, mockall::automock)]
79#[cfg_attr(target_family = "wasm", async_trait(?Send))]
80#[cfg_attr(not(target_family = "wasm"), async_trait)]
81pub trait CertificateVerifierCache: Sync + Send {
82    /// Store a validated certificate hash and its parent hash in the cache.
83    async fn store_validated_certificate(
84        &self,
85        certificate_hash: &str,
86        previous_certificate_hash: &str,
87    ) -> MithrilResult<()>;
88
89    /// Get the previous hash of the certificate with the given hash if available in the cache.
90    async fn get_previous_hash(&self, certificate_hash: &str) -> MithrilResult<Option<String>>;
91
92    /// Reset the stored values
93    async fn reset(&self) -> MithrilResult<()>;
94}