balius_runtime/ledgers/
mod.rs

1use std::sync::Arc;
2
3use tokio::sync::Mutex;
4
5use crate::{metrics::Metrics, wit::balius::app::ledger as wit};
6
7pub mod mock;
8pub mod u5c;
9
10pub use wit::{Host as CustomLedger, LedgerError, TxoRef, Utxo, UtxoPage, UtxoPattern};
11
12#[async_trait::async_trait]
13pub trait LedgerProvider {
14    async fn read_utxos(
15        &mut self,
16        refs: Vec<wit::TxoRef>,
17    ) -> Result<Vec<wit::Utxo>, wit::LedgerError>;
18    async fn search_utxos(
19        &mut self,
20        pattern: wit::UtxoPattern,
21        start: Option<String>,
22        max_items: u32,
23    ) -> Result<wit::UtxoPage, wit::LedgerError>;
24    async fn read_params(&mut self) -> Result<wit::Json, wit::LedgerError>;
25}
26
27#[derive(Clone)]
28#[allow(clippy::large_enum_variant)]
29pub enum Ledger {
30    Mock(mock::Ledger),
31    U5C(u5c::Ledger),
32    Custom(Arc<Mutex<dyn LedgerProvider + Send + Sync>>),
33}
34
35impl From<mock::Ledger> for Ledger {
36    fn from(ledger: mock::Ledger) -> Self {
37        Ledger::Mock(ledger)
38    }
39}
40
41impl From<u5c::Ledger> for Ledger {
42    fn from(ledger: u5c::Ledger) -> Self {
43        Ledger::U5C(ledger)
44    }
45}
46
47#[derive(Clone)]
48pub struct LedgerHost {
49    worker_id: String,
50    ledger: Ledger,
51    metrics: Arc<Metrics>,
52}
53impl LedgerHost {
54    pub fn new(worker_id: &str, ledger: &Ledger, metrics: &Arc<Metrics>) -> Self {
55        Self {
56            worker_id: worker_id.to_string(),
57            ledger: ledger.clone(),
58            metrics: metrics.clone(),
59        }
60    }
61}
62
63impl wit::Host for LedgerHost {
64    async fn read_utxos(
65        &mut self,
66        refs: Vec<wit::TxoRef>,
67    ) -> Result<Vec<wit::Utxo>, wit::LedgerError> {
68        self.metrics.ledger_read_utxos(&self.worker_id);
69        match &mut self.ledger {
70            Ledger::Mock(ledger) => ledger.read_utxos(refs).await,
71            Ledger::U5C(ledger) => ledger.read_utxos(refs).await,
72            Ledger::Custom(ledger) => {
73                let mut lock = ledger.lock().await;
74                lock.read_utxos(refs).await
75            }
76        }
77    }
78
79    async fn search_utxos(
80        &mut self,
81        pattern: wit::UtxoPattern,
82        start: Option<String>,
83        max_items: u32,
84    ) -> Result<wit::UtxoPage, wit::LedgerError> {
85        self.metrics.ledger_search_utxos(&self.worker_id);
86        match &mut self.ledger {
87            Ledger::Mock(ledger) => ledger.search_utxos(pattern, start, max_items).await,
88            Ledger::U5C(ledger) => ledger.search_utxos(pattern, start, max_items).await,
89            Ledger::Custom(ledger) => {
90                let mut lock = ledger.lock().await;
91                lock.search_utxos(pattern, start, max_items).await
92            }
93        }
94    }
95
96    async fn read_params(&mut self) -> Result<wit::Json, wit::LedgerError> {
97        self.metrics.ledger_read_params(&self.worker_id);
98        match &mut self.ledger {
99            Ledger::Mock(ledger) => ledger.read_params().await,
100            Ledger::U5C(ledger) => ledger.read_params().await,
101            Ledger::Custom(ledger) => {
102                let mut lock = ledger.lock().await;
103                lock.read_params().await
104            }
105        }
106    }
107}