// introduction

What is ConsBlock?

ConsBlock is an open-source BFT consensus framework for distributed systems. It gives your network persistent state, sub-second block finality, and fault-tolerant agreement — without the protocol complexity.

Whether you're building a DeFi protocol, an on-chain game, or an AI agent swarm, ConsBlock provides the coordination primitives you need in a developer-friendly SDK.

✓ Open source · Apache 2.0 · Built for Web3 and distributed systems everywhere

Sub-second Finality

BFT engine, <50ms block commit

Cryptographic State

Merkle-trie, signed, tamper-proof

Peer Discovery

libp2p, no bootstrapper needed

EVM Compatible

Drop-in for any EVM chain

// introduction

The Vision

Traditional distributed systems bolt on consensus as an afterthought — fragile Raft implementations, hand-rolled leader election, or black-box third-party middleware you can't debug at 3am.

ConsBlock exists to change that. Our goal is a world where any developer can spin up a production-grade consensus network in minutes, not weeks.

Principles

  • Developer-first — clean API, great error messages, TypeScript-native
  • Pluggable — swap consensus engines without touching application code
  • Observable — metrics, logs, and a dashboard included by default
  • Open — Apache 2.0, forever free, community-driven
// introduction

Core Concepts

Rounds & Phases

Each consensus round goes through 4 phases: PROPOSE → PREVOTE → PRECOMMIT → COMMIT. A round is locked once ⅔ of validators pre-commit.

Validators

Validators are nodes that participate in voting. They hold ECDSA secp256k1 keypairs. Leader election uses VRF (Verifiable Random Function) for unpredictable, sybil-resistant proposer selection.

State Root

After every block, the state machine computes a Merkle Patricia Trie root. This root is included in the block header, making the entire state cryptographically verifiable at any point in history.

Finality

ConsBlock has deterministic finality — once committed, blocks cannot be reversed. No reorgs, no fork-choice rules, no probabilistic waiting.

// getting started

Quick Start

Prerequisites: Node.js >= 20 and npm/pnpm installed.
1

Install ConsBlock CLI

bash
npm install -g consblock
2

Initialize a new network

bash
consblock init my-network
cd my-network
3

Start your node

bash
consblock node start

Network runs at http://localhost:8545 · Metrics at :9090/metrics

4

Propose a state transition

typescript
import { ConsBlock, BftEngine } from 'consblock'

const node = await ConsBlock.create({
  engine: new BftEngine({ quorum: 0.67 }),
  port: 8545,
})

node.on('block:finalized', (block) => {
  console.log(`✓ Round ${block.round} finalized`)
})

await node.propose({ data: { amount: 100 } })
// getting started

Installation

CLI (recommended)

bash
npm install -g consblock
# or
pnpm add -g consblock

SDK only

bash
npm install consblock

Docker

bash
docker compose up --build

Docker starts 3 validator nodes + Prometheus + Grafana dashboard.

// getting started

Configuration

Variable Default Description
PORT 8545 JSON-RPC port
P2P_PORT 26656 libp2p listen port
CHAIN_ID 1337 Network chain ID
BLOCK_TIME_MS 500 Target block time (ms)
QUORUM 0.67 Fraction needed to commit
MAX_VALIDATORS 100 Max validator set size
LOG_LEVEL info debug / info / warn / error
METRICS_PORT 9090 Prometheus metrics port
// consblock engine

Architecture Overview

diagram
Client App ──(JSON-RPC)──► ConsBlock Node ◄──(libp2p)──► Peers
                                  │
             WebSocket Events ◄───┤
                                  │
                     ┌────────────┴────────────┐
                     ▼                         ▼
               Consensus Engine           State Machine
             (BFT / Tendermint)          (Merkle Trie)
                     │                         │
              ┌──────┴──────┐            ┌─────┴─────┐
              ▼             ▼            ▼           ▼
           Mempool     GossipSub      LevelDB    Snapshots

Key Components

  • Consensus Engine — pluggable BFT adapter (PBFT or Tendermint)
  • State Machine — Merkle Patricia Trie backed by LevelDB
  • P2P Layer — libp2p with NOISE encryption + GossipSub
  • Mempool — pending transaction pool with priority ordering
  • JSON-RPC — Ethereum-compatible HTTP + WebSocket server
// consblock engine

BFT Consensus

ConsBlock's consensus algorithm is based on practical Byzantine Fault Tolerance (pBFT). It provides safety and liveness as long as <⅓ of validators are faulty.

Round Lifecycle

Phase Description
PROPOSE VRF-elected leader broadcasts a new block
PREVOTE Validators verify and cast prevotes
PRECOMMIT On ⅔ prevotes, validators precommit the block
COMMIT On ⅔ precommits, block is finalized and stored

Timeouts

Each phase has a configurable timeout. On timeout, validators vote nil and the round advances. View-change protocol detects Byzantine leaders and rotates to the next VRF candidate.

// consblock engine

Cryptographic State

