Für Entwickler / JSON-RPC

Historie und Aufbewahrung

Der Node ist ein RPC-Index, kein Archiv. Er behält grob zwei Minuten an Blöcken, und eine Abfrage darüber hinaus antwortet null statt mit einem Fehler - deshalb steht diese Seite vor dem Schreiben eines Indexers und nicht danach.

Was der Node behält

DatenAufbewahrt
EVM block history~2 minuteskeep_evm_blocks() = 120,000 / EVM_BLOCK_MS - 480 blocks at the default. Older blocks return null and their logs become unqueryable
Mini-block history20,000KEEP_MINI_BLOCKS, roughly 200 seconds at the 10 ms scheduling target
Receipts and bodies200,000MAX_RECEIPTS, evicted first-in-first-out
Full historynot on the nodeit lives in Postgres behind the explorer, fed by the sequencer's spool. This RPC is an index, not an archive

Das Blockfenster ist abgeleitet statt fest: keep_evm_blocks() = 120_000 / EVM_BLOCK_MS, was bei der voreingestellten Kadenz 480 Blöcke ergibt. Logs werden mit ihrem Block verdrängt. Quittungen und Transaktionskörper haben ihre eigene First-in-first-out-Obergrenze und können vor ihrem Block verschwinden.

Lesezugriffe werden aus einem veröffentlichten Copy-on-Write-Snapshot bedient und nehmen nie das Ausführungs-Lock, weshalb ein langsamer eth_call die Blockproduktion nicht anhalten kann und ein blockierter Block keine Lesezugriffe anhalten kann. Das ist der Entwurf, der das Fenster vertretbar macht: Der Node optimiert darauf, die Gegenwart schnell zu bedienen, und reicht die Historie an etwas weiter, das dafür gebaut ist.

Wie das schiefgeht

Außerhalb des Fensters bekommen Sie null, keinen Fehler

eth_getTransactionReceipt, eth_getTransactionByHash und jede Blockabfrage antworten null für alles Verdrängte. Nichts unterscheidet „hat nie existiert" von „hat existiert und wurde fallengelassen".

Drei Muster, die richtig aussehen und es nicht sind:

  • Nach einer Quittung mit langem Backoff fragen. Warten Sie zwischen zwei Versuchen lange genug, und die Quittung kann zwischen zwei Abfragen verdrängt werden. Sie existiert etwa 10 ms nach dem Senden - fragen Sie früh und oft, nicht geduldig.
  • Ab Block 0 nachladen. earliest ist der früheste aufbewahrte Block, und er wandert nach vorn, während Sie arbeiten. Eine Nachladeschleife, die ihm hinterherläuft, erreicht nie einen festen Anfang.
  • Ein Ledger nächtlich abgleichen. Bis ein nächtlicher Job läuft, ist jeder Block weg, den er wollte.

Was stattdessen zu tun ist

Die vollständige Historie existiert - sie wird vom Sequencer in das Postgres hinter dem Explorer gestreamt, das als Archiv gebaut ist. Also:

  • Für die Gegenwart - die letzten paar Sekunden - nehmen Sie den Node. Abonnements und eth_getLogs über einen engen Bereich sind das, worin er schnell ist.
  • Für die Vergangenheit lesen Sie den Explorer. Er hat auch Aufruf-Traces, die der Node überhaupt nicht ausstellt, da es keinen debug-Namensraum gibt.
  • Um eine eigene Historie zu führen, abonnieren Sie und schreiben Sie weg, während die Ereignisse eintreffen, statt sie später abzufragen. Der Mini-Block-Strom ist die Quelle mit der höchsten Treue; ein langsamer Handler wird von ihm getrennt, schieben Sie also in eine Queue und verarbeiten Sie anderswo.
javascript
// Right: capture as it happens, persist immediately.
socket.send(JSON.stringify({
  jsonrpc: "2.0", id: 1, method: "eth_subscribe",
  params: ["logs", { address: MY_CONTRACT }],
}));

// Wrong on this chain: a range that has already scrolled out of the window
// returns an empty array rather than an error, so this looks like "no events".
await client.getLogs({ address: MY_CONTRACT, fromBlock: 0n, toBlock: "latest" });

Und wenn Sie einen Ereignisspeicher auf (blockNumber, logIndex) schlüsseln, nehmen Sie den Transaktions-Hash dazu: logIndex wird hier pro Transaktion durchnummeriert, dieses Paar ist also nicht eindeutig.

Quittungen über einen Neustart hinweg

Der Zustand überlebt einen Neustart; der Quittungsindex nicht

Der Quittungs- und Log-Index wird im Speicher gehalten. Die Quittung eines bestätigten Transfers wurde nach einem Neustart des Sequencers verschwinden gesehen, während die Guthabenänderung korrekt überlebte - eine Quittung ist also kein dauerhafter Nachweis von irgendetwas. Behandeln Sie den Explorer als die Aufzeichnung dessen, was geschehen ist, und die Quittung des Node als eine schnelle, verderbliche Empfangsbestätigung.