Pour les développeurs / JSON-RPC
Historique et rétention
Le nœud est un index RPC, pas une archive. Il garde à peu près deux minutes de blocs, et une requête au-delà répond null plutôt qu'une erreur - c'est pourquoi cette page existe avant que vous n'écriviez un indexeur, et non après.
Ce que le nœud conserve
| Donnée | Conservée |
|---|---|
| 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 history | 20,000KEEP_MINI_BLOCKS, roughly 200 seconds at the 10 ms scheduling target |
| Receipts and bodies | 200,000MAX_RECEIPTS, evicted first-in-first-out |
| Full history | not on the nodeit lives in Postgres behind the explorer, fed by the sequencer's spool. This RPC is an index, not an archive |
La fenêtre de blocs est dérivée plutôt que fixe : keep_evm_blocks() = 120_000 / EVM_BLOCK_MS, soit 480 blocs à la cadence par défaut. Les logs sont évincés avec leur bloc. Les reçus et les corps de transactions ont leur propre plafond premier entré premier sorti et peuvent disparaître avant leur bloc.
Les lectures sont servies depuis un instantané publié en copie sur écriture et ne prennent jamais le verrou d'exécution, ce qui fait qu'un eth_call lent ne peut pas bloquer la production de blocs et qu'un bloc bloqué ne peut pas bloquer les lectures. C'est la conception qui rend la fenêtre acceptable : le nœud optimise pour servir le présent rapidement, et confie l'historique à quelque chose de bâti pour ça.
Comment cela échoue
Hors de la fenêtre vous obtenez null, pas une erreur
eth_getTransactionReceipt, eth_getTransactionByHash et toutes les recherches de blocs répondent null pour ce qui a été évincé. Rien ne distingue « n'a jamais existé » de « a existé et a été supprimé ».
Trois motifs qui ont l'air corrects et ne le sont pas :
- Interroger un reçu avec un long délai de reprise. Attendez assez longtemps entre deux tentatives et le reçu peut être évincé entre deux sondages. Il existe dans les 10 ms environ après l'envoi - sondez tôt et souvent, pas patiemment.
- Reprendre l'historique depuis le bloc 0.
earliestest le plus ancien bloc conservé, et il avance pendant que vous travaillez. Une boucle de reprise qui le poursuit n'atteint jamais un point de départ fixe. - Réconcilier un registre chaque nuit. Le temps qu'un travail nocturne tourne, tous les blocs qu'il voulait ont disparu.
Quoi faire à la place
L'historique complet existe - il est diffusé du séquenceur vers le Postgres derrière l'explorateur, qui est bâti pour être une archive. Donc :
- Pour le présent - les dernières secondes - utilisez le nœud. Les abonnements et
eth_getLogssur une plage étroite sont ce en quoi il est rapide. - Pour le passé, lisez l'explorateur. Il a aussi les traces d'appels, que le nœud n'expose pas du tout puisqu'il n'y a pas d'espace de noms
debug. - Pour tenir votre propre historique, abonnez-vous et persistez à mesure que les événements arrivent, plutôt que de les demander plus tard. Le flux de mini-blocs est la source la plus fidèle ; un gestionnaire lent en est éjecté, donc poussez vers une file et traitez ailleurs.
// 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" });Et si vous indexez un magasin d'événements sur (blockNumber, logIndex), incluez le hash de la transaction : ici logIndex est énuméré par transaction, donc cette paire n'est pas unique.
Les reçus à travers un redémarrage
L'état survit à un redémarrage ; l'index des reçus, non
L'index des reçus et des logs est tenu en mémoire. On a observé le reçu d'un transfert acquitté disparaître après un redémarrage du séquenceur alors que le changement de solde avait correctement survécu - un reçu n'est donc l'enregistrement durable de rien. Traitez l'explorateur comme l'enregistrement de ce qui s'est passé, et le reçu du nœud comme un accusé de réception rapide et périssable.