Skip to main content

Node Architecture

This page describes the internal architecture of a Mersennet node β€” the Rust binary that produces blocks, executes transactions, participates in consensus, and serves the JSON-RPC API.

Overview​

A running Mersennet node is composed of five cooperating subsystems:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PRIME CHAIN NODE β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ JSON-RPC β”‚ β”‚ WebSocket β”‚ β”‚ P2P β”‚ β”‚ Block Producer β”‚ β”‚
β”‚ β”‚ Server β”‚ β”‚ Server β”‚ β”‚ Network β”‚ β”‚ (Engine Loop) β”‚ β”‚
β”‚ β”‚ :8545 β”‚ β”‚ :9945 β”‚ β”‚ :30303 β”‚ β”‚ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ ENGINE β”‚ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ EVM (revm) β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ + Precompiles β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ State Backend β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ sled / redb β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ Consensus β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ (DPoS + BFT) β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ Mempool β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ PrimeOrders β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ Order Book β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
ComponentRole
EngineCentral coordinator: drives block production, EVM execution, consensus, and state management
P2P NetworkTCP/UDP transport for block propagation, transaction gossip, and consensus votes
JSON-RPC ServerHTTP endpoint implementing Ethereum-compatible JSON-RPC methods
WebSocket ServerPersistent connection endpoint for subscriptions (eth_subscribe)
Block ProducerTimer-driven loop that triggers block creation at the configured block_time_ms

Module Breakdown​

The codebase is organized into four Rust crates:

crates/core/ β€” Core Domain Logic​

The heart of the node. Contains all types, execution logic, and consensus:

ModulePurpose
engineEngine struct coordinating block production, EVM execution, and state transitions. Defines Block, Transaction, Receipt, LogEntry types
consensusDPoS validator management, proposer rotation, BFT finalization, slashing, rewards
hotstuff2Alternative HotStuff-2 consensus pipeline (optional)
cryptosecp256k1 signing/verification, tx_signing_hash, sign_transaction, recover_signer
statePersistentState with sled backend, Merkle tree computation, snapshots
state_redbAlternative RedbState backend using the redb embedded database
flat_stateFlatState β€” flat key-value representation for fast reads
state_traitStateBackend trait abstracting storage (sled, redb, in-memory)
mempoolTransaction pool with nonce ordering, gas price priority, per-sender limits, replacement logic
precompilesPrimeOrders EVM precompile registration at address 0x0100
precompile_abiABI encoding/decoding for precompile function selectors
prime_ordersOrder book state: markets, orders, positions, matching engine
configAppConfig and all sub-config structs (EngineConfig, P2pConfig, etc.)
eventsDomain event types for PrimeOrders and Bridge operations
errorsError types for RPC validation and PrimeOrders
networkNetwork simulation and consensus message types (Prevote, Precommit, etc.)
bridgeCross-domain bridge queue (EVM ↔ PrimeOrders)
prometheusPrometheus metrics registry and /metrics endpoint
identityNode identity (keypair) generation and persistence
governanceOn-chain governance proposals and voting
pipelineBlock execution pipeline orchestration
parallelParallel transaction execution engine
fbaFrequent Batch Auction (FBA) matching engine
mainnetMainnet safety guards and invariant checks
metricsInternal metrics collection
zk_proofsZero-knowledge proof generation
zk_sp1SP1 zkVM integration

crates/node/ β€” Node Binary​

The executable entry point that wires all components together:

FilePurpose
bin/prime-chain.rsMain binary: CLI parsing, config loading, identity management, engine initialization, block production loop, P2P networking, RPC server startup
bin/genesis.rsGenesis file generator utility
bin/faucet.rsTestnet faucet HTTP server
bin/stresstest.rsTransaction stress test tool
bin/loadtest.rsNetwork load testing tool

crates/rpc/ β€” JSON-RPC Server​

HTTP and WebSocket RPC servers:

FilePurpose
rpc.rsHTTP JSON-RPC server using tiny_http. Handles eth_* and prime_* methods. Includes CORS, metrics, and Prometheus /metrics endpoint
ws.rsWebSocket server for eth_subscribe (new blocks, pending transactions, logs)
rpc_router.rsMethod dispatch router mapping RPC method names to handler functions

crates/network/ β€” P2P Networking​

Peer-to-peer communication layer:

FilePurpose
p2p.rsP2pNetwork and NetworkNode β€” peer management, message routing, block/tx/vote handling
net_transport.rsTcpSync (reliable block sync) and UdpGossip (low-latency tx/vote propagation)
noise.rsNoise Protocol Framework encryption for P2P channels

