Skip to main content

confium_coordinator/coordinator/
capabilities.rs

1//! Coordinator capability advertisement — feature flags.
2
3use serde::{Deserialize, Serialize};
4
5/// Capabilities a coordinator supports.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct CoordinatorCapabilities {
8    /// Supported threshold schemes.
9    pub schemes: Vec<String>,
10    /// Supported algorithms.
11    pub algorithms: Vec<String>,
12    /// Maximum threshold the coordinator can handle.
13    pub max_threshold: u32,
14    /// Maximum party count.
15    pub max_party_count: u32,
16    /// Whether batch signing is supported.
17    pub supports_batch: bool,
18    /// Whether idempotency keys are supported.
19    pub supports_idempotency: bool,
20    /// Whether backpressure enforcement is active.
21    pub supports_backpressure: bool,
22    /// Protocol version.
23    pub protocol_version: u32,
24}
25
26impl Default for CoordinatorCapabilities {
27    fn default() -> Self {
28        Self {
29            schemes: vec!["CMP20".into(), "FROST-P256".into(), "GG18".into()],
30            algorithms: vec!["ECDSA-P256".into(), "Ed25519".into()],
31            max_threshold: 32,
32            max_party_count: 64,
33            supports_batch: true,
34            supports_idempotency: true,
35            supports_backpressure: true,
36            protocol_version: 1,
37        }
38    }
39}
40
41impl CoordinatorCapabilities {
42    /// Check if a scheme is supported.
43    pub fn supports_scheme(&self, scheme: &str) -> bool {
44        self.schemes.iter().any(|s| s == scheme)
45    }
46
47    /// Check if an algorithm is supported.
48    pub fn supports_algorithm(&self, alg: &str) -> bool {
49        self.algorithms.iter().any(|a| a == alg)
50    }
51
52    /// Check if a threshold/party combination is within limits.
53    pub fn supports_config(&self, threshold: u32, party_count: u32) -> bool {
54        threshold <= self.max_threshold && party_count <= self.max_party_count
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn default_has_schemes() {
64        let caps = CoordinatorCapabilities::default();
65        assert!(caps.supports_scheme("CMP20"));
66        assert!(!caps.supports_scheme("UnknownScheme"));
67    }
68
69    #[test]
70    fn algorithm_check() {
71        let caps = CoordinatorCapabilities::default();
72        assert!(caps.supports_algorithm("Ed25519"));
73        assert!(!caps.supports_algorithm("RSA"));
74    }
75
76    #[test]
77    fn config_within_limits() {
78        let caps = CoordinatorCapabilities::default();
79        assert!(caps.supports_config(5, 10));
80        assert!(!caps.supports_config(100, 10));
81        assert!(!caps.supports_config(5, 100));
82    }
83
84    #[test]
85    fn serializes() {
86        let caps = CoordinatorCapabilities::default();
87        let json = serde_json::to_string(&caps).unwrap();
88        assert!(json.contains("schemes"));
89        assert!(json.contains("supports_batch"));
90    }
91}