Giter Site home page Giter Site logo

cardinal-cryptography / alephbft Goto Github PK

View Code? Open in Web Editor NEW
48.0 9.0 27.0 3.05 MB

Rust implementation of Aleph consensus protocol

Home Page: https://cardinal-cryptography.github.io/AlephBFT/index.html

License: Apache License 2.0

Rust 99.76% Shell 0.24%
blockchain consensus asynchronous bft

alephbft's Introduction

Crate Docs Build Status Apache 2.0 Licensed cargo-audit

Overview

AlephBFT is an asynchronous and Byzantine fault-tolerant consensus protocol aimed at ordering arbitrary messages (transactions). It has been designed to operate continuously under conditions where there is no bound on message-delivery delay and under the assumption that there is a significant probability of malicious behavior, making it an excellent fit for blockchain-related applications. For more information, check the white paper.

This repository contains a Rust implementation of AlephBFT that offers a convenient API enabling seamless application to various problems. The prime application of the repository is the consensus engine (sometimes called the "finality gadget") of the Aleph Zero blockchain.

The code is split into several Rust packages, each having its own directory - see the Cargo.toml file, which defines the layout of the whole workspace. The main package, aleph-bft, is located in the consensus directory. Additionally, every other package has a short README describing its role in the AlephBFT toolset.

Documentation

Every package is documented on docs.rs. Comprehensive documentation is available as a mdBook.

The book can be built locally (assuming you have installed rustup):

cargo install mdbook
cd docs
mdbook serve --open

Implementation status

Highlights:

  • The protocol is asynchronous, so it's driven by consensus events as opposed to some clock ticks.
  • The performance is still optimal in a partially synchronous environment.
  • BFT - secure if less than one third of the committee is malicious.
  • Secure against fork bombs.
  • Lowered network overhead of sending DAG parent information.
  • Thorough testing, including malicious scenarios, and high code coverage.

More details are available in the book.

Using the crate

  • Import AlephBFT in your crate
    [dependencies]
    aleph-bft = "^0.36"
  • The main entry point is the run_session function, which returns a Future that runs the consensus algorithm. To call this function, you need to pass a configuration (defaults are available in the package), and implement certain traits, which will provide all the necessary functionalities, such as networking and message signing. A comprehensive guide is available in the documentation.

Examples

We provide two basic examples of running AlephBFT, both of which are not cryptographically secure, and assume honest, but possibly malfunctioning, participants.

The first one, ordering, implements a simple node that produces data items, and then waits for them to be finalized. It can also perform a simulated crash after creating a specified number of items.

For example, you may run the following command:

cd ./examples/ordering
./run.sh

that will launch 2 properly working nodes, and 2 nodes that will crash 3 times each. The delay before relaunching a crashed node will be set to 1 second. A faulty node will create 25 items before every crash, and another 25 in the end. Every node will therefore create 100 items in total, and then wait for other nodes before finishing its run.

See:

./run.sh -h

for further details.

Note that if the number of properly working nodes is less or equal than two times the number of faulty nodes, they will be unable to advance the protocol on their own.

The script will try to start nodes at predefined IP addresses, 127.0.0.1:100XX, where XX denotes the node id. If the port is unavailable, the node will log an error and keep trying to aquire it, waiting 10 seconds between consecutive attempts.

Running this script will result in generating log files node0.log, node1.log, ... corresponding to subsequent nodes. A directory called aleph-bft-examples-ordering-backup will be created to store data required by the crash recovery mechanism, and the logs from subsequent runs will be appended to existing log files. The cache and logs will be automatically cleared when launching the script again.

The second example, blockchain, is meant for benchmarking AlephBFT in the blockchain setting. It implements a simple round-robin blockchain assuming honest participation. The easiest way to run it is to use the provided script as follows (assuming we start in the root directory):

cd ./examples/blockchain
./run.sh 5

where, again, 5 denotes the number of nodes that will be started. Here we only assume that the address 127.0.0.1:43000 is available, as the network implementation contains a simple node discovery mechanism. The achieved transactions per second will be among the final log messages in these files.

For further details, see

cargo run -- --help

Dependencies

The repository is mainly self-contained. It is implemented using Rust's async features and depends only on the futures crate from the standard library. Moreover, it has some usual dependencies like log and rand and one bigger for encoding, namely parity-scale-codec. In future work, we plan to get rid of this dependency.

Toolchain

This release was built and tested against the nightly-2022-10-30 Rust toolchain. If you want to use another version, edit the rust-toolchain file, or use an override with higher priority.

Tests

There are many unit tests and several integration tests that may be run by standard command cargo test --lib or cargo test --lib --skip medium if you want to run just small tests. Alternatively, you may run the run_local_pipeline.sh script.

