Architecture

Node Structure
Kaizen Core consists of 1 Write node + N Read nodes.
Common Structure
All nodes run the same engine (Engine + STF). The only difference between node types is who produces blocks and whether they accept transactions.
Write Node (Sequencer)
- Receives transactions and executes immediately (streaming execution)
- Produces checkpoint every 100ms (oracle update + settlement)
- Broadcasts produced blocks to Read nodes
- Uses aggressive pruning to minimize storage
Read Nodes
Read nodes receive blocks from Write node and re-execute the same STF. They come in two modes:
Aggressive Mode (read-node-aggressive)
- Purpose: Low-latency queries for real-time applications
- Pruning: Keeps only ~16 minutes of history (10,000 blocks at 100ms)
- Use case: Live trading UI, WebSocket subscriptions,
simulateTransaction - Disk usage: Minimal, stays constant
Archive Mode (read-node-archive)
- Purpose: Full history for indexing and analytics
- Pruning: Disabled - keeps all blocks, snapshots, and state
- Use case: Historical queries, data indexing, auditing, analytics
- Disk usage: Grows over time
Both modes:
- Re-execute the same STF to reconstruct state (deterministic, guarantees identical results)
- Handle queries from external clients (Frontend, Solver)
- Provide real-time updates via WebSocket
- Are horizontally scalable
Why Re-execute STF?
- Simplicity: No need for state diffs or separate sync protocols. Just transmit blocks.
- Verification: Read nodes can compute state_root themselves and compare with Write node results.
- Code Unification: Engine code doesn't need to distinguish between node types. Single business logic.
- Fraud Proofs: Anyone can verify execution and prove invalid state transitions.
State-Backed Execution
All execution is deterministic - same block produces same state:
- No in-memory caches: API wallets, permissions all read from state
- Same verification: Read nodes run identical signature/timestamp checks as Write node
- Divergence detection: State root mismatch immediately caught and reported
See the Architecture overview for implementation details.
Components
Core components shared by all nodes (Write/Read):
Write Node Components
Component Descriptions
| Component | Description |
|---|---|
| Server | JSON-RPC and WebSocket endpoints. Query handling and transaction execution (Write node only). |
| Engine | Core component handling business logic. Coordinates AuthService, OracleService, RfqService. |
| STF | State Transition Function. Executes transactions to change state. Operates like a pure function. |
| Executor | (Write Only) Streaming tx execution + 100ms checkpoint loop for oracle updates. |
| Storage | RocksDB-based persistent storage. State managed with JMT (Jellyfish Merkle Tree). |
| Indexer | Event indexer with WAL for durability + PostgreSQL for queries. |
| Sync Service | (Write Only) Streams produced blocks to Read nodes via TCP. |
| Settler | (External) Monitors theses and submits SystemSettle transactions. See Settler. |
External Component Integration
Frontend
Connects to Read node via WebSocket. Receives real-time oracle prices, thesis status. Thesis submission proxied to Write node.
Solver
Similarly connects to Read node. Receives quote requests, returns signed quotes.
Bridge Relayer
Indexes deposit events from external chains (Arbitrum, Base, etc.) and submits Deposit transactions to Kaizen Core.
Oracle Service
Connects to Binance WebSocket and exposes HTTP API. Write node pulls prices every 100ms checkpoint instead of receiving OracleFeed transactions.
Core Abstraction Layer (kaizen-core)
Kaizen Core defines core abstractions in the kaizen-core crate for extensibility. This layer enables replacing or extending transaction types, state storage, and execution logic.
Core Traits
| Trait | Purpose |
|---|---|
Payload | Transaction payload abstraction. Type ID, priority, permissions |
StateReader / StateWriter | State read/write abstraction (borsh serialization based) |
VersionedStorage | Version-based state management (JMT commit, snapshots) |
PayloadExecutor<P> | Execution logic for specific payload type P |
BlockHook | Hooks for block start/end (auto-settlement, etc.) |
Clock | Time abstraction (MockClock for testing) |
Signable | EIP-712 signable objects |
Domain Service Traits
| Trait | Purpose |
|---|---|
BalanceManager | Asset balance management (deposit/withdraw) |
TxDeduplication | Transaction hash tracking for replay prevention |
RoleManager | Role-based permission (Admin, Feeder, Relayer) |
BlacklistManager | Blacklist management |
PauseManager | System pause state management |
IdGenerator | Sequential ID generation (theses, withdrawals) |
EcdsaRecovery | Address recovery from ECDSA signature |
Modular STF Executors
Each executor is independently testable and returns events:
// AccountExecutor usage example
let executor = AccountExecutor::new();
let events = executor.execute_transfer(&mut state, sender, &tx)?;
// RfqExecutor usage example
let executor = RfqExecutor::new();
let events = executor.execute_submit(&mut state, &oracle_service, sender, &tx, timestamp)?;Testing Utilities
kaizen-core provides the following utilities for testing:
InMemoryStorage: Memory-based state storage, implementsVersionedStorageandStateReader/WriterMockClock: Test clock with manual time controlVecEventCollector: Vector-based collector for events during executionNoopEventCollector: No-op implementation that ignores eventsSingleAssetBalanceManager: Single asset balance management implementation
use kaizen_core::{InMemoryStorage, MockClock, StateReader, StateWriter};
// Create test storage
let mut storage = InMemoryStorage::new();
storage.begin_version(1);
// State write/read
StateWriter::set(&mut storage, b"key", 42u64)?;
let value: Option<u64> = StateReader::get(&storage, b"key")?;