/* This file is part of DarkFi (https://dark.fi)
*
* Copyright (C) 2020-2023 Dyne.org foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
use std::{collections::HashMap, io};
use darkfi_serial::{Decodable, Encodable, SerialDecodable, SerialEncodable};
use crate::{Error, Result};
pub type Channel = (smol::channel::Sender, smol::channel::Receiver);
pub type Sender = (smol::channel::Sender, smol::channel::Receiver);
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Role {
Follower,
Candidate,
Leader,
}
#[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
pub struct SyncRequest {
pub id: u64,
pub logs_len: u64,
pub last_term: u64,
}
#[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
pub struct SyncResponse {
pub id: u64,
pub logs: Logs,
pub commit_length: u64,
pub leader_id: NodeId,
pub wipe: bool,
}
#[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
pub struct VoteRequest {
pub node_id: NodeId,
pub current_term: u64,
pub log_length: u64,
pub last_term: u64,
}
#[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
pub struct VoteResponse {
pub node_id: NodeId,
pub current_term: u64,
pub ok: bool,
}
#[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
pub struct LogRequest {
pub leader_id: NodeId,
pub current_term: u64,
pub prefix_len: u64,
pub prefix_term: u64,
pub commit_length: u64,
pub suffix: Logs,
}
#[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
pub struct LogResponse {
pub node_id: NodeId,
pub current_term: u64,
pub ack: u64,
pub ok: bool,
}
#[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
pub struct NodeIdMsg {
pub id: NodeId,
}
impl VoteResponse {
pub fn set_ok(&mut self, ok: bool) {
self.ok = ok;
}
}
#[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
pub struct BroadcastMsgRequest(pub Vec);
#[derive(Clone, Debug, SerialDecodable, SerialEncodable)]
pub struct Log {
pub term: u64,
pub msg: Vec,
}
#[derive(Clone, Debug, Eq, PartialEq, Hash, SerialDecodable, SerialEncodable)]
pub struct NodeId(pub String);
#[derive(Clone, Debug, SerialDecodable, SerialEncodable)]
pub struct Logs(pub Vec);
impl Logs {
pub fn len(&self) -> u64 {
self.0.len() as u64
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn slice_from(&self, start: u64) -> Option {
if self.len() >= start {
return Some(Self(self.0[start as usize..].to_vec()))
}
None
}
pub fn slice_to(&self, end: u64) -> Self {
for i in (0..end).rev() {
if self.len() >= i {
return Self(self.0[..i as usize].to_vec())
}
}
Self(vec![])
}
pub fn get(&self, index: u64) -> Result {
match self.0.get(index as usize) {
Some(l) => Ok(l.clone()),
None => Err(Error::RaftError("unable to indexing into vector".into())),
}
}
pub fn to_vec(&self) -> Vec {
self.0.clone()
}
}
#[derive(Clone, Debug)]
pub struct MapLength(pub HashMap);
impl MapLength {
pub fn get(&self, key: &NodeId) -> Result {
match self.0.get(key) {
Some(v) => Ok(*v),
None => Err(Error::RaftError("unable to indexing into HashMap".into())),
}
}
pub fn insert(&mut self, key: &NodeId, value: u64) {
self.0.insert(key.clone(), value);
}
}
#[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
pub struct NetMsg {
pub id: u64,
pub recipient_id: Option,
pub method: NetMsgMethod,
pub payload: Vec,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum NetMsgMethod {
LogResponse = 0,
LogRequest = 1,
VoteResponse = 2,
VoteRequest = 3,
BroadcastRequest = 4,
NodeIdMsg = 5,
}
impl Encodable for NetMsgMethod {
fn encode(&self, s: S) -> core::result::Result {
let len: usize = match self {
Self::LogResponse => 0,
Self::LogRequest => 1,
Self::VoteResponse => 2,
Self::VoteRequest => 3,
Self::BroadcastRequest => 4,
Self::NodeIdMsg => 5,
};
(len as u8).encode(s)
}
}
impl Decodable for NetMsgMethod {
fn decode(d: D) -> core::result::Result {
let com: u8 = Decodable::decode(d)?;
Ok(match com {
0 => Self::LogResponse,
1 => Self::LogRequest,
2 => Self::VoteResponse,
3 => Self::VoteRequest,
4 => Self::BroadcastRequest,
_ => Self::NodeIdMsg,
})
}
}