Fuzzing

We provide fuzzing tests that try to crash the whole application by creating arbitrary data for the network layer and feeding it into the member implementation. To run those tests you need to install afl and cargo-fuzz. cargo-fuzz requires you to use a nightly Rust toolchain. afl differs from cargo-fuzz in that it requires so called corpus data to operate, i.e. some non-empty data set that do not crash the application. Both tools are using LLVM's instrumentation capabilities in order to guide the fuzzing process basing on code-coverage statistics.

cargo install cargo-fuzz
cargo install afl

cargo-fuzz/libfuzzer

cargo fuzz run --features="libfuzz" fuzz_target

afl

You will need to generate some seed data first in order to run it.

# create some random input containing network data from a locally executed test
mkdir afl_in
cargo build --bin gen_fuzz
./target/debug/gen_fuzz >./afl_in/seed

You might need to reconfigure your operating system in order to proceed - in such a case follow the instructions printed by the afl tool in your terminal.

cargo afl build --features="afl-fuzz" --bin fuzz_target_afl
cargo afl fuzz -i afl_in -o afl_out target/debug/fuzz_target_afl

The gen_fuzz binary is also able to verify data for the afl tool.

cargo build --bin gen_fuzz
./target/debug/gen_fuzz | ./target/debug/gen_fuzz --check-fuzz

Code Coverage

You may generate the code coverage summary using the gen_cov_data.sh script and then a detailed raport for every file with cov_report.sh. Make sure to first install all the required tools with install_cov_tools.sh.

Resources

Future work

  • Asynchronous liveness is an important theoretical property and there is a lot of technical sophistication that comes in the design of AlephBFT in order to achieve it, however on the practical side there is still little evidence that performing such attacks against liveness in real-world scenarios is possible. Still, no matter how unlikely such attacks might be, we take them very seriously and plan to add randomness to AlephBFT in one of the future releases. We decided to go for a version without randomness first, as it gives an incredibly simple and at the same time secure and robust BFT consensus protocol. Adding randomness introduces some complexity into the protocol, so it makes sense to add it on top of a well-tested, working product. The API of the protocol will not change, and we will make the use of randomness configurable.
  • We see a big value in keeping a critical piece of code such as a consensus protocol as self-contained as possible, so we would like to get rid of the only major dependency - parity-scale-codec

License

AlephBFT is licensed under the terms of the Apache License 2.0.

Funding

The implementation in this repository is funded by Aleph Zero Foundation.

alephbft's People

Contributors

adamgagol avatar artemis-cc avatar damianstraszak avatar dependabot[bot] avatar fixxxedpoint avatar ggawryal avatar h4nsu avatar joschisan avatar joshuajbouw avatar kostekiv avatar krzysztofziobro avatar lesniak43 avatar maan2003 avatar maciejnems avatar maciejzelaszczyk avatar marcin-radecki avatar michalseweryn avatar mike1729 avatar nicholasgasior avatar obrok avatar pmikolajczyk41 avatar timorl avatar timorleph avatar woocash2 avatar yithis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alephbft's Issues

Ending sessions with max_round.

Hello everyone,

I need to run sessions sequentially to create an atomic broadcast. However, the time to finalisation is critical and we therefore cannot increase the round_delay until we finalise a preset number of items in this session. The alternative seems to be to specify the max_round to 3000 for example and finalise a variable number of items per session. In this case, however, the behaviour of the algorithm is unclear to me. I am wondering if the node keeps transmitting messages after he has finalized the last Data item to allow the other nodes to finish the session as well. Or do I risk that some nodes will not be able to finish their session if I use max_round to finish a session? In my case I need the session to allow all other nodes to catch up until either all of them have finished or I terminate it manually.

Please let me know if there is a developer discord or similar to discuss questions like this.

Inconvenient logging levels and logging target formats

In a context of a larger application AlephBFT crate logs a lot of errors on high levels for things that are normal and expected during typical use, even if "an error", or "warning" in the context of AlephBFT's internals. Please note that rust logging levels are global and shared for all the crates of the application, so the deeper "in the stack" given library is, the less the chance that certain logging statement is really relevant to the end user.

These logging messages are also cryptic and not useful for anyone that is not intimately familiar with its internals.

On top of it, AlephBFT currently makes it really inconvenient to disable or silence its log messages. The target: in logging statements is meant to be (and defaults to) a Rust module path. So the separator use for the hierarchical structure is ::, like Rust modules. Had it been:

info!(target: "alephbft::extender", ...);

etc. it would be natural to disable all alephbft logging with:

env RUST_LOG=info,alephbft=off

but since AlephBFT-xyz is used, this is not the case.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.