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}