scirs2_metrics/optimization/distributed_advanced/consensus/
majority.rs

1//! Simple Majority Consensus Implementation
2//!
3//! Implementation of simple majority voting consensus for distributed optimization.
4
5use crate::error::{MetricsError, Result};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9/// Simple majority consensus implementation
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct MajorityConsensus {
12    node_id: String,
13    nodes: Vec<String>,
14    votes: HashMap<String, bool>,
15    proposal_id: u64,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct Vote {
20    voter_id: String,
21    proposal_id: u64,
22    decision: bool,
23}
24
25/// Simple majority algorithm state
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct MajorityState {
28    pub current_proposal_id: u64,
29    pub active_votes: HashMap<String, Vote>,
30    pub completed_proposals: Vec<u64>,
31    pub consensus_threshold: f64,
32}
33
34impl Default for MajorityState {
35    fn default() -> Self {
36        Self {
37            current_proposal_id: 0,
38            active_votes: HashMap::new(),
39            completed_proposals: Vec::new(),
40            consensus_threshold: 0.5, // Simple majority (>50%)
41        }
42    }
43}
44
45impl MajorityConsensus {
46    pub fn new(node_id: String, nodes: Vec<String>) -> Self {
47        Self {
48            node_id,
49            nodes,
50            votes: HashMap::new(),
51            proposal_id: 0,
52        }
53    }
54
55    pub fn propose(&mut self, data: Vec<u8>) -> Result<u64> {
56        self.proposal_id += 1;
57        self.votes.clear();
58        // Auto-vote for own proposal
59        self.votes.insert(self.node_id.clone(), true);
60        Ok(self.proposal_id)
61    }
62
63    pub fn vote(&mut self, vote: Vote) -> Result<()> {
64        if vote.proposal_id != self.proposal_id {
65            return Err(MetricsError::InvalidOperation("Invalid proposal ID".into()));
66        }
67
68        self.votes.insert(vote.voter_id, vote.decision);
69        Ok(())
70    }
71
72    pub fn has_majority(&self) -> bool {
73        let yes_votes = self.votes.values().filter(|&&v| v).count();
74        let total_nodes = self.nodes.len();
75        yes_votes > total_nodes / 2
76    }
77
78    pub fn is_decided(&self) -> bool {
79        let total_votes = self.votes.len();
80        let total_nodes = self.nodes.len();
81
82        // Check if we have enough votes to make a decision
83        let yes_votes = self.votes.values().filter(|&&v| v).count();
84        let no_votes = total_votes - yes_votes;
85
86        // Majority reached
87        yes_votes > total_nodes / 2 || no_votes > total_nodes / 2
88    }
89
90    pub fn get_result(&self) -> Option<bool> {
91        if self.is_decided() {
92            Some(self.has_majority())
93        } else {
94            None
95        }
96    }
97}