delta_domain_sdk/views/
sdls.rs

1use base_sdk::{
2    core::TxId,
3    crypto::HashDigest,
4};
5use domain_runtime::{
6    ports::DbQueriesPort,
7    sdls::types::{
8        SdlState,
9        SdlTransactionIds,
10    },
11    storage::SdlStateColumnFamily,
12};
13use snafu::{
14    ResultExt,
15    Snafu,
16};
17use storage::{
18    column_family::StorageQuery,
19    database::StorageError,
20};
21
22/// Errors occurring in the [Sdls] helper
23#[derive(Debug, Snafu)]
24pub enum Error {
25    /// Error when reading from storage
26    #[snafu(display("Error while reading from storage: {source}"))]
27    Storage {
28        /// The underlying storage error
29        source: StorageError,
30    },
31}
32
33/// Helper to access the SDL state
34#[derive(Debug, Clone)]
35pub struct Sdls<Db> {
36    db: Db,
37}
38
39impl<Db> Sdls<Db> {
40    pub(crate) const fn new(db: Db) -> Self {
41        Self { db }
42    }
43}
44
45impl<Db> Sdls<Db>
46where
47    Db: DbQueriesPort,
48{
49    /// Get the current status of a State Diff List (SDL) that was processed by
50    /// this domain.
51    ///
52    /// # Parameters
53    ///
54    /// * `sdl_hash` - The hash of the SDL to query
55    ///
56    /// # Returns
57    ///
58    /// * `Ok(Some(state))` - The current state of the SDL if found
59    /// * `Ok(None)` - If no SDL with the given hash exists
60    /// * `Err(Error)` - If there was an error reading from storage
61    pub fn get_status(&self, sdl_hash: &HashDigest) -> Result<Option<SdlState>, Error> {
62        StorageQuery::<SdlStateColumnFamily>::get_value(&self.db, sdl_hash).context(StorageSnafu)
63    }
64
65    /// Get all State Diff List (SDL) hashes with their current status
66    pub fn get_all(&self) -> Result<Vec<(HashDigest, SdlState)>, Error> {
67        // TODO: This method does not scale with time as it iterates over all sdls
68        StorageQuery::<SdlStateColumnFamily>::iter(&self.db)
69            .collect::<Result<Vec<_>, _>>()
70            .context(StorageSnafu)
71    }
72
73    /// Get the [TxId] of base-layer transaction in which the SDL identified by its [HashDigest]
74    /// has been submitted to the base-layer.
75    ///
76    /// Note that this transaction does not include the SDL proof submission.
77    ///
78    /// # Returns
79    ///
80    /// * `Ok(Some(tx_id))` - The requested [TxId] if found
81    /// * `Ok(None)` - If no [TxId] was registered for the given SDL hash
82    /// * `Err(Error)` - If there was an error reading from storage
83    pub fn get_transaction_id(&self, sdl_hash: &HashDigest) -> Result<Option<TxId>, Error> {
84        self.get_txids(sdl_hash)
85            .map(|associated_data| associated_data.map(|data| data.tx_id))
86    }
87
88    /// Get the [TxId] of base-layer transaction in which the proof for the SDL identified by
89    /// its [HashDigest] has been submitted to the base-layer.
90    ///
91    /// If the proof of this SDL was not yet submitted, this will return `None`.
92    ///
93    /// Note that this transaction only includes the SDL proof, and not the SDL itself.
94    ///
95    /// # Returns
96    ///
97    /// * `Ok(Some(tx_id))` - The requested [TxId] if found
98    /// * `Ok(None)` - If no [TxId] was registered for the given SDL hash
99    /// * `Err(Error)` - If there was an error reading from storage
100    pub fn get_proof_transaction_id(&self, sdl_hash: &HashDigest) -> Result<Option<TxId>, Error> {
101        self.get_txids(sdl_hash)
102            .map(|associated_data| associated_data.and_then(|data| data.proof_tx_id))
103    }
104
105    fn get_txids(&self, key: &HashDigest) -> Result<Option<SdlTransactionIds>, Error> {
106        StorageQuery::<SdlTransactionIds>::get_value(&self.db, key).context(StorageSnafu)
107    }
108}