scirs2_metrics/optimization/distributed_advanced/consensus/
coordinator.rs

1//! Consensus Coordinator Implementation
2//!
3//! Coordinates different consensus algorithms for distributed optimization.
4
5use super::{
6    majority::MajorityConsensus, pbft::PbftConsensus, proof_of_stake::ProofOfStakeConsensus,
7    raft::RaftConsensus,
8};
9use crate::error::{MetricsError, Result};
10
11/// Consensus coordinator that manages different consensus algorithms
12#[derive(Debug)]
13pub struct ConsensusCoordinator {
14    algorithm_type: ConsensusType,
15    raft: Option<RaftConsensus>,
16    pbft: Option<PbftConsensus>,
17    pos: Option<ProofOfStakeConsensus>,
18    majority: Option<MajorityConsensus>,
19}
20
21#[derive(Debug, Clone)]
22pub enum ConsensusType {
23    Raft,
24    Pbft,
25    ProofOfStake,
26    Majority,
27}
28
29impl ConsensusCoordinator {
30    /// Create new consensus coordinator from configuration
31    pub fn new(
32        config: crate::optimization::distributed::config::ConsensusConfig,
33    ) -> crate::error::Result<Self> {
34        use crate::optimization::distributed::config::ConsensusAlgorithm;
35        match config.algorithm {
36            ConsensusAlgorithm::Raft => Ok(Self::new_raft(
37                config.node_id.unwrap_or_else(|| "default".to_string()),
38                config.peers.unwrap_or_default(),
39            )),
40            ConsensusAlgorithm::Pbft => Ok(Self::new_pbft(
41                config.node_id.unwrap_or_else(|| "default".to_string()),
42                config.peers.unwrap_or_default(),
43            )),
44            ConsensusAlgorithm::ProofOfStake => Ok(Self::new_proof_of_stake(
45                config.node_id.unwrap_or_else(|| "default".to_string()),
46                100,
47            )),
48            ConsensusAlgorithm::SimpleMajority => Ok(Self::new_majority(
49                config.node_id.unwrap_or_else(|| "default".to_string()),
50                config.peers.unwrap_or_default(),
51            )),
52            ConsensusAlgorithm::DelegatedProofOfStake => Ok(Self::new_proof_of_stake(
53                config.node_id.unwrap_or_else(|| "default".to_string()),
54                100,
55            )), // Treat similar to ProofOfStake for now
56            ConsensusAlgorithm::None => Err(crate::error::MetricsError::ConsensusError(
57                "No consensus algorithm specified".to_string(),
58            )),
59        }
60    }
61
62    pub fn new_raft(node_id: String, peers: Vec<String>) -> Self {
63        Self {
64            algorithm_type: ConsensusType::Raft,
65            raft: Some(RaftConsensus::new(node_id, peers)),
66            pbft: None,
67            pos: None,
68            majority: None,
69        }
70    }
71
72    pub fn new_pbft(node_id: String, replicas: Vec<String>) -> Self {
73        Self {
74            algorithm_type: ConsensusType::Pbft,
75            raft: None,
76            pbft: Some(PbftConsensus::new(node_id, replicas)),
77            pos: None,
78            majority: None,
79        }
80    }
81
82    pub fn new_proof_of_stake(node_id: String, stake: u64) -> Self {
83        Self {
84            algorithm_type: ConsensusType::ProofOfStake,
85            raft: None,
86            pbft: None,
87            pos: Some(ProofOfStakeConsensus::new(node_id, stake)),
88            majority: None,
89        }
90    }
91
92    pub fn new_majority(node_id: String, nodes: Vec<String>) -> Self {
93        Self {
94            algorithm_type: ConsensusType::Majority,
95            raft: None,
96            pbft: None,
97            pos: None,
98            majority: Some(MajorityConsensus::new(node_id, nodes)),
99        }
100    }
101
102    pub fn propose(&mut self, data: Vec<u8>) -> Result<String> {
103        match self.algorithm_type {
104            ConsensusType::Raft => {
105                if let Some(ref mut raft) = self.raft {
106                    raft.start_election()?;
107                    Ok("raft_proposal".to_string())
108                } else {
109                    Err(MetricsError::InvalidOperation(
110                        "Raft not initialized".into(),
111                    ))
112                }
113            }
114            ConsensusType::Pbft => {
115                if let Some(ref mut pbft) = self.pbft {
116                    let msg = pbft.pre_prepare(data)?;
117                    Ok(format!("pbft_{}", msg.sequence))
118                } else {
119                    Err(MetricsError::InvalidOperation(
120                        "PBFT not initialized".into(),
121                    ))
122                }
123            }
124            ConsensusType::ProofOfStake => {
125                if let Some(ref pos) = self.pos {
126                    let validator = pos.select_validator()?;
127                    Ok(format!("pos_{}", validator))
128                } else {
129                    Err(MetricsError::InvalidOperation("PoS not initialized".into()))
130                }
131            }
132            ConsensusType::Majority => {
133                if let Some(ref mut majority) = self.majority {
134                    let proposal_id = majority.propose(data)?;
135                    Ok(format!("majority_{}", proposal_id))
136                } else {
137                    Err(MetricsError::InvalidOperation(
138                        "Majority not initialized".into(),
139                    ))
140                }
141            }
142        }
143    }
144}