Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ help:
@echo " fmt - Format code"
@echo " clippy - Run clippy lints"
@echo " clean - Clean build artifacts"
@echo " book - Build the user documentation (mdbook)"
@echo ""
@echo "Environment Variables:"
@echo ""
Expand Down Expand Up @@ -329,6 +330,10 @@ clippy:
clean:
$(CARGO) clean

.PHONY: book
book:
mdbook build book

# Dafny commands
dafny-translate:
@echo "Translating Dafny specification to Rust..."
Expand Down
11 changes: 11 additions & 0 deletions book/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[book]
authors = ["Rayls Network"]
language = "en"
src = "src"
title = "RBFT User Guide"

[build]
build-dir = "../target/book"

[output.html]
git-repository-url = "https://github.com/raylsnetwork/rbft"
39 changes: 39 additions & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Summary

[Introduction](./introduction.md)

# Getting Started

- [Prerequisites](./getting-started/prerequisites.md)
- [Installation](./getting-started/installation.md)

# Running a Chain

- [Local Testnet](./running/local-testnet.md)
- [Follower Nodes](./running/follower-nodes.md)
- [Validator Management](./running/validator-management.md)
- [Docker Deployment](./running/docker.md)
- [Kubernetes Deployment](./running/kubernetes.md)

# Deploying Contracts

- [Using Cast (Foundry)](./contracts/cast.md)
- [QBFTValidatorSet Contract](./contracts/validator-set.md)
- [Deploying Your Own Contracts](./contracts/deploying.md)

# Interacting with the Chain

- [Sending Transactions](./interacting/transactions.md)
- [ERC20 Tokens](./interacting/erc20.md)
- [Load Testing](./interacting/load-testing.md)

# Operations

- [Configuration Reference](./operations/configuration.md)
- [Monitoring and Logs](./operations/monitoring.md)
- [Troubleshooting](./operations/troubleshooting.md)

# Architecture

- [Overview](./architecture/overview.md)
- [QBFT Consensus](./architecture/qbft.md)
89 changes: 89 additions & 0 deletions book/src/architecture/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Architecture Overview

RBFT is built as a layered system on top of Reth, the Rust Ethereum client.

```
┌─────────────────┐
│ RPC Interface │ HTTP JSON-RPC (ports 8545+)
└────────┬────────┘
┌────────▼────────┐
│ Reth Engine │ EVM execution, state management, transaction pool
└────────┬────────┘
┌────────▼────────┐
│ RBFT Consensus │ QBFT protocol, proposer rotation, validator management
└────────┬────────┘
┌────────▼────────┐
│ RLPx Network │ P2P messaging between validators and followers
└─────────────────┘
```

## Crate structure

### `rbft` (core library)

The consensus protocol implementation with no Reth dependencies. Contains:

- QBFT state machine (`NodeState`)
- Message types (Proposal, Prepare, Commit, RoundChange, NewBlock)
- Block validation and proposer election
- Round change and timeout logic

This crate is designed to be testable in isolation using an in-memory
`NodeSwarm` simulation.

### `rbft-node` (binary)

Integrates the core library with Reth:

- Custom consensus engine (`RbftConsensus`)
- RLPx protocol handler for QBFT messages
- Block building and execution via Reth
- P2P connection management

### `rbft-utils` (binary)

Operator tooling:

- Genesis generation (compiles and deploys QBFTValidatorSet contract)
- Testnet orchestration (start/stop/monitor nodes)
- Validator management (add/remove/status via contract calls)
- Log analysis (logjam)

### `rbft-megatx` (binary)

Transaction load generator for stress testing.

### `rbft-validator-inspector` (binary)

Terminal UI for real-time validator monitoring.

## Node types

| Type | Has validator key | Participates in consensus | Produces blocks |
|---|---|---|---|
| Validator (proposer) | Yes | Yes | Yes (when elected) |
| Validator (non-proposer) | Yes | Yes | No |
| Follower | No | No | No |

## Data flow

1. Transactions arrive via JSON-RPC
2. The current proposer builds a block and broadcasts a `Proposal`
3. Validators verify and send `Prepare` messages
4. On quorum of prepares, validators send `Commit` messages
5. On quorum of commits, the block is finalized
6. A `NewBlock` message is broadcast so followers can update

## Fault tolerance

With `n` validators, RBFT tolerates `f = ⌊(n-1)/3⌋` Byzantine faults.
The quorum size is `⌈(2n+1)/3⌉`.

| Validators | Max faults | Quorum |
|---|---|---|
| 4 | 1 | 3 |
| 7 | 2 | 5 |
| 10 | 3 | 7 |
80 changes: 80 additions & 0 deletions book/src/architecture/qbft.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# QBFT Consensus

RBFT implements the QBFT (Quorum Byzantine Fault Tolerant) consensus protocol,
a practical BFT algorithm designed for permissioned blockchain networks.

## References

