Architecture

Makechain uses a layered architecture with single-chain Simplex BFT consensus and serial per-project execution.

System overview

Clients (Browser, CLI, SDK)grpc-web / gRPC — reader fan-out to every validatorValidator NodegRPC APIMempoolSimplex BFT~300ms finalityExecution EngineQMDBLocal mempoolno P2P tx gossip

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.

Proposed BlockN messagesPhase 1: SerialAccount pre-passKEY, ACCOUNT, PROJECT_CREATE, FORK...account diffsBatchStore (QMDB + overlay)Phase 2: Serial per projectProject Amsgs seriallyProject Bmsgs seriallyProject Nmsgs seriallyMerkleizeQMDB state rootState RootBLAKE3 digest

The two phases are:

  1. Account pre-passSIGNER_ADD, SIGNER_REMOVE, ACCOUNT_DATA, VERIFICATION_ADD / VERIFICATION_REMOVE, LINK_ADD / LINK_REMOVE, REACTION_ADD / REACTION_REMOVE, PROJECT_CREATE, PROJECT_REMOVE, STORAGE_CLAIM, and FORK are applied serially because they touch shared owner_address-scoped account state
  2. Serial project execution — Remaining project-scoped messages are grouped by project_id and executed serially per group against a shared BatchStore overlay 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:

PrefixNamespace
0x02Blocks
0x03Tombstones
0x04Account state
0x05Account metadata
0x06Key entries
0x07Key reverse index (pubkey → owner_address)
0x08Usernames
0x09Verifications
0x0AProject state
0x0BProject metadata
0x0CProject name index
0x0DRefs
0x0ECommits
0x0FCollaborators
0x10Links
0x11Link reverse index
0x12Reactions
0x13Reaction reverse index
0x14Counters
0x15Prune markers
0x16Storage grants
0x17Storage claim settlement markers
0x1AFork parent index
0x1BMerge requests
0x1CMerge request reverse index
0x1ERef point-read index
0x1FCommit point-read index
0x202P-set slot index (point-read quota enforcement)
0x21Merge-request requester counter
0x22Storage-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:

PrimitiveUsage
commonware-consensusSimplex BFT consensus engine
commonware-broadcastBlock relay broadcast (buffered per-peer caching)
commonware-p2pAuthenticated peer connections
commonware-parallelExecution strategies (Sequential)
commonware-runtimeAsync task execution (tokio backend)
commonware-cryptographyEd25519 signing, BLAKE3 digests
commonware-storageQMDB merkleized key-value store (source of truth)
commonware-codecBinary 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 streamingSubscribeMessages with type and project_id filters