fedimint_core/
admin_client.rs

1use std::collections::BTreeMap;
2use std::fmt::Debug;
3
4use fedimint_core::util::SafeUrl;
5use serde::{Deserialize, Serialize};
6#[cfg(not(target_family = "wasm"))]
7use tokio_rustls::rustls::Certificate as RustlsCertificate;
8
9use crate::config::ServerModuleConfigGenParamsRegistry;
10use crate::PeerId;
11
12/// The state of the server returned via APIs
13#[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)]
14#[serde(rename_all = "snake_case")]
15pub enum ServerStatus {
16    /// Server needs a password to read configs
17    #[default]
18    AwaitingPassword,
19    /// Waiting for peers to share the config gen params
20    SharingConfigGenParams,
21    /// Ready to run config gen once all peers are ready
22    ReadyForConfigGen,
23    /// We failed running config gen
24    ConfigGenFailed,
25    /// Config is generated, peers should verify the config
26    VerifyingConfigs,
27    /// We have verified all our peer configs
28    VerifiedConfigs,
29    /// Consensus is running
30    ConsensusRunning,
31    /// Restarted setup. All peers need to sync on this state before continuing
32    /// to `SharingConfigGenParams`
33    SetupRestarted,
34}
35
36#[cfg(target_family = "wasm")]
37#[derive(Debug, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
38struct RustlsCertificate(pub Vec<u8>);
39
40/// Sent by admin user to the API
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct ConfigGenConnectionsRequest {
43    /// Our guardian name
44    pub our_name: String,
45    /// URL of "leader" guardian to send our connection info to
46    /// Will be `None` if we are the leader
47    pub leader_api_url: Option<SafeUrl>,
48}
49
50#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
51/// Connection information sent between peers in order to start config gen
52pub struct PeerServerParams {
53    /// TLS cert is necessary for P2P auth during DKG and  consensus
54    #[serde(with = "serde_tls_cert")]
55    pub cert: RustlsCertificate,
56    /// P2P is the network for running DKG and consensus
57    pub p2p_url: SafeUrl,
58    /// API for secure websocket requests
59    pub api_url: SafeUrl,
60    /// Name of the peer, used in TLS auth
61    pub name: String,
62    /// Status of the peer if known
63    pub status: Option<ServerStatus>,
64}
65
66/// The config gen params that need to be in consensus, sent by the config gen
67/// leader to all the other guardians
68#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
69pub struct ConfigGenParamsConsensus {
70    /// Endpoints of all servers
71    pub peers: BTreeMap<PeerId, PeerServerParams>,
72    /// Guardian-defined key-value pairs that will be passed to the client
73    pub meta: BTreeMap<String, String>,
74    /// Module init params (also contains local params from us)
75    pub modules: ServerModuleConfigGenParamsRegistry,
76}
77
78/// The config gen params response which includes our peer id
79#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
80pub struct ConfigGenParamsResponse {
81    /// The same for all peers
82    pub consensus: ConfigGenParamsConsensus,
83    /// Our id (might change if new peers join)
84    pub our_current_id: PeerId,
85}
86
87/// Config gen params that can be configured from the UI
88#[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)]
89pub struct ConfigGenParamsRequest {
90    /// Guardian-defined key-value pairs that will be passed to the client
91    pub meta: BTreeMap<String, String>,
92    /// Set the params (if leader) or just the local params (if follower)
93    pub modules: ServerModuleConfigGenParamsRegistry,
94}
95
96mod serde_tls_cert {
97    use std::borrow::Cow;
98
99    use hex::{FromHex, ToHex};
100    use serde::de::Error;
101    use serde::{Deserialize, Deserializer, Serializer};
102
103    use super::RustlsCertificate;
104
105    pub fn serialize<S>(certs: &RustlsCertificate, serializer: S) -> Result<S::Ok, S::Error>
106    where
107        S: Serializer,
108    {
109        let hex_str = certs.0.encode_hex::<String>();
110        serializer.serialize_str(&hex_str)
111    }
112
113    pub fn deserialize<'de, D>(deserializer: D) -> Result<RustlsCertificate, D::Error>
114    where
115        D: Deserializer<'de>,
116    {
117        let value: Cow<str> = Deserialize::deserialize(deserializer)?;
118        Ok(RustlsCertificate(
119            Vec::from_hex(value.as_ref()).map_err(D::Error::custom)?,
120        ))
121    }
122}