Para desarrolladores / JSON-RPC
Histórico y retención
El nodo es un índice RPC, no un archivo. Guarda aproximadamente dos minutos de bloques, y una consulta más allá responde null en vez de un error - por eso esta página existe antes de que usted escriba un indexador, y no después.
Lo que el nodo conserva
| Dato | Conservado |
|---|---|
| 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 ventana de bloques es derivada y no fija: keep_evm_blocks() = 120_000 / EVM_BLOCK_MS, es decir 480 bloques a la cadencia por defecto. Los logs se desalojan con su bloque. Los recibos y los cuerpos de las transacciones tienen su propio tope de primero en entrar, primero en salir, y pueden desaparecer antes que su bloque.
Las lecturas se sirven desde una instantánea publicada en copia sobre escritura y nunca toman el cerrojo de ejecución, lo que hace que un eth_call lento no pueda bloquear la producción de bloques y que un bloque atascado no pueda bloquear las lecturas. Ese es el diseño que hace aceptable la ventana: el nodo optimiza para servir el presente deprisa, y confía el histórico a algo construido para eso.
Cómo falla esto
Fuera de la ventana obtiene null, no un error
eth_getTransactionReceipt, eth_getTransactionByHash y todas las búsquedas de bloques responden null para lo que se ha desalojado. Nada distingue «nunca existió» de «existió y se ha eliminado».
Tres patrones que parecen correctos y no lo son:
- Sondear un recibo con un repliegue largo. Espere lo suficiente entre dos intentos y el recibo puede desalojarse entre dos sondeos. Existe unos 10 ms después del envío - sondee pronto y a menudo, no con paciencia.
- Rellenar el histórico desde el bloque 0.
earliestes el bloque conservado más antiguo, y avanza mientras usted trabaja. Un bucle de relleno que lo persigue nunca alcanza un punto de partida fijo. - Reconciliar un registro cada noche. Para cuando corre un trabajo nocturno, todos los bloques que quería han desaparecido.
Qué hacer en su lugar
El histórico completo existe - se transmite del secuenciador al Postgres que hay detrás del explorador, que está construido para ser un archivo. Así que:
- Para el presente - los últimos segundos - use el nodo. Las suscripciones y
eth_getLogssobre un rango estrecho son aquello en lo que es rápido. - Para el pasado, lea el explorador. Tiene además las trazas de llamada, que el nodo no expone en absoluto puesto que no hay espacio de nombres
debug. - Para llevar su propio histórico, suscríbase y persista a medida que llegan los eventos, en vez de pedirlos más tarde. El flujo de minibloques es la fuente más fiel; un manejador lento es expulsado de él, así que empuje a una cola y procese en otro sitio.
// 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" });Y si indexa un almacén de eventos por (blockNumber, logIndex), incluya el hash de la transacción: aquí logIndex está enumerado por transacción, así que ese par no es único.
Los recibos a través de un reinicio
El estado sobrevive a un reinicio; el índice de recibos, no
El índice de recibos y de logs se mantiene en memoria. Se ha observado desaparecer el recibo de una transferencia reconocida tras un reinicio del secuenciador mientras el cambio de saldo sobrevivía correctamente - así que un recibo no es el registro duradero de nada. Trate el explorador como el registro de lo que pasó, y el recibo del nodo como un acuse de recibo rápido y perecedero.