- [The Istanbul BFT Consensus Algorithm (IBFT paper)](https://arxiv.org/abs/2002.03613)
- [QBFT Formal Specification (ConsenSys)](https://github.com/ConsenSys/qbft-formal-spec-and-verification)

## Protocol overview

QBFT operates in rounds within each block height. Each round has a designated
proposer determined by round-robin rotation.

### Normal case (round 0)

1. **Block timeout** — the proposer waits for the block interval, then
broadcasts a `Proposal` containing the new block.
2. **Prepare** — validators verify the proposal and broadcast a `Prepare`
message.
3. **Commit** — once a validator receives a quorum of prepares, it broadcasts
a `Commit` message with a commit seal.
4. **Finalize** — once a quorum of commits is collected, the block is added
to the chain with the commit seals embedded in the header.
5. **NewBlock** — the committed block is broadcast so all nodes (including
followers) can update their chains.

### Round change

If the proposer fails to propose within the timeout, validators trigger a
round change:

1. Each validator sends a `RoundChange` message for the next round.
2. When a quorum of round changes is collected, the new round's proposer
creates a proposal with a justification (the round change messages).
3. The protocol continues from step 2 (prepare phase).

### Timeout schedule

Round timeouts grow exponentially to avoid thrashing:

```
timeout(r) = first_interval * growth_factor^r
```

Default values:

| Parameter | Default |
|---|---|
| `first_interval` | 1.0 s |
| `growth_factor` | 2.0 |
| `max_round` | 10 |

## Proposer election

The proposer for a given round is determined by:

```
proposer_index = (height + round) % num_validators
```

This ensures fair rotation across validators and rounds.

## Quorum and fault tolerance

For `n` validators:

- Maximum Byzantine faults tolerated: `f = ⌊(n-1)/3⌋`
- Quorum size: `q = ⌈(2n+1)/3⌉`

The protocol guarantees safety (no conflicting blocks are finalized) as long as
at most `f` validators are faulty. It guarantees liveness as long as at least
`q` validators are honest and connected.

## Validator sets and epochs

The validator set can change dynamically through the QBFTValidatorSet contract.
Changes take effect at epoch boundaries (every `epochLength` blocks) to ensure
all validators agree on the set for a given block range.
67 changes: 67 additions & 0 deletions book/src/contracts/cast.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Using Cast (Foundry)

[Cast](https://book.getfoundry.sh/cast/) is a CLI tool from Foundry for
interacting with EVM-compatible chains. It is the recommended way to send
transactions and query state on an RBFT network.

## Installation

```bash
curl -L https://foundry.paradigm.xyz | bash
foundryup
```

Verify:

```bash
cast --version
```

## Common operations

All examples assume the default testnet RPC at `http://localhost:8545`.

### Check block height

```bash
cast bn
```

### Query an account balance

```bash
cast balance 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf
```

### Send ETH

```bash
cast send 0x1234567890123456789012345678901234567890 \
--value 1ether \
--private-key 0x<YOUR_KEY> \
--rpc-url http://localhost:8545
```

### Derive an address from a private key

```bash
cast wallet address --private-key 0x<YOUR_KEY>
```

### Call a contract (read-only)

```bash
cast call 0x0000000000000000000000000000000000001001 \
"getValidators()(address[])" \
--rpc-url http://localhost:8545
```

### Send a contract transaction

```bash
cast send 0x0000000000000000000000000000000000001001 \
"addValidator(address,string)" \
0xABCD... "enode://..." \
--private-key 0x<ADMIN_KEY> \
--rpc-url http://localhost:8545
```
68 changes: 68 additions & 0 deletions book/src/contracts/deploying.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Deploying Your Own Contracts

RBFT chains are fully EVM-compatible. Any contract that works on Ethereum can be
deployed to an RBFT network using standard tools.

## Using Foundry (forge)

Create a project and deploy:

```bash
forge init my-contract
cd my-contract

# Edit src/Counter.sol, then deploy:
forge create src/Counter.sol:Counter \
--rpc-url http://localhost:8545 \
--private-key 0x<YOUR_KEY>
```

## Using cast with raw bytecode

```bash
cast send --create <BYTECODE> \
--private-key 0x<YOUR_KEY> \
--rpc-url http://localhost:8545
```

## Using Hardhat

In `hardhat.config.js`:

```javascript
module.exports = {
networks: {
rbft: {
url: "http://localhost:8545",
accounts: ["0x<YOUR_PRIVATE_KEY>"]
}
}
};
```

Deploy:

```bash
npx hardhat run scripts/deploy.js --network rbft
```

## Getting test funds

On a default local testnet, the admin account
(`0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf`, derived from key `0x000...0001`)
is pre-funded with ETH. Transfer from it to fund your deployment account:

```bash
cast send 0x<YOUR_ADDRESS> \
--value 100ether \
--private-key 0x0000000000000000000000000000000000000000000000000000000000000001 \
--rpc-url http://localhost:8545
```

## Chain ID

The chain ID is set in `genesis.json`. Check it with:

```bash
cast chain-id --rpc-url http://localhost:8545
```
Loading
Loading