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