fedimint_unknown_server/
lib.rs

1#![deny(clippy::pedantic)]
2#![allow(clippy::module_name_repetitions)]
3#![allow(clippy::must_use_candidate)]
4
5use std::collections::BTreeMap;
6
7use anyhow::bail;
8use async_trait::async_trait;
9use fedimint_core::config::{
10    ConfigGenModuleParams, DkgResult, ServerModuleConfig, ServerModuleConsensusConfig,
11    TypedServerModuleConfig, TypedServerModuleConsensusConfig,
12};
13use fedimint_core::core::ModuleInstanceId;
14use fedimint_core::db::{CoreMigrationFn, DatabaseTransaction, DatabaseVersion};
15use fedimint_core::module::audit::Audit;
16use fedimint_core::module::{
17    ApiEndpoint, CoreConsensusVersion, InputMeta, ModuleConsensusVersion, ModuleInit, PeerHandle,
18    ServerModuleInit, ServerModuleInitArgs, SupportedModuleApiVersions, TransactionItemAmount,
19    CORE_CONSENSUS_VERSION,
20};
21use fedimint_core::server::DynServerModule;
22use fedimint_core::{OutPoint, PeerId, ServerModule};
23pub use fedimint_unknown_common as common;
24use fedimint_unknown_common::config::{
25    UnknownClientConfig, UnknownConfig, UnknownConfigConsensus, UnknownConfigLocal,
26    UnknownConfigPrivate, UnknownGenParams,
27};
28use fedimint_unknown_common::{
29    UnknownCommonInit, UnknownConsensusItem, UnknownInput, UnknownInputError, UnknownModuleTypes,
30    UnknownOutput, UnknownOutputError, UnknownOutputOutcome, MODULE_CONSENSUS_VERSION,
31};
32pub mod db;
33
34/// Generates the module
35#[derive(Debug, Clone)]
36pub struct UnknownInit;
37
38// TODO: Boilerplate-code
39impl ModuleInit for UnknownInit {
40    type Common = UnknownCommonInit;
41
42    /// Dumps all database items for debugging
43    async fn dump_database(
44        &self,
45        _dbtx: &mut DatabaseTransaction<'_>,
46        _prefix_names: Vec<String>,
47    ) -> Box<dyn Iterator<Item = (String, Box<dyn erased_serde::Serialize + Send>)> + '_> {
48        Box::new(vec![].into_iter())
49    }
50}
51
52/// Implementation of server module non-consensus functions
53#[async_trait]
54impl ServerModuleInit for UnknownInit {
55    type Params = UnknownGenParams;
56
57    /// Returns the version of this module
58    fn versions(&self, _core: CoreConsensusVersion) -> &[ModuleConsensusVersion] {
59        &[MODULE_CONSENSUS_VERSION]
60    }
61
62    fn supported_api_versions(&self) -> SupportedModuleApiVersions {
63        SupportedModuleApiVersions::from_raw(
64            (CORE_CONSENSUS_VERSION.major, CORE_CONSENSUS_VERSION.minor),
65            (
66                MODULE_CONSENSUS_VERSION.major,
67                MODULE_CONSENSUS_VERSION.minor,
68            ),
69            &[(0, 0)],
70        )
71    }
72
73    /// Initialize the module
74    async fn init(&self, args: &ServerModuleInitArgs<Self>) -> anyhow::Result<DynServerModule> {
75        Ok(Unknown::new(args.cfg().to_typed()?).into())
76    }
77
78    /// Generates configs for all peers in a trusted manner for testing
79    fn trusted_dealer_gen(
80        &self,
81        peers: &[PeerId],
82        params: &ConfigGenModuleParams,
83    ) -> BTreeMap<PeerId, ServerModuleConfig> {
84        let _params = self.parse_params(params).unwrap();
85        // Generate a config for each peer
86        peers
87            .iter()
88            .map(|&peer| {
89                let config = UnknownConfig {
90                    local: UnknownConfigLocal {},
91                    private: UnknownConfigPrivate,
92                    consensus: UnknownConfigConsensus {},
93                };
94                (peer, config.to_erased())
95            })
96            .collect()
97    }
98
99    /// Generates configs for all peers in an untrusted manner
100    async fn distributed_gen(
101        &self,
102        _peers: &PeerHandle,
103        params: &ConfigGenModuleParams,
104    ) -> DkgResult<ServerModuleConfig> {
105        let _params = self.parse_params(params).unwrap();
106
107        Ok(UnknownConfig {
108            local: UnknownConfigLocal {},
109            private: UnknownConfigPrivate,
110            consensus: UnknownConfigConsensus {},
111        }
112        .to_erased())
113    }
114
115    /// Converts the consensus config into the client config
116    fn get_client_config(
117        &self,
118        config: &ServerModuleConsensusConfig,
119    ) -> anyhow::Result<UnknownClientConfig> {
120        let _config = UnknownConfigConsensus::from_erased(config)?;
121        Ok(UnknownClientConfig {})
122    }
123
124    fn validate_config(
125        &self,
126        _identity: &PeerId,
127        _config: ServerModuleConfig,
128    ) -> anyhow::Result<()> {
129        Ok(())
130    }
131
132    /// DB migrations to move from old to newer versions
133    fn get_database_migrations(&self) -> BTreeMap<DatabaseVersion, CoreMigrationFn> {
134        let mut migrations: BTreeMap<DatabaseVersion, CoreMigrationFn> = BTreeMap::new();
135        // Unknown module prior to v0.5.0 had a `DATABASE_VERSION` of 1, so we must
136        // insert a no-op migration to ensure that upgrades work.
137        migrations.insert(DatabaseVersion(0), |_| Box::pin(async { Ok(()) }));
138        migrations
139    }
140}
141
142/// Unknown module
143#[derive(Debug)]
144pub struct Unknown {
145    pub cfg: UnknownConfig,
146}
147
148/// Implementation of consensus for the server module
149#[async_trait]
150impl ServerModule for Unknown {
151    /// Define the consensus types
152    type Common = UnknownModuleTypes;
153    type Init = UnknownInit;
154
155    async fn consensus_proposal(
156        &self,
157        _dbtx: &mut DatabaseTransaction<'_>,
158    ) -> Vec<UnknownConsensusItem> {
159        Vec::new()
160    }
161
162    async fn process_consensus_item<'a, 'b>(
163        &'a self,
164        _dbtx: &mut DatabaseTransaction<'b>,
165        _consensus_item: UnknownConsensusItem,
166        _peer_id: PeerId,
167    ) -> anyhow::Result<()> {
168        // WARNING: `process_consensus_item` should return an `Err` for items that do
169        // not change any internal consensus state. Failure to do so, will result in an
170        // (potentially significantly) increased consensus history size.
171        // If you are using this code as a template,
172        // make sure to read the [`ServerModule::process_consensus_item`] documentation,
173        bail!("The unknown module does not use consensus items");
174    }
175
176    async fn process_input<'a, 'b, 'c>(
177        &'a self,
178        _dbtx: &mut DatabaseTransaction<'c>,
179        _input: &'b UnknownInput,
180    ) -> Result<InputMeta, UnknownInputError> {
181        unreachable!();
182    }
183
184    async fn process_output<'a, 'b>(
185        &'a self,
186        _dbtx: &mut DatabaseTransaction<'b>,
187        _output: &'a UnknownOutput,
188        _out_point: OutPoint,
189    ) -> Result<TransactionItemAmount, UnknownOutputError> {
190        unreachable!();
191    }
192
193    async fn output_status(
194        &self,
195        _dbtx: &mut DatabaseTransaction<'_>,
196        _out_point: OutPoint,
197    ) -> Option<UnknownOutputOutcome> {
198        unreachable!()
199    }
200
201    async fn audit(
202        &self,
203        _dbtx: &mut DatabaseTransaction<'_>,
204        _audit: &mut Audit,
205        _module_instance_id: ModuleInstanceId,
206    ) {
207    }
208
209    fn api_endpoints(&self) -> Vec<ApiEndpoint<Self>> {
210        Vec::new()
211    }
212}
213
214impl Unknown {
215    /// Create new module instance
216    pub fn new(cfg: UnknownConfig) -> Unknown {
217        Unknown { cfg }
218    }
219}