scirs2_metrics/optimization/distributed_advanced/consensus/
pbft.rs1use crate::error::{MetricsError, Result};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct PbftConsensus {
12 node_id: String,
13 view: u64,
14 sequence_number: u64,
15 replicas: Vec<String>,
16 is_primary: bool,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct PbftMessage {
21 pub view: u64,
22 pub sequence: u64,
23 pub digest: String,
24 pub sender: String,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct PbftState {
30 pub current_view: u64,
31 pub sequence_number: u64,
32 pub phase: PbftPhase,
33 pub committed_messages: HashMap<u64, String>,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38pub enum PbftPhase {
39 PrePrepare,
40 Prepare,
41 Commit,
42 Reply,
43}
44
45impl Default for PbftState {
46 fn default() -> Self {
47 Self {
48 current_view: 0,
49 sequence_number: 0,
50 phase: PbftPhase::PrePrepare,
51 committed_messages: HashMap::new(),
52 }
53 }
54}
55
56impl PbftConsensus {
57 pub fn new(node_id: String, replicas: Vec<String>) -> Self {
58 let is_primary = replicas.first() == Some(&node_id);
59 Self {
60 node_id,
61 view: 0,
62 sequence_number: 0,
63 replicas,
64 is_primary,
65 }
66 }
67
68 pub fn pre_prepare(&mut self, request: Vec<u8>) -> Result<PbftMessage> {
69 if !self.is_primary {
70 return Err(MetricsError::InvalidOperation(
71 "Only primary can send pre-prepare".into(),
72 ));
73 }
74
75 self.sequence_number += 1;
76 Ok(PbftMessage {
77 view: self.view,
78 sequence: self.sequence_number,
79 digest: format!("{:?}", request),
80 sender: self.node_id.clone(),
81 })
82 }
83
84 pub fn prepare(&mut self, message: PbftMessage) -> Result<bool> {
85 if message.view != self.view {
87 return Ok(false);
88 }
89 Ok(true)
90 }
91
92 pub fn commit(&mut self, message: PbftMessage) -> Result<bool> {
93 Ok(true)
95 }
96}