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