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]
- 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.
- 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_getLogsand the receipt methods follow the executed head. - State-dependent calls (
eth_getBalanceand similar) are limited until indexing completes, because they need the fully-built history rather than a live state trie. - The headline
debugmethods —debug_traceTransactionanddebug_traceBlockByNumber/ByHashwith the call tracer — are served by the execution subsystem (--execute), alongsideeth_calland 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.