JSON-RPC¶
UMNode serves its API over JSON-RPC 2.0 on HTTP. The server is built for
throughput — Go's net/http for the transport, sonic
for JSON encoding/decoding, and pooled gzip writers for optional response
compression — so it can answer many small reads quickly.
It is enabled by default and binds 0.0.0.0:8550. Each call is timed: a Debug
log line, plus — when --metrics-addr is set — a per-method latency histogram.
See Observability.
Browser explorer at /docs
Open the RPC address in a browser and you're redirected to /docs — a
small built-in explorer (no external assets), laid out in three columns: a
method outline on the left (grouped by namespace), the selected method's
documentation filling the middle, and a 60%-wide request / response
pane on the right. Pick a method from the outline and it pre-fills a
ready-to-send request; edit it and press ⌘/Ctrl + Enter to see the
pretty-printed reply below, with its HTTP status, round-trip time and
response size, and a Wrap toggle for wide JSON. Under the
documentation, a cURL panel mirrors the request as a ready-to-run shell
command against the page's own endpoint — it follows every edit to the
request (valid JSON is compacted onto one line; anything else is passed
through verbatim and flagged) — and its Copy button puts the command on
the clipboard for a terminal. The method list and per-method docs come from
GET /docs/methods; the explorer POSTs to the same endpoint your own client
would. It's served wherever RPC is, so a node behind --rpc-addr exposes it
too — keep that in mind on a public bind.
A small, growing surface
Standard Ethereum methods: block and transaction reads (eth_blockNumber,
eth_getBlockByNumber, eth_getBlockByHash, eth_getTransactionByHash),
receipts and logs (eth_getTransactionReceipt,
eth_getBlockReceipts, eth_getLogs), and the
state methods (eth_call, the
getters, eth_chainId, the callTracer traces). Plus UMNode-specific debug
methods: debug_getBlockArtifact (a block exactly as the store persists
it), debug_listPeers (the live p2p peer set),
debug_getP2PBlockArtifact (force-fetch a block over p2p and see the wire
exchange), and node / index / state / receipts management. More methods
register as the store gains the data to back them.
Settings¶
| Flag | Default | Meaning |
|---|---|---|
--rpc-addr |
0.0.0.0:8550 |
host:port to bind the HTTP server. Empty disables RPC. |
--rpc-compression |
true |
gzip responses when the client advertises Accept-Encoding: gzip. |
These are node-wide settings (like --discovery-addr), so they are configured
by flag only — there is no per-network YAML equivalent. To turn the server off,
pass an empty address:
The protocol¶
- Send a JSON-RPC 2.0 request object with
POSTto the bind address. AGETreturns a short plain-text banner. - Batches are supported:
POSTa JSON array of request objects and receive an array of responses. - Errors use the standard codes:
-32700parse error,-32600invalid request,-32601method not found,-32602invalid params,-32603internal error, and-32000for application errors such as a missing block.
Compression¶
When --rpc-compression is on (the default), responses are gzip-compressed only
when the client sends Accept-Encoding: gzip and the payload is large enough
to be worth it (small replies like errors are sent uncompressed). The response
then carries Content-Encoding: gzip. Block artifacts are large and compress
well, so most real clients should advertise gzip.
eth_blockNumber¶
Returns the number of the most recent block in the store, as a hex quantity.
Params — none.
Result — the highest stored block number (e.g. "0x18103f3"). Errors if the
block store is disabled (--block-db "") or still empty (nothing imported yet).
This is the head of the local store, which can trail the live chain while
syncing, and is not necessarily contiguous down to genesis — backfill fills history
downward separately.
eth_getBlockByNumber¶
Returns a block by number in the canonical eth_ JSON shape (the same shape
geth/reth return), assembled from the stored header, body and transactions.
Params:
- the block — a hex quantity (
"0x18103f3"), a decimal/number, or a tag:"latest","earliest", or"pending"/"safe"/"finalized"(all map to the store head — UMNode tracks no pending block or finality). fullTransactions(boolean) —truereturns full transaction objects (including the recoveredfromsender and block location);falsereturns only the transaction hashes.
Result — the block object (number, hash, parentHash, the stateRoot /
transactionsRoot / receiptsRoot, miner, gasLimit / gasUsed, timestamp,
size, baseFeePerGas, transactions, uncles, and post-Shanghai withdrawals,
plus the post-fork fields when the header carries them), or null if the block is
not in the store.
Differences from a full node
totalDifficulty is omitted — UMNode does not track it. Receipts are not part
of this response; read them from the stored artifact via
debug_getBlockArtifact.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["latest", false]}'
A block not in the store returns a null result (not an error):
eth_getBlockByHash¶
Returns a block by its hash, in the same canonical eth_ shape as
eth_getBlockByNumber. Needs the
hash index (--index, on by default).
Params:
blockHash— the 32-byte block hash, hex ("0x…").fullTransactions(boolean) —truefor full transaction objects,falsefor just their hashes.
Result — the block object (identical shape to eth_getBlockByNumber), or
null if the block is not stored. A recent block is served from the in-memory
tail, an older one from the
on-disk index; with --index=false the method returns a "hash indexing is
disabled" error.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByHash","params":["0x…", false]}'
eth_getTransactionByHash¶
Returns a transaction by its hash, in the canonical eth_ shape. Needs the
hash index.
Params:
transactionHash— the 32-byte transaction hash, hex ("0x…").
Result — the transaction object: the signed fields, the recovered from
sender, the per-type fee fields, and its block location (blockHash,
blockNumber, transactionIndex), or null if it is not in any stored block.
Pending (unmined) transactions are not tracked.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionByHash","params":["0x…"]}'
Receipts and logs¶
Receipts are derived data: executing a block yields exactly the receipts
its header's receiptsRoot commits to. UMNode therefore has three ways to
treat them, chosen by --receipts:
fetch— receipts are downloaded with each block and stored inline in the block record. Blocks an earlier run stored without receipts (underderiveornone) are backfilled: a background worker fetches their receipts from peers on start and attaches them in place — a tail or open-segment block is rewritten in the pending area, a sealed segment is re-packed with its receipts and swapped in atomically — until the store matches a fetch-mode import. Progress is indebug_receiptsStatus;debug_fillReceiptsre-runs the pass.derive(the default) — receipts are not downloaded: the executor produces every block's receipts and keeps them in a receipts stream, a second slim segmented store under<state-db>/receiptsbuilt from the same machinery as the changeset store. Download volume drops by about a quarter and eth/68 peers serve the whole exchange. The pre-Byzantium range (mainnet blocks below 4,370,000) is still fetched: those receipts carry a per-transaction state root that a trie-free executor cannot recompute.--receipts-history Nbounds the stream to the most recentNblocks; receipts below that floor are reclaimed by deleting whole sealed segments. Without--executenothing derives them: blocks are imported without receipts and the methods below report them not available until execution is enabled or the mode is switched tofetch, which backfills them.none— receipts are neither downloaded nor stored: the lightest import for a node that serves blocks and transactions only. With--executethe two point lookups still re-execute a block on request;eth_getLogshas nothing to scan.
Deriving is the default whatever --execute says; downloading has to be asked
for with an explicit --receipts fetch (auto, the former default, follows
--execute: derive with it, fetch without).
The three methods below resolve a block's receipts in this order: inline
with the block, else the receipts stream, else — for the two point
lookups only — by re-executing the block on its parent's state, exactly
as debug_traceTransaction re-executes (the result is verified against the
header and cached by block hash). eth_getLogs scans a range and serves
stored receipts only: a range of re-executions is minutes of work per
thousand blocks, so a block whose receipts were pruned or not derived yet
fails the query with an error naming the block and the cause, rather than
silently crawling.
A block whose receipts are not available now — stored without them, and
nothing to derive them with — answers with an error that names the remedy for
the running mode: wait for the backfill (fetch), enable --execute or switch
to fetch (derive), or switch mode (none). Nothing is lost meanwhile:
switching to --receipts fetch later fills every such block retroactively.
latest for receipts
In derive mode the receipts stream trails execution, so for these methods
"latest" is the receipts head: the executed head when it is below the
store head. A block above it is served by eth_getBlockReceipts only once
execution reaches it (or via re-execution, which needs the parent executed).
eth_getTransactionReceipt¶
Returns the receipt of a mined transaction in the canonical eth_ shape, or
null if the transaction is not in any stored block. Needs the
hash index.
Params: 1. transactionHash — the 32-byte transaction hash, hex.
Result — transactionHash, transactionIndex, blockHash, blockNumber,
from, to (null for a contract creation) and contractAddress (the created
contract, else null), gasUsed and cumulativeGasUsed, effectiveGasPrice,
type, status (or root for a pre-Byzantium receipt), logs — each with its
blockNumber, transactionHash, transactionIndex, logIndex, blockHash
and blockTimestamp — and logsBloom; blobGasUsed and blobGasPrice for a
blob transaction.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionReceipt","params":["0x…"]}'
eth_getBlockReceipts¶
Returns every receipt of a block, in transaction order.
Params: 1. the block — a hex quantity, a number, a tag ("latest",
"earliest", "pending" / "safe" / "finalized"), or an object
{"blockHash": "0x…"} / {"blockNumber": "0x…"} (by hash needs the
hash index).
Result — an array of receipt objects (the eth_getTransactionReceipt
shape), empty for a block without transactions, or null if the block is not
stored.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockReceipts","params":["latest"]}'
eth_getLogs¶
Returns the logs matching a filter over a block range, or within one block.
Params — one filter object:
fromBlock/toBlock— a quantity or tag; both default to"latest"(the receipts head, see above). AtoBlockpast the head is clamped to it;fromBlockabovetoBlockis rejected.blockHash— instead of a range: the one block to search (needs the hash index; cannot be combined withfromBlock/toBlock).address— a single address or an array; absent matches every address.topics— positional: each entry isnull(any topic), one 32-byte topic, or an array of alternatives. A log with fewer topics than positions given never matches.
Result — an array of log objects (address, topics, data,
blockNumber, transactionHash, transactionIndex, blockHash,
blockTimestamp, logIndex, removed: false), in block, transaction and log
order.
Limits. The range may span at most --rpc-logs-max-blocks
blocks (default 10000); wider queries are rejected so clients page. Blocks
are pre-filtered on the header's logs bloom, so a filter that cannot match
reads no receipts. A block in the range that is not in the store yet, whose
receipts were pruned (below the --receipts-history floor), whose receipts
execution has not derived yet, or that was stored without receipts fails the
query with an error naming it and the remedy.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"fromBlock":"0x18103f3","toBlock":"latest","address":"0x…","topics":["0x…"]}]}'
State methods (the execution subsystem)¶
The methods below read the executed state built by the
execution subsystem, which is on by default
(--execute=false disables it). They share these rules:
- The trailing block argument accepts a quantity or a tag;
"latest"/"pending"/"safe"/"finalized"resolve to the executed head (which can trail the stored head while execution catches up),"earliest"is genesis. It defaults to"latest". - Until the backfill has reached genesis and execution has caught up to the
requested block, they error with
state not ready— never an approximation. Below the--state-historypruning floor they error withstate history not available. With execution disabled (or its prerequisites missing) they error withstate is disabled.
eth_chainId¶
Returns the chain id from the execution chain config, as a hex quantity
("0x1" on mainnet). No parameters.
eth_getBalance¶
Params: 1. address; 2. block (optional). Result — the balance in
wei as a hex quantity ("0x0" for a non-existent account).
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBalance","params":["0x…","latest"]}'
eth_getTransactionCount¶
Params: 1. address; 2. block (optional). Result — the account
nonce as a hex quantity.
eth_getCode¶
Params: 1. address; 2. block (optional). Result — the contract
bytecode, hex ("0x" for a code-less account).
eth_getStorageAt¶
Params: 1. address; 2. slot (hex, short forms like "0x0" accepted);
3. block (optional). Result — the 32-byte slot value, zero-padded hex.
eth_call¶
Executes a read-only call against the executed state at the requested block,
in that block's context (BASEFEE, TIMESTAMP, BLOCKHASH, …). This is the
method behind token balances of any standard — ERC-20/721/1155
balanceOf is just calldata.
Params:
callObject—{ from?, to, gas?, gasPrice?|maxFeePerGas? / maxPriorityFeePerGas?, value?, input?(aliasdata), accessList? }. Gas defaults to (and is capped at)--rpc-gas-cap; fees default to zero, which is always accepted.block(optional).
Result — the return data, hex. A revert returns error code 3 with
execution reverted[: reason] and the raw revert data in the error's data
field. Calls running longer than --rpc-call-timeout are aborted.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x…","input":"0x70a08231…"},"latest"]}'
debug_traceBlockByNumber / debug_traceBlockByHash¶
Re-executes a block on its parent's post-state and returns the call
tracer's frames for every transaction. UMNode serves the callTracer
only — it must be named explicitly; the default struct logger and every
other tracer are rejected.
Params:
block— quantity or tag (by-number), or the 32-byte block hash (by-hash; needs the hash index).traceConfig—{"tracer": "callTracer", "tracerConfig": {"onlyTopCall": bool, "withLog": bool}?, "timeout": "10s"?}. Required.
Result — [{ "txHash", "result": <call frame> }, …] in transaction
order (a transaction whose tracer failed carries "error" instead). The
call frame is geth's schema — type, from, to, value, gas,
gasUsed, input, output, error?, revertReason?, calls?, logs? —
so existing tooling works unmodified.
Tracing block N needs the parent's state: the same readiness and
--state-history floor errors apply. Each transaction's execution is
bounded by --rpc-trace-timeout.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_traceBlockByNumber","params":["0x96bed7", {"tracer": "callTracer"}]}'
debug_traceTransaction¶
Re-executes the transaction's block up to and including the transaction (prefix untraced — only its state effects matter) and returns the transaction's call frame. Needs the hash index to locate the transaction.
Params: 1. transactionHash; 2. traceConfig — as above
({"tracer": "callTracer"} required).
Result — the call frame object.
debug_getBlockArtifact¶
Returns the stored artifact for one block: its header, body and receipts, exactly as they live in the segmented block store — no node-side derivation.
Params — a single positional argument identifying the block:
- a block number as a JSON integer (
25232371), - a hex quantity string (
"0x18103f3"), - a decimal string (
"25232371"), or - the tag
"latest"(the store head) or"earliest"(block 0).
Result — an object with:
| Field | Meaning |
|---|---|
number |
Block number (hex quantity). |
hash |
Block hash (derived from the header; not part of the header JSON). |
header |
The full header, in go-ethereum's canonical JSON form. |
body |
transactions, and uncles / withdrawals when present. |
receipts |
One entry per transaction (see below). |
Faithful to what is stored
This is a debug method: it shows the stored artifact, not a fully-derived
block. The storage encoding keeps only a receipt's status (or pre-Byzantium
post-state root), cumulativeGasUsed and logs (each log's address,
topics and data). The transaction type and the logs bloom are not
stored — the type defaults to legacy on read and the bloom is recomputed from
the logs at serve time — so both are omitted here, as are a log's derived
fields (block hash/number, transaction hash/index, log index). Cross-reference
a receipt with its transaction in the same body to recover them. A block
imported without receipts (--receipts derive) shows the executor-derived
ones from the receipts stream once execution has reached it; until then its
receipts array is empty.
Example¶
curl -s http://127.0.0.1:8550 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_getBlockArtifact","params":["latest"]}'
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"number": "0x18103f3",
"hash": "0xbde13a4a8d725a8ba8ef1fbc8b0cd968e6377cfb5291a35e8936964b54c51bfe",
"header": {
"parentHash": "0x…",
"number": "0x18103f3",
"gasUsed": "0x…",
"timestamp": "0x…"
},
"body": {
"transactions": [
{ "type": "0x0", "nonce": "0x7", "to": "0x…", "value": "0x3e8", "hash": "0x…" }
],
"withdrawals": [
{ "index": "0x…", "validatorIndex": "0x…", "address": "0x…", "amount": "0x…" }
]
},
"receipts": [
{
"status": "0x1",
"cumulativeGasUsed": "0x5208",
"logs": [
{ "address": "0x…", "topics": ["0x…"], "data": "0x…" }
]
}
]
}
}
Request a specific block by number instead of the head:
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_getBlockArtifact","params":["0x18103f3"]}'
A block that is not in the store yet returns an application error:
debug_listPeers¶
A snapshot of every currently-connected (handshaked) peer — a window into what the p2p layer is talking to right now — plus the configured RPC peers, when there are any.
Params — none.
Result — { "count": N, "peers": [ … ], "rpcPeers": [ … ] }, each p2p peer
carrying its node id, enode, client name, inbound flag, remoteAddr,
negotiated ethVersion and advertised caps, the handshake's networkID /
forkHash / forkNext, the peer's best-block head hash, its served range
(earliestBlock / latestBlock, eth/69+), and how long it has been connected
(connectedFor). rpcPeers is present only with --rpc-peers; each endpoint
carries its id (scheme and host — never the path or credentials), status
(ready; down, resting after a failure, with retryIn until the next probe;
unverified, not reached yet; rejected, it serves another chain), chainId,
its latest block as last probed (head, headHash, headAge), whether it
serves eth_getBlockReceipts (receipts), its batch-call requests,
transport failures and invalid-response faults, and lastError while one
is current.
{
"count": 4,
"peers": [
{
"id": "6b36f791…a20507",
"enode": "enode://4aeb4ab6…@157.90.35.166:30303",
"name": "Geth/v1.17.2-stable-…",
"inbound": false,
"ethVersion": 69,
"caps": ["eth/69", "snap/1"],
"networkID": 1,
"forkHash": "0x07c9462e",
"head": "0xa811afa1…b48cc",
"latestBlock": 25244452,
"connectedFor": "1s"
}
],
"rpcPeers": [
{
"id": "http://127.0.0.1:8545",
"status": "ready",
"chainId": 1,
"head": 25244452,
"headHash": "0xa811afa1…b48cc",
"headAge": "2s",
"receipts": true,
"requests": 1483,
"failures": 0,
"faults": 0
}
]
}
latestBlock (or an RPC peer's head) is that peer's view of the chain head —
handy for spotting that a block you're chasing is simply above the current
head.
debug_getP2PBlockArtifact¶
A force-fetch: pull one block straight from peers over the wire — bypassing the store entirely — and report what we sent and what each peer sent back. It's a diagnostic for "why won't this block fetch?"; it writes nothing to the store.
Params:
- the block (a number, hex/decimal string, or
"latest"/"earliest"when a store is present), and - (optional) a peer
idto target a single peer instead of trying each.
Result — { number, peer?, note?, attempts: [ … ], artifact }. Each entry in
attempts describes one peer's exchange (headers, then bodies and receipts
once a header comes back, plus ok / error). artifact is the assembled block
(same shape as debug_getBlockArtifact) once a peer
serves a valid one, or null if none do.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_getP2PBlockArtifact","params":[25244400]}'
A successful fetch — one peer lacked the block, the next served it:
{
"number": "0x18104d0",
"attempts": [
{ "peer": "fde63ae0…", "ethVersion": 69,
"headers": "GetBlockHeaders{origin:25244400, amount:1} → 0 header(s)",
"ok": false, "error": "empty header response (block above the chain head, or peer lacks it)" },
{ "peer": "96f65494…", "ethVersion": 69,
"headers": "GetBlockHeaders{origin:25244400, amount:1} → 1 header(s) 0x6bbbbf62…",
"bodies": "GetBlockBodies{1 hash} → 1 body(ies), 242 txs",
"receipts": "GetReceipts{1 hash} → 1 list",
"ok": true }
],
"artifact": { "number": "0x18104d0", "header": { … }, "body": { … }, "receipts": [ … ] }
}
When a block is above the chain head, every peer returns an empty header
response and artifact is null — the unambiguous signature of "this block
doesn't exist yet" (cross-check the head via debug_listPeers):
{
"number": "0x180a4cf",
"attempts": [
{ "peer": "6b36f791…", "ethVersion": 69, "headers": "GetBlockHeaders{origin:25249999, amount:1} → 0 header(s)", "ok": false, "error": "empty header response (block above the chain head, or peer lacks it)" }
],
"artifact": null
}
Target one peer (e.g. to check whether a specific peer serves a range):
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_getP2PBlockArtifact","params":[25244400,"96f65494…"]}'
debug_indexStatus¶
The hash index's configuration and how far the background reindexer has covered already-stored data. Takes no parameters.
Result — { enabled, keyBytes, target, next, done, running, percent, diskBytes, compacting }:
enabled— whether hash indexing is on (--index).keyBytes— leading hash bytes per index key (the--index-key-bytesthe DB was created with).target/next— the confirmed ceiling the current backlog pass covers, and the next block it will index.done— the backlog is fully indexed; the live import path keeps it current.running— a reindex worker is active now.percent— progress of the current backlog pass (0–100).diskBytes— the index DB's on-disk size (whatdureports).compacting— an index compaction is running now.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_indexStatus","params":[]}'
debug_reindex¶
Force a fresh background reindex
pass (current floor → confirmed head), then return the status. The escape hatch for
filling gaps left when --index was turned off for a while and back on. A no-op
that just reports the live status if a reindex is already running. Takes no
parameters.
Result — the debug_indexStatus shape, plus "started": true.
debug_compactIndex¶
Trigger a background compaction of the hash-index DB to reclaim space from churn — old key versions and levels left un-merged by abrupt restarts. Heavy for a large index, so it is operator-triggered; a no-op that just reports the live status if a compaction is already running. Takes no parameters.
Result — the debug_indexStatus shape, plus "started": true. Watch
compacting and diskBytes via debug_indexStatus.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_compactIndex","params":[]}'
debug_rebuildState¶
Queues a state rebuild on the execution worker and returns
immediately; the rebuild runs between execution steps — watch the execution
section of debug_status. A parked executor (halted on an
execution divergence) is revived by this call.
Params:
block(optional) — rebuild from this block: the state is unwound through the recorded changesets to the block's post-state and re-executed forward. Must be at or above the--state-historyfloor and below the executed head. Omitted or0: the state is discarded entirely and rebuilt from genesis.
Result — { "accepted": true, "previousHead": "0x…", "rebuildFrom":
"genesis" | "0x…" }. Errors when the execution subsystem is off or a rebuild
is already pending.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_rebuildState","params":[]}'
debug_snapshotState¶
Takes a state snapshot now and publishes it to
the segment archive, due or not by --state-snapshot-every. The request is
queued for the archive uploader's next pass, which it wakes for; the snapshot
is taken at the executed head the store is at then — once every sealed
history segment is in the archive, as any snapshot waits for. The pass runs
the checkpoint (commits pause for a few seconds), the digest, the pack and
the upload; debug_status shows the progress under
archive.upload.snapshot, and
debug_cancelStateSnapshot interrupts it.
Older snapshots beyond --state-snapshot-keep are deleted as it lands, and
the schedule, if any, counts from it. Takes no parameters.
Result — { started, …the snapshot status }: started is true when
the request was queued, false when one is already queued or being taken
(the call is then a no-op). The status:
every— blocks between scheduled snapshots (0: on request only);uploaded(since start),published(the archive lists),latest(the newest one's head) andnextDue(the head the schedule takes the next one at).requested— a request is queued for the next pass.running— one is being taken: itshead,trigger(requestorschedule),phase(checkpoint,digest,pack,uploadormanifest), thebytes/totalof the pack or upload so far,startedAt, andcancellingonce a cancel has interrupted it.last,lastHead,lastAt— how the last one ended:published,cancelledorfailed(the upload status'slastErrornames the failure; a failed snapshot is retried by the next pass until it lands or is cancelled).
Errors unless the node backs up to an archive (--backup) with
--execute.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_snapshotState","params":[]}'
debug_cancelStateSnapshot¶
Interrupts the state snapshot being taken — its
digest, pack or upload stops within a read, the scratch files are removed and
the archive's manifest is left as it was — or drops a queued request
(debug_snapshotState) no pass has picked up yet. A
snapshot whose upload has landed is past interrupting: it is listed. A
scheduled snapshot that is cancelled is not retaken a minute later: the
schedule moves on by one period, as if it had been taken, until the node
restarts or a snapshot on request lands first. Cancelling also ends the
retries of a snapshot that keeps failing. Takes no parameters.
Result — { cancelled, …the snapshot status } (the debug_snapshotState
shape): cancelled is true when a snapshot was interrupted (again, while
it winds down) or a request dropped, false when nothing was queued or
being taken. Errors unless the node backs up to an archive
(--backup) with --execute.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_cancelStateSnapshot","params":[]}'
debug_receiptsStatus¶
Reports where receipts come from and how complete the stored receipts are. Takes no parameters.
Result — { mode, missing, stream?, fill? }:
mode— the resolved--receiptsmode:fetch,deriveornone.missing—{ blocks, segments }: how many stored blocks have transactions but no receipts (imported underderiveornone), and the segments holding them.stream— with--receipts deriveand--execute: the receipts stream'sfloor,sealedSegmentsandtip(the highest block whose receipts it holds).fill— with--receipts fetch: the backfill worker —running,filled(blocks given receipts since start),passes, thesegmentbeing filled while running, andlastErrorafter a failed step (the worker retries on its own).
A block counted in missing answers eth_getLogs with an error naming the
remedy; eth_getTransactionReceipt and eth_getBlockReceipts still derive its
receipts by re-execution when --execute is on.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_receiptsStatus","params":[]}'
debug_fillReceipts¶
Starts a receipts backfill pass: fetches receipts from peers for every stored
block that lacks them and attaches them in place (rewriting sealed segments —
see Receipts backfill). The worker runs one
pass on start under --receipts fetch; this re-runs it, for instance once
peers that serve old receipts (eth/69+ with a deep served range) are connected.
Takes no parameters.
Result — the debug_receiptsStatus shape plus started: true when a new
pass was queued, false when one is already running or queued (the request is
then a no-op). Errors unless the node runs --receipts fetch.
curl -s http://127.0.0.1:8550 \
-d '{"jsonrpc":"2.0","id":1,"method":"debug_fillReceipts","params":[]}'
debug_status¶
A one-call overview of the node. Takes no parameters.
Result — { version, uptime, uptimeSeconds, blocks, transactions, db, memory, execution, rpcPeers, archive }:
blocks—{ total, sealed, open, tail, floor, head, missingReceipts, prunedBelow, extraRanges? }: block counts across the store tiers, the stored range (floor–head), how many stored blocks have transactions but no receipts (seedebug_receiptsStatus), the pruning floor (0when nothing was pruned) and, with--extra-archive-blocks, the ranges kept outside the window as the store keeps them (padded below, whole segments), each{ from, to, filledDownTo?, complete }— a range is filled downward from its top, sofilledDownTois where its fill stands.transactions— the running total of transactions across all stored blocks.db— on-disk bytes per area:sealedBytes(.seg+.idx),openBytes(.seg.open),tailBytes(the pending DB),indexBytes(the hash index), and theirtotalBytes.memory— Go runtime use:heapBytes(live heap) andsysBytes(reserved from the OS).execution— the execution subsystem:{ enabled }when off; with--executealsoready(genesis state initialized), the executedhead/headHash, the historyfloor,lag(how far execution trails the stored head), andreceipts—{ stream: false }when receipts are fetched and stored inline, else the receipts stream's retentionfloor,tipandsealedSegments;unverified: truemarks a debug state seeded mid-chain by--execute-from(wrong by construction, see Debugging a block range);historyExtension— pruned history being fetched back after a retention window grew:running,historyWanted(where the window reaches),historyFloor/receiptsFloor, thekind,segmentandphase(download,adopt,index) in progress with the blocksindexed,adoptedsince start,done,lastError.rpcPeers— only with--rpc-peers:{ configured, ready }, how many RPC peers are configured and how many are serving requests right now (debug_listPeershas each one's state).archive— with--backupand/or an archive source (the public archive unless--archive-source none): the segment archive workers —upload(destination,verified,segments,bytes,published,pending,holdsPruning— per kind, the first block of the lowest sealed segment pruning is waiting on the archive for, absent when none —lastUploadAt,lastError, and with--executesnapshot, the state snapshots' schedule, queued request and progress in thedebug_snapshotStateshape) anddownload(source,state,segments,bytes,lastSegment,lastError).
The db byte figures are measured by walking the store directories.