All application state is stored in a Merkle Patricia Trie — the same structure used by Ethereum. This means:

  • Every key-value pair can be proven with a compact Merkle proof
  • The entire state is summarized by a single 32-byte root hash
  • State roots are included in every block header
  • Historical states are accessible by block hash

State API

typescript
// Read state
const value = await node.state.get('balance:0xabc')

// Generate Merkle proof
const proof = await node.state.prove('balance:0xabc')

// Verify proof independently
const valid = verifyProof(proof, stateRoot)
// consblock engine

Peer Discovery

ConsBlock uses libp2p for all networking. Peer discovery is automatic via Kademlia DHT — no hardcoded bootstrap list required.

How it works

  • On startup, the node announces itself to the DHT
  • It finds nearby peers using Kademlia routing tables
  • Block and vote propagation uses GossipSub for efficient fan-out
  • All connections are encrypted with the NOISE protocol
  • NAT traversal via hole-punching and relay nodes

Manual peer connect

bash
consblock node join --peer /ip4/10.0.0.2/tcp/26656/p2p/QmPeer1...
// consblock engine

Security & Infrastructure

Validator Identity

Validators sign all messages with ECDSA secp256k1 keypairs — the same curve as Ethereum accounts. All vote messages include the validator address, round number, and block hash.

Slashing

Double-voting (equivocation) is detected on-chain. Evidence is included in the next block and the offending validator's stake is slashed.

Rate Limiting

Proposal and vote endpoints are rate-limited per validator key. Configurable via RATE_LIMIT_PROPOSALS and RATE_LIMIT_VOTES env vars.

Message Authentication

Node-to-node messages include HMAC-SHA256 signatures with sequence numbers to prevent replay attacks.

// sdk & api

TypeScript SDK

bash
npm install consblock

Available Methods

Method Description
ConsBlock.create(config) Spin up or connect to a consensus node
node.propose(tx) Submit a state transition for voting
node.state.get(key) Read current state value
node.state.prove(key) Generate Merkle inclusion proof
node.peers() List connected validator peers
node.status() Get current round and phase
node.on(event, fn) Subscribe to consensus events
node.stop() Gracefully disconnect from network

Full Example

typescript
import { ConsBlock, BftEngine } from 'consblock'

const node = await ConsBlock.create({
  engine: new BftEngine({ quorum: 0.67 }),
  port: 8545,
  peers: ['peer1.consblock.xyz'],
})

node.on('block:finalized', (block) => {
  console.log(`Round ${block.round}${block.hash}`)
})

const receipt = await node.propose({
  data: { transfer: '0xabc → 0xdef', amount: 100 },
})
// sdk & api

REST API

Health

http
GET /health
json
{ "status": "ok", "block": 14823, "peers": 7 }

Consensus Status

http
GET /consensus/status
json
{
  "round": 14823,
  "phase": "PRECOMMIT",
  "leader": "0xabc…",
  "votes": { "prevote": 7, "precommit": 6 }
}

Submit Transaction

http
POST /consensus/propose
Content-Type: application/json

{ "data": { "transfer": "0xabc", "amount": 100 } }

Read State

http
GET /state/:key
json
{ "key": "balance:0xabc", "value": "1000", "root": "0x4f8a…" }
// sdk & api

WebSocket

Connect to ws://localhost:8545/ws for real-time consensus events.

Subscribe

json
{ "type": "subscribe", "events": ["block:finalized", "peer:joined"] }

Event Types

Event Description
block:proposed Leader broadcast a new block
block:prevoted Quorum of prevotes collected
block:precommitted Round locked
block:finalized Block committed to chain
peer:joined New validator appeared
peer:left Validator went offline
state:synced Node caught up after being offline

Close Codes

Code Meaning
4000 Auth timeout
4001 Rate limit exceeded
4002 Invalid message format
4003 Server shutting down
// engines

BFT Engine (default)

Classic pBFT. Best for small-to-medium validator sets (< 100 nodes). Provides deterministic finality in 2 network round-trips.

typescript
import { BftEngine } from 'consblock'

const engine = new BftEngine({
  quorum: 0.67,      // ⅔ threshold
  timeout: 1000,    // phase timeout ms
  maxValidators: 50
})
// engines

Tendermint Engine

Higher throughput for larger validator sets. Implements the Tendermint BFT algorithm with weighted proposer priority.

typescript
import { TendermintEngine } from 'consblock/engines'

const engine = new TendermintEngine({
  proposerPriority: 'weighted'
})
// engines

Custom Adapter

Implement the ConsensusAdapter interface to plug in any consensus algorithm.

typescript
import { ConsensusAdapter } from 'consblock'

class MyEngine implements ConsensusAdapter {
  async propose(block: Block) { /* broadcast */ }
  async vote(block: Block, phase: Phase) { /* sign + send */ }
  async finalize(block: Block) { /* commit to state */ }
}
⚠️ Custom engines must implement all 3 methods. Missing any will throw at startup.