vrf-pbft 0.1.0

A Rust implementation of VRF-enhanced PBFT consensus protocol
Documentation
use serde::{Deserialize, Serialize};

use crate::types::{hash, Block, Hash, NodeId};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum MessageType {
    PrePrepare,
    Prepare,
    Commit,
    Reply,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Vote {
    pub voter: NodeId,
    pub approve: bool,
}

impl Vote {
    pub fn approve(voter: NodeId) -> Self {
        Self {
            voter,
            approve: true,
        }
    }

    pub fn reject(voter: NodeId) -> Self {
        Self {
            voter,
            approve: false,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
    pub source: NodeId,
    pub round: u64,
    pub msg_type: MessageType,
    pub block_hash: Hash,
    pub vote: Option<Vote>,
    pub block: Option<Block>,
}

impl Message {
    pub fn pre_prepare(source: NodeId, round: u64, block: Block) -> Self {
        let block_hash = block.hash();
        Self {
            source,
            round,
            msg_type: MessageType::PrePrepare,
            block_hash,
            vote: None,
            block: Some(block),
        }
    }

    pub fn prepare(source: NodeId, round: u64, block_hash: Hash, approve: bool) -> Self {
        let vote = if approve {
            Vote::approve(source)
        } else {
            Vote::reject(source)
        };
        Self {
            source,
            round,
            msg_type: MessageType::Prepare,
            block_hash,
            vote: Some(vote),
            block: None,
        }
    }

    pub fn commit(source: NodeId, round: u64, block_hash: Hash, approve: bool) -> Self {
        let vote = if approve {
            Vote::approve(source)
        } else {
            Vote::reject(source)
        };
        Self {
            source,
            round,
            msg_type: MessageType::Commit,
            block_hash,
            vote: Some(vote),
            block: None,
        }
    }

    pub fn reply(source: NodeId, round: u64, block: Block) -> Self {
        let block_hash = block.hash();
        Self {
            source,
            round,
            msg_type: MessageType::Reply,
            block_hash,
            vote: None,
            block: Some(block),
        }
    }

    pub fn hash(&self) -> Hash {
        let bytes = bincode::serialize(self).expect("message serialization failed");
        hash(&bytes)
    }
}