1use std::collections::{BTreeMap, BTreeSet};
2use std::fmt::{Debug, Display};
3use std::hash::Hash;
4use std::path::Path;
5use std::str::FromStr;
6
7use anyhow::{Context, format_err};
8use bitcoin::hashes::sha256::HashEngine;
9use bitcoin::hashes::{Hash as BitcoinHash, hex, sha256};
10use bls12_381::Scalar;
11use fedimint_core::core::{ModuleInstanceId, ModuleKind};
12use fedimint_core::encoding::{DynRawFallback, Encodable};
13use fedimint_core::module::registry::ModuleRegistry;
14use fedimint_core::util::SafeUrl;
15use fedimint_core::{ModuleDecoderRegistry, format_hex};
16use fedimint_logging::LOG_CORE;
17use hex::FromHex;
18use secp256k1::PublicKey;
19use serde::de::DeserializeOwned;
20use serde::ser::SerializeMap;
21use serde::{Deserialize, Deserializer, Serialize, Serializer};
22use serde_json::json;
23use threshold_crypto::{G1Projective, G2Projective};
24use tracing::warn;
25
26use crate::core::DynClientConfig;
27use crate::encoding::Decodable;
28use crate::module::{
29 CoreConsensusVersion, DynCommonModuleInit, IDynCommonModuleInit, ModuleConsensusVersion,
30 SerdeModuleEncoding,
31};
32use crate::session_outcome::SignedSessionOutcome;
33use crate::{PeerId, maybe_add_send_sync, secp256k1};
34
35pub const ALEPH_BFT_UNIT_BYTE_LIMIT: usize = 50_000;
38
39#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
45pub struct JsonWithKind {
46 kind: ModuleKind,
47 #[serde(flatten)]
48 value: serde_json::Value,
49}
50
51impl JsonWithKind {
52 pub fn new(kind: ModuleKind, value: serde_json::Value) -> Self {
53 Self { kind, value }
54 }
55
56 pub fn with_fixed_empty_value(self) -> Self {
77 if let serde_json::Value::Object(ref o) = self.value
78 && o.is_empty()
79 {
80 return Self {
81 kind: self.kind,
82 value: serde_json::Value::Null,
83 };
84 }
85
86 self
87 }
88
89 pub fn value(&self) -> &serde_json::Value {
90 &self.value
91 }
92
93 pub fn kind(&self) -> &ModuleKind {
94 &self.kind
95 }
96
97 pub fn is_kind(&self, kind: &ModuleKind) -> bool {
98 &self.kind == kind
99 }
100}
101
102#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Encodable, Decodable)]
103pub struct PeerUrl {
104 pub url: SafeUrl,
106 pub name: String,
108}
109
110#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Encodable, Decodable)]
114pub struct ClientConfigV0 {
115 #[serde(flatten)]
116 pub global: GlobalClientConfigV0,
117 #[serde(deserialize_with = "de_int_key")]
118 pub modules: BTreeMap<ModuleInstanceId, ClientModuleConfig>,
119}
120
121#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Encodable, Decodable)]
125pub struct ClientConfig {
126 #[serde(flatten)]
127 pub global: GlobalClientConfig,
128 #[serde(deserialize_with = "de_int_key")]
129 pub modules: BTreeMap<ModuleInstanceId, ClientModuleConfig>,
130}
131
132fn de_int_key<'de, D, K, V>(deserializer: D) -> Result<BTreeMap<K, V>, D::Error>
134where
135 D: Deserializer<'de>,
136 K: Eq + Ord + FromStr,
137 K::Err: Display,
138 V: Deserialize<'de>,
139{
140 let string_map = <BTreeMap<String, V>>::deserialize(deserializer)?;
141 let map = string_map
142 .into_iter()
143 .map(|(key_str, value)| {
144 let key = K::from_str(&key_str).map_err(serde::de::Error::custom)?;
145 Ok((key, value))
146 })
147 .collect::<Result<BTreeMap<_, _>, _>>()?;
148 Ok(map)
149}
150
151fn optional_de_int_key<'de, D, K, V>(deserializer: D) -> Result<Option<BTreeMap<K, V>>, D::Error>
152where
153 D: Deserializer<'de>,
154 K: Eq + Ord + FromStr,
155 K::Err: Display,
156 V: Deserialize<'de>,
157{
158 let Some(string_map) = <Option<BTreeMap<String, V>>>::deserialize(deserializer)? else {
159 return Ok(None);
160 };
161
162 let map = string_map
163 .into_iter()
164 .map(|(key_str, value)| {
165 let key = K::from_str(&key_str).map_err(serde::de::Error::custom)?;
166 Ok((key, value))
167 })
168 .collect::<Result<BTreeMap<_, _>, _>>()?;
169
170 Ok(Some(map))
171}
172
173#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
176pub struct JsonClientConfig {
177 pub global: GlobalClientConfig,
178 pub modules: BTreeMap<ModuleInstanceId, JsonWithKind>,
179}
180
181#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Encodable, Decodable)]
183pub struct GlobalClientConfigV0 {
184 #[serde(deserialize_with = "de_int_key")]
186 pub api_endpoints: BTreeMap<PeerId, PeerUrl>,
187 pub consensus_version: CoreConsensusVersion,
189 pub meta: BTreeMap<String, String>,
192}
193
194#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Encodable, Decodable)]
196pub struct GlobalClientConfig {
197 #[serde(deserialize_with = "de_int_key")]
199 pub api_endpoints: BTreeMap<PeerId, PeerUrl>,
200 #[serde(default, deserialize_with = "optional_de_int_key")]
203 pub broadcast_public_keys: Option<BTreeMap<PeerId, PublicKey>>,
204 pub consensus_version: CoreConsensusVersion,
206 pub meta: BTreeMap<String, String>,
209}
210
211impl GlobalClientConfig {
212 pub fn calculate_federation_id(&self) -> FederationId {
215 FederationId(self.api_endpoints.consensus_hash())
216 }
217
218 pub fn federation_name(&self) -> Option<&str> {
220 self.meta.get(META_FEDERATION_NAME_KEY).map(|x| &**x)
221 }
222}
223
224impl ClientConfig {
225 pub fn redecode_raw(
227 self,
228 modules: &ModuleDecoderRegistry,
229 ) -> Result<Self, crate::encoding::DecodeError> {
230 Ok(Self {
231 modules: self
232 .modules
233 .into_iter()
234 .map(|(module_id, v)| {
235 let kind = v.kind.clone();
238
239 v.redecode_raw(modules)
240 .context(format!("redecode_raw: instance: {module_id}, kind: {kind}"))
241 .map(|v| (module_id, v))
242 })
243 .collect::<Result<_, _>>()?,
244 ..self
245 })
246 }
247
248 pub fn calculate_federation_id(&self) -> FederationId {
249 self.global.calculate_federation_id()
250 }
251
252 pub fn meta<V: serde::de::DeserializeOwned + 'static>(
254 &self,
255 key: &str,
256 ) -> Result<Option<V>, anyhow::Error> {
257 let Some(str_value) = self.global.meta.get(key) else {
258 return Ok(None);
259 };
260 let res = serde_json::from_str(str_value)
261 .map(Some)
262 .context(format!("Decoding meta field '{key}' failed"));
263
264 if res.is_err() && std::any::TypeId::of::<V>() == std::any::TypeId::of::<String>() {
268 let string_ret = Box::new(str_value.clone());
269 let ret = unsafe {
270 std::mem::transmute::<Box<String>, Box<V>>(string_ret)
272 };
273 Ok(Some(*ret))
274 } else {
275 res
276 }
277 }
278
279 pub fn to_json(&self) -> JsonClientConfig {
285 JsonClientConfig {
286 global: self.global.clone(),
287 modules: self
288 .modules
289 .iter()
290 .map(|(&module_instance_id, module_config)| {
291 let module_config_json = JsonWithKind {
292 kind: module_config.kind.clone(),
293 value: module_config.config
294 .clone()
295 .decoded()
296 .and_then(|dyn_cfg| dyn_cfg.to_json())
297 .unwrap_or_else(|| json!({
298 "unknown_module_hex": module_config.config.consensus_encode_to_hex()
299 })),
300 };
301 (module_instance_id, module_config_json)
302 })
303 .collect(),
304 }
305 }
306}
307
308#[derive(
314 Debug,
315 Copy,
316 Serialize,
317 Deserialize,
318 Clone,
319 Eq,
320 Hash,
321 PartialEq,
322 Encodable,
323 Decodable,
324 Ord,
325 PartialOrd,
326)]
327pub struct FederationId(pub sha256::Hash);
328
329#[derive(
330 Debug,
331 Copy,
332 Serialize,
333 Deserialize,
334 Clone,
335 Eq,
336 Hash,
337 PartialEq,
338 Encodable,
339 Decodable,
340 Ord,
341 PartialOrd,
342)]
343pub struct FederationIdPrefix([u8; 4]);
349
350impl Display for FederationIdPrefix {
351 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
352 format_hex(&self.0, f)
353 }
354}
355
356impl Display for FederationId {
357 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
358 format_hex(&self.0.to_byte_array(), f)
359 }
360}
361
362impl FromStr for FederationIdPrefix {
363 type Err = anyhow::Error;
364
365 fn from_str(s: &str) -> Result<Self, Self::Err> {
366 Ok(Self(<[u8; 4]>::from_hex(s)?))
367 }
368}
369
370impl FederationIdPrefix {
371 pub fn to_bytes(&self) -> Vec<u8> {
372 self.0.to_vec()
373 }
374}
375
376impl FederationId {
378 pub fn dummy() -> Self {
380 Self(sha256::Hash::from_byte_array([42; 32]))
381 }
382
383 pub(crate) fn from_byte_array(bytes: [u8; 32]) -> Self {
384 Self(sha256::Hash::from_byte_array(bytes))
385 }
386
387 pub fn to_prefix(&self) -> FederationIdPrefix {
388 FederationIdPrefix(self.0[..4].try_into().expect("can't fail"))
389 }
390
391 pub fn to_fake_ln_pub_key(
401 &self,
402 secp: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>,
403 ) -> anyhow::Result<bitcoin::secp256k1::PublicKey> {
404 let sk = bitcoin::secp256k1::SecretKey::from_slice(&self.0.to_byte_array())?;
405 Ok(bitcoin::secp256k1::PublicKey::from_secret_key(secp, &sk))
406 }
407}
408
409impl FromStr for FederationId {
410 type Err = anyhow::Error;
411
412 fn from_str(s: &str) -> Result<Self, Self::Err> {
413 Ok(Self::from_byte_array(<[u8; 32]>::from_hex(s)?))
414 }
415}
416
417impl ClientConfig {
418 pub fn consensus_hash(&self) -> sha256::Hash {
420 let mut engine = HashEngine::default();
421 self.consensus_encode(&mut engine)
422 .expect("Consensus hashing should never fail");
423 sha256::Hash::from_engine(engine)
424 }
425
426 pub fn get_module<T: Decodable + 'static>(&self, id: ModuleInstanceId) -> anyhow::Result<&T> {
427 self.modules.get(&id).map_or_else(
428 || Err(format_err!("Client config for module id {id} not found")),
429 |client_cfg| client_cfg.cast(),
430 )
431 }
432
433 pub fn get_module_cfg(&self, id: ModuleInstanceId) -> anyhow::Result<ClientModuleConfig> {
435 self.modules.get(&id).map_or_else(
436 || Err(format_err!("Client config for module id {id} not found")),
437 |client_cfg| Ok(client_cfg.clone()),
438 )
439 }
440
441 pub fn get_first_module_by_kind<T: Decodable + 'static>(
449 &self,
450 kind: impl Into<ModuleKind>,
451 ) -> anyhow::Result<(ModuleInstanceId, &T)> {
452 let kind: ModuleKind = kind.into();
453 let Some((id, module_cfg)) = self.modules.iter().find(|(_, v)| v.is_kind(&kind)) else {
454 anyhow::bail!("Module kind {kind} not found")
455 };
456 Ok((*id, module_cfg.cast()?))
457 }
458
459 pub fn get_first_module_by_kind_cfg(
461 &self,
462 kind: impl Into<ModuleKind>,
463 ) -> anyhow::Result<(ModuleInstanceId, ClientModuleConfig)> {
464 let kind: ModuleKind = kind.into();
465 self.modules
466 .iter()
467 .find(|(_, v)| v.is_kind(&kind))
468 .map(|(id, v)| (*id, v.clone()))
469 .ok_or_else(|| anyhow::format_err!("Module kind {kind} not found"))
470 }
471}
472
473#[derive(Clone, Debug)]
474pub struct ModuleInitRegistry<M>(BTreeMap<ModuleKind, M>);
475
476impl<M> ModuleInitRegistry<M> {
477 pub fn iter(&self) -> impl Iterator<Item = (&ModuleKind, &M)> {
478 self.0.iter()
479 }
480}
481
482impl<M> Default for ModuleInitRegistry<M> {
483 fn default() -> Self {
484 Self(BTreeMap::new())
485 }
486}
487
488#[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
491pub struct ConfigGenModuleParams {
492 pub local: serde_json::Value,
493 pub consensus: serde_json::Value,
494}
495
496impl ConfigGenModuleParams {
497 pub fn new(local: serde_json::Value, consensus: serde_json::Value) -> Self {
498 Self { local, consensus }
499 }
500
501 pub fn to_typed<P: ModuleInitParams>(&self) -> anyhow::Result<P> {
504 Ok(P::from_parts(
505 Self::parse("local", self.local.clone())?,
506 Self::parse("consensus", self.consensus.clone())?,
507 ))
508 }
509
510 fn parse<P: DeserializeOwned>(name: &str, json: serde_json::Value) -> anyhow::Result<P> {
511 serde_json::from_value(json).with_context(|| format!("Schema mismatch for {name} argument"))
512 }
513
514 pub fn from_typed<P: ModuleInitParams>(p: P) -> anyhow::Result<Self> {
515 let (local, consensus) = p.to_parts();
516 Ok(Self {
517 local: serde_json::to_value(local)?,
518 consensus: serde_json::to_value(consensus)?,
519 })
520 }
521}
522
523pub type CommonModuleInitRegistry = ModuleInitRegistry<DynCommonModuleInit>;
524
525pub type ServerModuleConfigGenParamsRegistry = ModuleRegistry<ConfigGenModuleParams>;
527
528impl Eq for ServerModuleConfigGenParamsRegistry {}
529
530impl PartialEq for ServerModuleConfigGenParamsRegistry {
531 fn eq(&self, other: &Self) -> bool {
532 self.iter_modules().eq(other.iter_modules())
533 }
534}
535
536impl Serialize for ServerModuleConfigGenParamsRegistry {
537 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
538 let modules: Vec<_> = self.iter_modules().collect();
539 let mut serializer = serializer.serialize_map(Some(modules.len()))?;
540 for (id, kind, params) in modules {
541 serializer.serialize_key(&id)?;
542 serializer.serialize_value(&(kind.clone(), params.clone()))?;
543 }
544 serializer.end()
545 }
546}
547
548impl<'de> Deserialize<'de> for ServerModuleConfigGenParamsRegistry {
549 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
550 where
551 D: Deserializer<'de>,
552 {
553 let json: BTreeMap<ModuleInstanceId, (ModuleKind, ConfigGenModuleParams)> =
554 Deserialize::deserialize(deserializer)?;
555 let mut params = BTreeMap::new();
556
557 for (id, (kind, module)) in json {
558 params.insert(id, (kind, module));
559 }
560 Ok(Self::from(params))
561 }
562}
563
564impl<M> From<Vec<M>> for ModuleInitRegistry<M>
565where
566 M: AsRef<dyn IDynCommonModuleInit + Send + Sync + 'static>,
567{
568 fn from(value: Vec<M>) -> Self {
569 Self(
570 value
571 .into_iter()
572 .map(|i| (i.as_ref().module_kind(), i))
573 .collect::<BTreeMap<_, _>>(),
574 )
575 }
576}
577
578impl<M> FromIterator<M> for ModuleInitRegistry<M>
579where
580 M: AsRef<maybe_add_send_sync!(dyn IDynCommonModuleInit + 'static)>,
581{
582 fn from_iter<T: IntoIterator<Item = M>>(iter: T) -> Self {
583 Self(
584 iter.into_iter()
585 .map(|i| (i.as_ref().module_kind(), i))
586 .collect::<BTreeMap<_, _>>(),
587 )
588 }
589}
590
591impl<M> ModuleInitRegistry<M> {
592 pub fn new() -> Self {
593 Self::default()
594 }
595
596 pub fn attach<T>(&mut self, r#gen: T)
597 where
598 T: Into<M> + 'static + Send + Sync,
599 M: AsRef<dyn IDynCommonModuleInit + 'static + Send + Sync>,
600 {
601 let r#gen: M = r#gen.into();
602 let kind = r#gen.as_ref().module_kind();
603 assert!(
604 self.0.insert(kind.clone(), r#gen).is_none(),
605 "Can't insert module of same kind twice: {kind}"
606 );
607 }
608
609 pub fn kinds(&self) -> BTreeSet<ModuleKind> {
610 self.0.keys().cloned().collect()
611 }
612
613 pub fn get(&self, k: &ModuleKind) -> Option<&M> {
614 self.0.get(k)
615 }
616}
617
618impl ModuleRegistry<ConfigGenModuleParams> {
619 pub fn attach_config_gen_params_by_id<T: ModuleInitParams>(
620 &mut self,
621 id: ModuleInstanceId,
622 kind: ModuleKind,
623 r#gen: T,
624 ) -> &mut Self {
625 let params = ConfigGenModuleParams::from_typed(r#gen)
626 .unwrap_or_else(|err| panic!("Invalid config gen params for {kind}: {err}"));
627 self.register_module(id, kind, params);
628 self
629 }
630
631 pub fn attach_config_gen_params<T: ModuleInitParams>(
632 &mut self,
633 kind: ModuleKind,
634 r#gen: T,
635 ) -> &mut Self {
636 let params = ConfigGenModuleParams::from_typed(r#gen)
637 .unwrap_or_else(|err| panic!("Invalid config gen params for {kind}: {err}"));
638 self.append_module(kind, params);
639 self
640 }
641}
642
643impl<M> ModuleInitRegistry<M>
644where
645 M: AsRef<dyn IDynCommonModuleInit + Send + Sync + 'static>,
646{
647 #[deprecated(
648 note = "You probably want `available_decoders` to support missing module kinds. If you really want a strict behavior, use `decoders_strict`"
649 )]
650 pub fn decoders<'a>(
651 &self,
652 modules: impl Iterator<Item = (ModuleInstanceId, &'a ModuleKind)>,
653 ) -> anyhow::Result<ModuleDecoderRegistry> {
654 self.decoders_strict(modules)
655 }
656
657 pub fn decoders_strict<'a>(
659 &self,
660 modules: impl Iterator<Item = (ModuleInstanceId, &'a ModuleKind)>,
661 ) -> anyhow::Result<ModuleDecoderRegistry> {
662 let mut decoders = BTreeMap::new();
663 for (id, kind) in modules {
664 let Some(init) = self.0.get(kind) else {
665 anyhow::bail!(
666 "Detected configuration for unsupported module id: {id}, kind: {kind}"
667 )
668 };
669
670 decoders.insert(id, (kind.clone(), init.as_ref().decoder()));
671 }
672 Ok(ModuleDecoderRegistry::from(decoders))
673 }
674
675 pub fn available_decoders<'a>(
677 &self,
678 modules: impl Iterator<Item = (ModuleInstanceId, &'a ModuleKind)>,
679 ) -> anyhow::Result<ModuleDecoderRegistry> {
680 let mut decoders = BTreeMap::new();
681 for (id, kind) in modules {
682 let Some(init) = self.0.get(kind) else {
683 warn!(target: LOG_CORE, "Unsupported module id: {id}, kind: {kind}");
684 continue;
685 };
686
687 decoders.insert(id, (kind.clone(), init.as_ref().decoder()));
688 }
689 Ok(ModuleDecoderRegistry::from(decoders))
690 }
691}
692
693#[derive(Debug, Default, Clone, Serialize, Deserialize)]
695pub struct EmptyGenParams {}
696
697pub trait ModuleInitParams: serde::Serialize + serde::de::DeserializeOwned {
698 type Local: DeserializeOwned + Serialize;
700 type Consensus: DeserializeOwned + Serialize;
702
703 fn from_parts(local: Self::Local, consensus: Self::Consensus) -> Self;
705
706 fn to_parts(self) -> (Self::Local, Self::Consensus);
708}
709
710#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Encodable, Decodable)]
711pub struct ServerModuleConsensusConfig {
712 pub kind: ModuleKind,
713 pub version: ModuleConsensusVersion,
714 #[serde(with = "::hex::serde")]
715 pub config: Vec<u8>,
716}
717
718#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Encodable, Decodable)]
724pub struct ClientModuleConfig {
725 pub kind: ModuleKind,
726 pub version: ModuleConsensusVersion,
727 #[serde(with = "::fedimint_core::encoding::as_hex")]
728 pub config: DynRawFallback<DynClientConfig>,
729}
730
731impl ClientModuleConfig {
732 pub fn from_typed<T: fedimint_core::core::ClientConfig>(
733 module_instance_id: ModuleInstanceId,
734 kind: ModuleKind,
735 version: ModuleConsensusVersion,
736 value: T,
737 ) -> anyhow::Result<Self> {
738 Ok(Self {
739 kind,
740 version,
741 config: fedimint_core::core::DynClientConfig::from_typed(module_instance_id, value)
742 .into(),
743 })
744 }
745
746 pub fn redecode_raw(
747 self,
748 modules: &ModuleDecoderRegistry,
749 ) -> Result<Self, crate::encoding::DecodeError> {
750 Ok(Self {
751 config: self.config.redecode_raw(modules)?,
752 ..self
753 })
754 }
755
756 pub fn is_kind(&self, kind: &ModuleKind) -> bool {
757 &self.kind == kind
758 }
759
760 pub fn kind(&self) -> &ModuleKind {
761 &self.kind
762 }
763}
764
765impl ClientModuleConfig {
766 pub fn cast<T>(&self) -> anyhow::Result<&T>
767 where
768 T: 'static,
769 {
770 self.config
771 .expect_decoded_ref()
772 .as_any()
773 .downcast_ref::<T>()
774 .context("can't convert client module config to desired type")
775 }
776}
777
778#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
782pub struct ServerModuleConfig {
783 pub private: JsonWithKind,
784 pub consensus: ServerModuleConsensusConfig,
785}
786
787impl ServerModuleConfig {
788 pub fn from(private: JsonWithKind, consensus: ServerModuleConsensusConfig) -> Self {
789 Self { private, consensus }
790 }
791
792 pub fn to_typed<T: TypedServerModuleConfig>(&self) -> anyhow::Result<T> {
793 let private = serde_json::from_value(self.private.value().clone())?;
794 let consensus = <T::Consensus>::consensus_decode_whole(
795 &self.consensus.config[..],
796 &ModuleRegistry::default(),
797 )?;
798
799 Ok(TypedServerModuleConfig::from_parts(private, consensus))
800 }
801}
802
803pub trait TypedServerModuleConsensusConfig:
805 DeserializeOwned + Serialize + Encodable + Decodable
806{
807 fn kind(&self) -> ModuleKind;
808
809 fn version(&self) -> ModuleConsensusVersion;
810
811 fn from_erased(erased: &ServerModuleConsensusConfig) -> anyhow::Result<Self> {
812 Ok(Self::consensus_decode_whole(
813 &erased.config[..],
814 &ModuleRegistry::default(),
815 )?)
816 }
817}
818
819pub trait TypedServerModuleConfig: DeserializeOwned + Serialize {
821 type Private: DeserializeOwned + Serialize;
824 type Consensus: TypedServerModuleConsensusConfig;
826
827 fn from_parts(private: Self::Private, consensus: Self::Consensus) -> Self;
829
830 fn to_parts(self) -> (ModuleKind, Self::Private, Self::Consensus);
832
833 fn to_erased(self) -> ServerModuleConfig {
835 let (kind, private, consensus) = self.to_parts();
836
837 ServerModuleConfig {
838 private: JsonWithKind::new(
839 kind,
840 serde_json::to_value(private).expect("serialization can't fail"),
841 ),
842 consensus: ServerModuleConsensusConfig {
843 kind: consensus.kind(),
844 version: consensus.version(),
845 config: consensus.consensus_encode_to_vec(),
846 },
847 }
848 }
849}
850
851#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Encodable, Decodable)]
852pub enum P2PMessage {
853 Aleph(Vec<u8>),
854 SessionSignature(secp256k1::schnorr::Signature),
855 SessionIndex(u64),
856 SignedSessionOutcome(SerdeModuleEncoding<SignedSessionOutcome>),
857 Checksum(sha256::Hash),
858 Dkg(DkgMessage),
859 Encodable(Vec<u8>),
860 #[encodable_default]
861 Default {
862 variant: u64,
863 bytes: Vec<u8>,
864 },
865}
866
867#[derive(Debug, PartialEq, Eq, Clone, Encodable, Decodable)]
868pub enum DkgMessage {
869 Hash(sha256::Hash),
870 Commitment(Vec<(G1Projective, G2Projective)>),
871 Share(Scalar),
872}
873
874impl Serialize for DkgMessage {
877 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
878 where
879 S: Serializer,
880 {
881 self.consensus_encode_to_hex().serialize(serializer)
882 }
883}
884
885impl<'de> Deserialize<'de> for DkgMessage {
886 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
887 where
888 D: Deserializer<'de>,
889 {
890 Self::consensus_decode_hex(
891 &String::deserialize(deserializer)?,
892 &ModuleDecoderRegistry::default(),
893 )
894 .map_err(serde::de::Error::custom)
895 }
896}
897
898pub const META_FEDERATION_NAME_KEY: &str = "federation_name";
901
902pub fn load_from_file<T: DeserializeOwned>(path: &Path) -> Result<T, anyhow::Error> {
903 let file = std::fs::File::open(path)?;
904 Ok(serde_json::from_reader(file)?)
905}
906
907#[cfg(test)]
908mod tests;