scirs2_metrics/optimization/distributed_advanced/consensus/
coordinator.rs1use super::{
6 majority::MajorityConsensus, pbft::PbftConsensus, proof_of_stake::ProofOfStakeConsensus,
7 raft::RaftConsensus,
8};
9use crate::error::{MetricsError, Result};
10
11#[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 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 )), 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}