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