fedimint_empty_client/
lib.rs1#![deny(clippy::pedantic)]
2#![allow(clippy::module_name_repetitions)]
3
4use std::collections::BTreeMap;
5
6use db::DbKeyPrefix;
7use fedimint_client_module::db::ClientModuleMigrationFn;
8use fedimint_client_module::error::ClientModuleError;
9use fedimint_client_module::module::init::{ClientModuleInit, ClientModuleInitArgs};
10use fedimint_client_module::module::recovery::NoModuleBackup;
11use fedimint_client_module::module::{ClientContext, ClientModule, IClientModule};
12use fedimint_client_module::sm::Context;
13use fedimint_core::core::{Decoder, ModuleKind};
14use fedimint_core::db::{Database, DatabaseTransaction, DatabaseVersion};
15use fedimint_core::module::{
16 AmountUnit, Amounts, ApiVersion, ModuleCommon, ModuleInit, MultiApiVersion,
17};
18use fedimint_core::{Amount, apply, async_trait_maybe_send};
19pub use fedimint_empty_common as common;
20use fedimint_empty_common::config::EmptyClientConfig;
21use fedimint_empty_common::{EmptyCommonInit, EmptyModuleTypes};
22use states::EmptyStateMachine;
23use strum::IntoEnumIterator;
24
25pub mod api;
26pub mod db;
27pub mod states;
28
29#[derive(Debug)]
30pub struct EmptyClientModule {
31 #[allow(dead_code)]
32 cfg: EmptyClientConfig,
33 #[allow(dead_code)]
34 client_ctx: ClientContext<Self>,
35 #[allow(dead_code)]
36 db: Database,
37}
38
39#[derive(Debug, Clone)]
41pub struct EmptyClientContext {
42 pub empty_decoder: Decoder,
43}
44
45impl Context for EmptyClientContext {
47 const KIND: Option<ModuleKind> = None;
48}
49
50#[apply(async_trait_maybe_send!)]
51impl ClientModule for EmptyClientModule {
52 type Init = EmptyClientInit;
53 type Common = EmptyModuleTypes;
54 type Backup = NoModuleBackup;
55 type ModuleStateMachineContext = EmptyClientContext;
56 type States = EmptyStateMachine;
57
58 fn context(&self) -> Self::ModuleStateMachineContext {
59 EmptyClientContext {
60 empty_decoder: self.decoder(),
61 }
62 }
63
64 fn input_fee(
65 &self,
66 _amount: &Amounts,
67 _input: &<Self::Common as ModuleCommon>::Input,
68 ) -> Option<Amounts> {
69 unreachable!()
70 }
71
72 fn output_fee(
73 &self,
74 _amount: &Amounts,
75 _output: &<Self::Common as ModuleCommon>::Output,
76 ) -> Option<Amounts> {
77 unreachable!()
78 }
79
80 async fn get_balance(&self, _dbtx: &mut DatabaseTransaction<'_>, _unit: AmountUnit) -> Amount {
81 Amount::ZERO
82 }
83}
84
85#[derive(Debug, Clone)]
86pub struct EmptyClientInit;
87
88impl ModuleInit for EmptyClientInit {
90 type Common = EmptyCommonInit;
91
92 async fn dump_database(
93 &self,
94 _dbtx: &mut DatabaseTransaction<'_>,
95 prefix_names: Vec<String>,
96 ) -> Box<dyn Iterator<Item = (String, Box<dyn erased_serde::Serialize + Send>)> + '_> {
97 let items: BTreeMap<String, Box<dyn erased_serde::Serialize + Send>> = BTreeMap::new();
98 let filtered_prefixes = DbKeyPrefix::iter().filter(|f| {
99 prefix_names.is_empty() || prefix_names.contains(&f.to_string().to_lowercase())
100 });
101
102 #[allow(clippy::never_loop)]
103 for table in filtered_prefixes {
104 match table {}
105 }
106
107 Box::new(items.into_iter())
108 }
109}
110
111#[apply(async_trait_maybe_send!)]
113impl ClientModuleInit for EmptyClientInit {
114 type Module = EmptyClientModule;
115
116 fn supported_api_versions(&self) -> MultiApiVersion {
117 MultiApiVersion::try_from_iter([ApiVersion { major: 0, minor: 0 }])
118 .expect("no version conflicts")
119 }
120
121 async fn init(
122 &self,
123 args: &ClientModuleInitArgs<Self>,
124 ) -> Result<Self::Module, ClientModuleError> {
125 Ok(EmptyClientModule {
126 cfg: args.cfg().clone(),
127 client_ctx: args.context(),
128 db: args.db().clone(),
129 })
130 }
131
132 fn get_database_migrations(&self) -> BTreeMap<DatabaseVersion, ClientModuleMigrationFn> {
133 BTreeMap::new()
134 }
135}