Crates.io | bft-core |
lib.rs | bft-core |
version | 0.1.0 |
source | src |
created_at | 2019-05-05 08:20:21.33019 |
updated_at | 2019-05-05 08:20:21.33019 |
description | An efficient and stable Rust library of BFT core for distributed system. |
homepage | |
repository | https://github.com/KaoImin/bft-core |
max_upload_size | |
id | 132209 |
size | 65,499 |
An efficient and stable Rust library of BFT protocol for distributed system.
BFT(Byzantine Fault Tolerance) comprise a class of consensus algorithms that achieve byzantine fault tolerance. BFT can guarantee liveness and safety for a distributed system where there are not more than 33% malicious byzantine nodes, and thus BFT is often used in the blockchain network.
BFT is a State Machine Replication algorithm, and some states are shown below:
NewHeight -> (Propose -> Prevote -> Precommit)+ -> Commit -> NewHeight -> ...
+-------------------------------------+
| | (Wait new block)
v |
+-----------+ +-----+-----+
+----------> | Propose +--------------+ | NewHeight |
| +-----------+ | +-----------+
| | ^
| (Else) | |
| v |
+-----+-----+ +-----------+ |
| Precommit | <------------------------+ Prevote | | (Wait RichStatus)
+-----+-----+ +-----------+ |
| |
| (When +2/3 Precommits for the block found) |
v |
+--------------------------------------------------------------+-----+
| Commit |
| |
| * Generate Proof; |
| * Set CommitTime = now; |
+--------------------------------------------------------------------+
A complete BFT model consists of 4 essential parts:
Consensus Module, the consensus algorithm module includes signature verification, proof generation, version check, etc.;
State Machine, the BFT state machine is focused on consensus proposal;
Transport Module, the network for consensus module to communicate with other modules;
Wal Module, the place saving BFT logs.
NOTICE: The bft-core only provides a basic BFT state machine and does not support the advanced functions such as signature verification, proof generation, compact block, etc. These functions are in consensus module rather than bft-core library.
The bft-core provides async_verify
feature to verify transcation after received a proposal. BFT state machine will check the verify result of the proposal before Precommit
step. If it has not received the result of the proposal yet, it will wait for an extra 1/2 of the consensus duration.
If bft-core works correctly, it needs to receive 4 types of message: Proposal
, Vote
, Feed
, Status
. And bft-core can send 4 types of message: Proposal
, Vote
, Commit
and GetProposalRequest
. Besides, bft-core also provides Stop
and Start
message that can control state machine stop or go on. These types of messages consist in the enum CoreInput
and CoreOutput
:
enum CoreInput {
Proposal(Proposal),
Vote(Vote),
Feed(Feed),
Status(Status),
Commit(Commit),
#[cfg(feature = "async_verify")]
VerifyResp(VerifyResp),
Pause,
Start,
}
enum CoreOutput {
Proposal(Proposal),
Vote(Vote),
Commit(Commit),
GetProposalRequest(u64),
}
For detailed introduction, click here.
First, add bft-core to your Cargo.toml
:
[dependencies]
bft-core = { git = "https://github.com/KaoImin/bft-core.git", branch = "develop" }
If you want to use async_verify
feature, needs to add following codes:
[features]
async_verify = ["bft-core/async_verify"]
Second, add BFT and channel to your crate as following:
extern crate bft_core as bft;
use bft::{types::*, Core, FromCore};
Third, initialize a BFT core:
let bft = BFT::new(address);
The address
here is the address of this node with type Vec<u8>
.
What needs to illustrate is that the BFT machine is in stop step by default, therefore, the first thing is send CoreInput::Start
message. Use send_bft_msg()
function to send a message to BFT state machine as following:
bft.send_bft_msg(CoreInput::Start).map_err();
bft.send_bft_msg(CoreInput::Status(status)).map_err();
// only in feature async_verify
bft.send_bft_msg(CoreInput::VerifyResq(result)).map_err();
And implement the trait FromCore
to receive messages from BFT core.
If you want to use the BFT height to do some verify, use get_height
function as following:
let height: u64 = bft.get_height();
This an open source project under the MIT License.