admin_client.rs
1 use std::collections::BTreeMap; 2 use std::fmt::Debug; 3 4 use fedimint_core::util::SafeUrl; 5 use serde::{Deserialize, Serialize}; 6 #[cfg(not(target_family = "wasm"))] 7 use tokio_rustls::rustls::Certificate as RustlsCertificate; 8 9 use crate::config::ServerModuleConfigGenParamsRegistry; 10 use 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")] 15 pub 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)] 38 struct RustlsCertificate(pub Vec<u8>); 39 40 /// Sent by admin user to the API 41 #[derive(Debug, Clone, Serialize, Deserialize)] 42 pub 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 52 pub 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)] 69 pub 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)] 80 pub 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)] 89 pub 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 96 mod 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 }