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  }