/ fedimint-core / src / admin_client.rs
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  }