1#![deny(missing_docs)]
7#![recursion_limit = "512"]
8#![allow(clippy::mutable_key_type)]
9
10mod codec;
12pub mod error;
14pub mod overlord;
16pub mod serde_hex;
18mod serde_multi_hex;
20mod smr;
22mod state;
24mod timer;
26pub mod types;
28mod utils;
30mod wal;
32
33pub use self::overlord::Overlord;
34pub use self::overlord::OverlordHandler;
35pub use self::utils::auth_manage::{extract_voters, get_leader};
36pub use creep::Context;
37pub use wal::WalInfo;
38
39use std::error::Error;
40use std::fmt::Debug;
41
42use async_trait::async_trait;
43use bytes::Bytes;
44use serde::{Deserialize, Serialize};
45
46use crate::error::ConsensusError;
47use crate::types::{Address, Commit, Hash, Node, OverlordMsg, Signature, Status, ViewChangeReason};
48
49pub type ConsensusResult<T> = std::result::Result<T, ConsensusError>;
51
52const INIT_HEIGHT: u64 = 0;
53const INIT_ROUND: u64 = 0;
54
55#[async_trait]
57pub trait Consensus<T: Codec>: Send + Sync {
58 async fn get_block(
60 &self,
61 ctx: Context,
62 height: u64,
63 ) -> Result<(T, Hash), Box<dyn Error + Send>>;
64
65 async fn check_block(
68 &self,
69 ctx: Context,
70 height: u64,
71 hash: Hash,
72 block: T,
73 ) -> Result<(), Box<dyn Error + Send>>;
74
75 async fn commit(
77 &self,
78 ctx: Context,
79 height: u64,
80 commit: Commit<T>,
81 ) -> Result<Status, Box<dyn Error + Send>>;
82
83 async fn get_authority_list(
85 &self,
86 ctx: Context,
87 height: u64,
88 ) -> Result<Vec<Node>, Box<dyn Error + Send>>;
89
90 async fn broadcast_to_other(
92 &self,
93 ctx: Context,
94 msg: OverlordMsg<T>,
95 ) -> Result<(), Box<dyn Error + Send>>;
96
97 async fn transmit_to_relayer(
99 &self,
100 ctx: Context,
101 addr: Address,
102 msg: OverlordMsg<T>,
103 ) -> Result<(), Box<dyn Error + Send>>;
104
105 fn report_error(&self, ctx: Context, error: ConsensusError);
107
108 fn report_view_change(&self, ctx: Context, height: u64, round: u64, reason: ViewChangeReason);
110}
111
112pub trait Codec: Clone + Debug + Send + PartialEq + Eq {
114 fn encode(&self) -> Result<Bytes, Box<dyn Error + Send>>;
116
117 fn decode(data: Bytes) -> Result<Self, Box<dyn Error + Send>>;
119}
120
121#[async_trait]
123pub trait Wal {
124 async fn save(&self, info: Bytes) -> Result<(), Box<dyn Error + Send>>;
126
127 async fn load(&self) -> Result<Option<Bytes>, Box<dyn Error + Send>>;
129}
130
131pub trait Crypto: Send {
133 fn hash(&self, msg: Bytes) -> Hash;
135
136 fn sign(&self, hash: Hash) -> Result<Signature, Box<dyn Error + Send>>;
138
139 fn aggregate_signatures(
141 &self,
142 signatures: Vec<Signature>,
143 voters: Vec<Address>,
144 ) -> Result<Signature, Box<dyn Error + Send>>;
145
146 fn verify_signature(
148 &self,
149 signature: Signature,
150 hash: Hash,
151 voter: Address,
152 ) -> Result<(), Box<dyn Error + Send>>;
153
154 fn verify_aggregated_signature(
156 &self,
157 aggregate_signature: Signature,
158 msg_hash: Hash,
159 voters: Vec<Address>,
160 ) -> Result<(), Box<dyn Error + Send>>;
161}
162
163#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
165pub struct DurationConfig {
166 pub propose_ratio: u64,
168 pub prevote_ratio: u64,
170 pub precommit_ratio: u64,
172 pub brake_ratio: u64,
174}
175
176impl DurationConfig {
177 pub fn new(
179 propose_ratio: u64,
180 prevote_ratio: u64,
181 precommit_ratio: u64,
182 brake_ratio: u64,
183 ) -> Self {
184 DurationConfig {
185 propose_ratio,
186 prevote_ratio,
187 precommit_ratio,
188 brake_ratio,
189 }
190 }
191
192 pub(crate) fn get_propose_config(&self) -> (u64, u64) {
193 (self.propose_ratio, 10u64)
194 }
195
196 pub(crate) fn get_prevote_config(&self) -> (u64, u64) {
197 (self.prevote_ratio, 10u64)
198 }
199
200 pub(crate) fn get_precommit_config(&self) -> (u64, u64) {
201 (self.precommit_ratio, 10u64)
202 }
203
204 pub(crate) fn get_brake_config(&self) -> (u64, u64) {
205 (self.brake_ratio, 10u64)
206 }
207}
208
209#[cfg(test)]
210mod test {
211 use super::DurationConfig;
212
213 #[test]
214 fn test_duration_config() {
215 let config = DurationConfig::new(1, 2, 3, 4);
216 assert_eq!(config.get_propose_config(), (1, 10));
217 assert_eq!(config.get_prevote_config(), (2, 10));
218 assert_eq!(config.get_precommit_config(), (3, 10));
219 assert_eq!(config.get_brake_config(), (4, 10));
220 }
221}