Vai al contenuto

Architecture

This page covers the theory: what UMNode is, how its pieces fit together, and how it is designed to fill and serve its store. Where a component already exists it is described as-is; where it is planned it is marked as such.

The core idea

A full node carries consensus to answer RPC. UMNode instead downloads and stores blocks, headers and receipts directly over the p2p wire protocol and serves them back — no consensus. State-dependent calls are served by an execution subsystem (on by default): a trie-free embedded EVM re-executes the stored chain from genesis into a compact state store, behind explicit state not ready errors until it has caught up.

Component overview

flowchart TB
    subgraph net[Network]
        P[(Ethereum peers)]
        RP[(RPC peers<br/>JSON-RPC of existing nodes)]
    end

    subgraph node[UMNode process]
        D[Discovery v4/v5]
        H[eth handshake<br/>network id + fork id]
        PS[Peer set]
        HT[Head tracker<br/>polls a peer]
        RT[Realtime worker]
        FE[Fetcher<br/>load-balanced]
        BF[Backfill worker]
        ST[(Segmented<br/>block store)]
        IV[(Peer inventory)]
        RPC[JSON-RPC server]
    end

    C[RPC clients]

    P <-->|dial out only| D
    D --> H --> PS
    PS --> HT
    PS --> FE
    RP -->|probe: latest block| HT
    RP -->|tried first| FE
    HT -->|new heads| RT
    RT <-->|fetch range| FE
    BF <-->|fetch range| FE
    RT -->|Put blocks| ST
    BF -->|Put blocks| ST
    H -->|good peers| IV
    IV -->|re-dial| D
    ST --> RPC
    RPC <--> C

Both fill workers exist today and share the load-balanced fetcher. Besides the wire peers, the fetcher can draw on RPC peers — the JSON-RPC endpoints of existing nodes, synced or partially synced — which it tries first and validates like any peer; a node can even run from them alone. The JSON-RPC server serves block, transaction, receipt and log reads, the state methods and the call-tracer traces — see below.

How the store fills

UMNode fills its store from two concurrent fronts that converge:

flowchart LR
    HEAD[Chain head] -->|realtime: follow the tip| MID((  ))
    GEN[Block 0] -->|backfill: fill downward| MID
    MID -->|fronts meet| DONE[Fully indexed]
  1. Realtime — at the head. The realtime worker follows the chain head and writes each new block (header, body and receipts) as it appears, handling reorgs at the tip. See Realtime sync.
  2. Backfill — historical. In parallel, a background worker fills the missing history below the store's anchor down toward genesis. See Backfill sync.

The two fronts converge; once they meet, the chain is fully indexed. This is why the store is built to accept out-of-order writes (see Block store).

Read path & RPC surface

The JSON-RPC server (net/http + sonic) is live and serves its first method, debug_getBlockArtifact, which returns a block exactly as the store persists it — header, body and receipts. See JSON-RPC.

The surface grows from there:

  • Block, transaction and receipt reads work as soon as the relevant block has been downloaded — they only need stored data. Receipts are the exception that proves the rule: with execution on they are not downloaded but derived, so eth_getLogs and the receipt methods follow the executed head.
  • State-dependent calls (eth_getBalance and similar) are limited until indexing completes, because they need the fully-built history rather than a live state trie.
  • The headline debug methods — debug_traceTransaction and debug_traceBlockByNumber/ByHash with the call tracer — are served by the execution subsystem (--execute), alongside eth_call and the state getters.

Packages

A rough map of the Go source (for contributors):

Package Responsibility
cmd CLI entry point, flag definitions, settings resolution.
app Process wiring: discovery, peer set, head tracker, realtime worker.
ethereum Per-network config, EIP-2124 fork id, eth handshake & protocol, peer set, head poller, RPC peers (JSON-RPC block sources).
chainsync Realtime, backfill and execution workers, and the load-balanced block fetcher.
evm Trie-free block execution: custom vm.StateDB (journaled overlay) over a StateReader, block executor with receipts verification. See EVM & state.
rpc JSON-RPC 2.0 HTTP server (net/http + sonic) and its methods.
store Peer inventory persistence (known-good peers).
store/segment The segmented, immutable, compressed block store.
store/state Executed-state store: flat latest state, per-block pre-value changesets, history index; point-in-time readers and reorg unwind. See EVM & state.
archive The segment archive: backup of sealed segments to S3 / Cloudflare R2 / a directory, and download + verified attach of block segments during backfill (built-in SigV4 S3 client).
logging Logger setup.
version Version string embedded at build time.

See Networking & peers for the discovery/handshake side and Block store for the storage side.