use super::types::*;
use serde::{Deserialize, Serialize};
use std::time::SystemTime;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BftMessage {
Request {
client_id: String,
operation: RdfOperation,
timestamp: SystemTime,
signature: Option<Vec<u8>>,
},
PrePrepare {
view: ViewNumber,
sequence: SequenceNumber,
digest: Vec<u8>,
request: Box<BftMessage>,
},
Prepare {
view: ViewNumber,
sequence: SequenceNumber,
digest: Vec<u8>,
node_id: NodeId,
},
Commit {
view: ViewNumber,
sequence: SequenceNumber,
digest: Vec<u8>,
node_id: NodeId,
},
Reply {
view: ViewNumber,
sequence: SequenceNumber,
client_id: String,
result: OperationResult,
timestamp: SystemTime,
},
Checkpoint {
sequence: SequenceNumber,
state_digest: Vec<u8>,
node_id: NodeId,
},
ViewChange {
new_view: ViewNumber,
node_id: NodeId,
last_sequence: SequenceNumber,
checkpoints: Vec<CheckpointProof>,
prepared_messages: Vec<PreparedProof>,
},
NewView {
view: ViewNumber,
view_changes: Vec<BftMessage>,
pre_prepares: Vec<BftMessage>,
},
}
impl BftMessage {
pub fn digest(&self) -> Vec<u8> {
use sha2::{Digest, Sha256};
let serialized =
oxicode::serde::encode_to_vec(self, oxicode::config::standard()).unwrap_or_default();
Sha256::digest(&serialized).to_vec()
}
pub fn view(&self) -> Option<ViewNumber> {
match self {
BftMessage::PrePrepare { view, .. }
| BftMessage::Prepare { view, .. }
| BftMessage::Commit { view, .. }
| BftMessage::Reply { view, .. }
| BftMessage::NewView { view, .. } => Some(*view),
BftMessage::ViewChange { new_view, .. } => Some(*new_view),
_ => None,
}
}
pub fn sequence(&self) -> Option<SequenceNumber> {
match self {
BftMessage::PrePrepare { sequence, .. }
| BftMessage::Prepare { sequence, .. }
| BftMessage::Commit { sequence, .. }
| BftMessage::Reply { sequence, .. } => Some(*sequence),
BftMessage::Checkpoint { sequence, .. } => Some(*sequence),
BftMessage::ViewChange { last_sequence, .. } => Some(*last_sequence),
_ => None,
}
}
pub fn node_id(&self) -> Option<NodeId> {
match self {
BftMessage::Prepare { node_id, .. }
| BftMessage::Commit { node_id, .. }
| BftMessage::Checkpoint { node_id, .. }
| BftMessage::ViewChange { node_id, .. } => Some(*node_id),
_ => None,
}
}
pub fn is_consensus_message(&self) -> bool {
matches!(
self,
BftMessage::PrePrepare { .. } | BftMessage::Prepare { .. } | BftMessage::Commit { .. }
)
}
pub fn is_view_change_message(&self) -> bool {
matches!(
self,
BftMessage::ViewChange { .. } | BftMessage::NewView { .. }
)
}
}