Architecture
Makechain uses a layered architecture with single-chain Simplex BFT consensus and serial per-project execution.
System overview
Layers
Message layer
Every message is a self-authenticating envelope containing a BLAKE3 hash, Ed25519 signature, and the signer's public key. Messages are structurally validated before entering the mempool.
Consensus layer
A single Simplex BFT consensus chain orders all messages. The leader proposes blocks by draining the mempool, and the execution engine processes them in two phases.
The two phases are:
- Account pre-pass —
SIGNER_ADD,SIGNER_REMOVE,ACCOUNT_DATA,VERIFICATION_ADD/VERIFICATION_REMOVE,LINK_ADD/LINK_REMOVE,REACTION_ADD/REACTION_REMOVE,PROJECT_CREATE,PROJECT_REMOVE,STORAGE_CLAIM, andFORKare applied serially because they touch sharedowner_address-scoped account state - Serial project execution — Remaining project-scoped messages are grouped by
project_idand executed serially per group against a sharedBatchStoreoverlay on QMDB
This single-chain model achieves high throughput through consensus pipelining (multiple blocks in flight) without the complexity of cross-shard coordination.
State layer
State is stored in a prefix-namespaced key-value store with lexicographic ordering for range scans:
| Prefix | Namespace |
|---|---|
0x02 | Blocks |
0x03 | Tombstones |
0x04 | Account state |
0x05 | Account metadata |
0x06 | Key entries |
0x07 | Key reverse index (pubkey → owner_address) |
0x08 | Usernames |
0x09 | Verifications |
0x0A | Project state |
0x0B | Project metadata |
0x0C | Project name index |
0x0D | Refs |
0x0E | Commits |
0x0F | Collaborators |
0x10 | Links |
0x11 | Link reverse index |
0x12 | Reactions |
0x13 | Reaction reverse index |
0x14 | Counters |
0x15 | Prune markers |
0x16 | Storage grants |
0x17 | Storage claim settlement markers |
0x1A | Fork parent index |
0x1B | Merge requests |
0x1C | Merge request reverse index |
0x1E | Ref point-read index |
0x1F | Commit point-read index |
0x20 | 2P-set slot index (point-read quota enforcement) |
0x21 | Merge-request requester counter |
0x22 | Storage-grant index |
QMDB is the single source of truth. During block execution, a BatchStore creates a local mutations overlay on QMDB, then merkleizes and applies the changeset atomically on commit. API queries use a QmdbReadStore for lock-free reads. The StateStore trait keeps the storage backend pluggable.
Content storage
The consensus layer stores only message metadata (~100-500 bytes). File content (blobs, trees) lives in external storage, referenced by optional content_digest (integrity hash) and url (locator) in commit bundles. These fields are self-attested — validators do not fetch or verify content.
Commonware primitives
Makechain builds on the Commonware Library:
| Primitive | Usage |
|---|---|
commonware-consensus | Simplex BFT consensus engine |
commonware-broadcast | Block relay broadcast (buffered per-peer caching) |
commonware-p2p | Authenticated peer connections |
commonware-parallel | Execution strategies (Sequential) |
commonware-runtime | Async task execution (tokio backend) |
commonware-cryptography | Ed25519 signing, BLAKE3 digests |
commonware-storage | QMDB merkleized key-value store (source of truth) |
commonware-codec | Binary serialization |
Indexer
The indexer (cargo build --bin indexer --features indexer) streams finalized blocks from a node via gRPC, verifies each block, decodes messages, and writes them into Postgres. In the same per-block transaction that inserts the events rows, it derives the denormalized query tables — projects, accounts, collaborators, links, and reactions — so a block's events and their projections commit or roll back atomically. The upserts are idempotent, so retrying a block is a no-op and indexer --backfill can re-derive the query tables from the events table without re-fetching blocks. There is no message broker: the former Redis event-processor pipeline was removed (§10.3), which makes broker gaps — and the reconciliation loop that healed them — structurally impossible.
The binary is feature-gated and requires an external Postgres instance.
gRPC API
The node exposes a gRPC service on port 50051 (configurable) with:
- grpc-web support — browser clients via HTTP/1.1, served from the same connectrpc handler
- CORS — configured for cross-origin grpc-web requests
- Server reflection — runtime service discovery (grpc reflection v1)
- Message streaming —
SubscribeMessageswith type and project_id filters