Execution Pipeline​

When the block timer fires, the following sequence executes:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BLOCK PRODUCTION PIPELINE β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Timer fires (every block_time_ms)
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. PROPOSER SELECTION β”‚ Consensus selects the validator with the
β”‚ β”‚ highest accumulated priority (stake-weighted
β”‚ β”‚ round-robin). If this node is not the
β”‚ β”‚ proposer, it waits for an incoming block.
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 2. TX GATHERING β”‚ Drain pending transactions from the mempool,
β”‚ β”‚ ordered by gas_price (highest first). Stop
β”‚ β”‚ when cumulative gas reaches gas_limit_per_block.
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 3. EVM EXECUTION β”‚ For each transaction:
β”‚ β”‚ a. Build revm::Env (caller, callee, value,
β”‚ β”‚ data, gas_limit, gas_price)
β”‚ β”‚ b. Execute via revm with PrimeOrders
β”‚ β”‚ precompile at 0x0100
β”‚ β”‚ c. Collect ExecutionResult β†’ Receipt
β”‚ β”‚ d. Update account states in StateBackend
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 4. BRIDGE PROCESSING β”‚ Process cross-domain bridge messages:
β”‚ β”‚ - EVM β†’ PrimeOrders deposits
β”‚ β”‚ - PrimeOrders β†’ EVM withdrawals
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 5. STATE ROOT β”‚ Compute Merkle root over all account states
β”‚ β”‚ (sorted address β†’ serialized account data).
β”‚ β”‚ This becomes the block's state_root.
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 6. REWARD DISTRIBUTION β”‚ Calculate block reward based on token
β”‚ β”‚ economics (10 PRIM/block, halving every
β”‚ β”‚ 35M blocks). Distribute proportionally
β”‚ β”‚ to validators by stake weight.
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 7. FINALIZATION β”‚ Run BFT consensus:
β”‚ β”‚ - Broadcast block to peers
β”‚ β”‚ - Collect prevotes (2/3+ stake)
β”‚ β”‚ - Collect precommits (2/3+ stake)
β”‚ β”‚ - Process slashing evidence
β”‚ β”‚ - Mark block as finalized
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 8. BROADCAST β”‚ Send finalized block to all connected
β”‚ β”‚ peers via TCP. Update Prometheus metrics.
β”‚ β”‚ Notify WebSocket subscribers.
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Storage​

State Backend Architecture​

State persistence is abstracted behind the StateBackend trait, allowing pluggable storage engines:

         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ StateBackend β”‚ (trait)
β”‚ ───────────────── β”‚
β”‚ get_account() β”‚
β”‚ set_account() β”‚
β”‚ get_storage() β”‚
β”‚ set_storage() β”‚
β”‚ get_code() β”‚
β”‚ state_root() β”‚
β”‚ snapshot() / load() β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚ β”‚
β–Ό β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Sled β”‚ β”‚ Redb β”‚ β”‚ InMemory β”‚
β”‚ (default)β”‚ β”‚ β”‚ β”‚ (testing)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Sled Backend (Default)​

The default sled backend persists all state to disk at the configured state_path:

state/
β”œβ”€β”€ node_key.json # Node identity (secp256k1 keypair)
β”œβ”€β”€ peers.json # Known peer addresses
└── sled_db/ # sled embedded database
β”œβ”€β”€ accounts # Address β†’ AccountInfo (nonce, balance, code_hash)
β”œβ”€β”€ storage # (Address, Slot) β†’ U256 value
β”œβ”€β”€ code # CodeHash β†’ Bytecode
└── metadata # Chain height, state root, etc.

Snapshots​

The state backend supports snapshots for:

  • Crash recovery β€” Restore to last consistent state on unexpected shutdown
  • State sync β€” Share state snapshots with new nodes joining the network
  • Archive queries β€” Historical state lookups at specific block heights

EVM Integration​

Mersennet uses revm (Rust EVM) for transaction execution with the Shanghai specification.

Execution Flow​

For each transaction, the engine:

  1. Constructs a revm::Env with block context (number, timestamp, coinbase, base_fee, gas_limit) and transaction context (caller, callee, value, data, gas_limit, gas_price)
  2. Builds an Evm instance with the in-memory database and registered precompiles
  3. Executes the transaction, which may:
    • Transfer PRIM between accounts
    • Deploy a new contract (when to is None)
    • Call an existing contract
    • Interact with the PrimeOrders precompile at 0x0100
  4. Captures the ExecutionResult (success/revert/halt, gas used, output, logs)
  5. Commits state changes to the StateBackend

