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