Precompiles​

Beyond the standard Ethereum precompiles (ecRecover, SHA-256, RIPEMD-160, identity, modexp, ecAdd, ecMul, ecPairing, blake2f), Mersennet adds:

AddressNameDescription
0x0100PrimeOrdersNative on-chain order book. Solidity contracts can place/cancel orders, query order books, and manage positions atomically within a transaction

The PrimeOrders precompile is registered via a custom EvmHandler that injects it into the precompile table before each block's execution. A thread-local context (PRIME_ORDERS_CTX) provides the precompile access to the order book state.

Gas Metering​

Gas follows standard EVM rules:

  • Base transaction cost: 21,000 gas
  • Contract creation: 32,000 gas + code deposit cost
  • Storage operations: 20,000 gas (SSTORE cold), 5,000 gas (SSTORE warm)
  • PrimeOrders precompile calls: fixed gas costs per operation type
  • Block gas limit: 30,000,000 (configurable)

EIP-1559 Fee Market​

Mersennet implements EIP-1559 dynamic base fee:

if gas_used > target_gas (gas_limit / elasticity):
base_fee increases (up to 12.5% per block)
if gas_used < target_gas:
base_fee decreases (up to 12.5% per block)

Configuration:

  • fee_elasticity_multiplier: 2 (target gas = gas_limit / 2 = 15M)
  • fee_max_change_denominator: 8 (max 12.5% change per block)

Custom Transaction Format​

Mersennet uses a custom binary format for transaction signing, inspired by EIP-155:

Signing Hash Input​

The signing hash is keccak256 of the following concatenated big-endian fields:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Field β”‚ Size β”‚ Encoding β”‚ Description β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ chain_id β”‚ 8 bytes β”‚ u64 big-endian β”‚ Network ID (7919)β”‚
β”‚ nonce β”‚ 8 bytes β”‚ u64 big-endian β”‚ Sender nonce β”‚
β”‚ gas_price β”‚ 32 bytesβ”‚ U256 big-endian β”‚ Price per gas β”‚
β”‚ gas_limit β”‚ 8 bytes β”‚ u64 big-endian β”‚ Max gas β”‚
β”‚ to β”‚ 20 bytesβ”‚ Address or 0x00 β”‚ Recipient (0x00 β”‚
β”‚ β”‚ β”‚ β”‚ for deploy) β”‚
β”‚ value β”‚ 32 bytesβ”‚ U256 big-endian β”‚ PRIM to transfer β”‚
β”‚ data β”‚ N bytes β”‚ Raw bytes β”‚ Calldata β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

signing_hash = keccak256(chain_id || nonce || gas_price || gas_limit || to || value || data)

Signed Transaction Wire Format​

After signing, the complete transaction includes the original fields plus the ECDSA signature:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Signing payload (as above) β”‚
β”‚ chain_id(8) || nonce(8) || gas_price(32) || gas_limit(8) β”‚
β”‚ || to(20) || value(32) || data(N) β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Signature β”‚
β”‚ r(32) || s(32) || v(1) β”‚
β”‚ β”‚
β”‚ v = recovery_id + 35 + chain_id Γ— 2 (EIP-155) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Signature Verification​

To recover the signer:

  1. Reconstruct the signing hash from the transaction fields
  2. Compute recovery_id = v - 35 - chain_id Γ— 2
  3. Recover the secp256k1 public key from (r, s, recovery_id, hash)
  4. Derive the Ethereum address: keccak256(public_key)[12..32]

Startup Sequence​

When the prime-chain binary starts:

1. Initialize tracing (structured logging from RUST_LOG env)
2. Initialize Prometheus metrics exporter
3. Parse CLI arguments and load config.json
4. Load or create node identity (secp256k1 keypair)
5. Initialize Engine with configured storage backend
6. Configure mempool limits, fee market, slashing parameters
7. Apply genesis state (fund accounts, register validators)
8. Set token economics (max supply, rewards, halving)
9. Start JSON-RPC server (if enabled)
10. Start WebSocket server (if enabled)
11. Start P2P networking (TCP sync + UDP gossip)
12. Enter block production loop:
└─ Every block_time_ms:
β”œβ”€ Process incoming P2P messages (blocks, txs, votes)
β”œβ”€ If proposer: produce_block()
β”œβ”€ Run consensus finalization
β”œβ”€ Broadcast results to peers
└─ Update metrics
13. On SIGINT/SIGTERM: graceful shutdown