Pour les développeurs / JSON-RPC
Erreurs et limites
Cinq codes d'erreur portent tout. -32005 est celui qu'il vaut la peine de bien gérer, parce qu'il signifie une limite plutôt qu'une erreur - la même requête réussira plus tard.
Les cinq codes
| Code | Value |
|---|---|
| -32602 | Invalid paramsa malformed address, block tag, filter id or topic filter |
| -32601 | Method not found or not availablean unregistered name, or one refused by design such as eth_sendTransaction |
| -32000 | Executiona revert, a decode failure, a signature failure, or a consensus rejection |
| -32005 | Limita rate limit, a full queue, a timeout, a size cap or a filter cap - every row on this page |
| -32603 | Internala write-ahead-log or coordinator failure; also every non-send error when you are on the WebSocket transport |
La distinction qui compte à l'usage est celle entre -32000 et -32005. Une erreur d'exécution est un fait sur votre transaction et réessayer n'y change rien ; une erreur de limite est un fait sur la charge actuelle du nœud, et la requête identique réussira dès qu'il y aura de la place.
Pas de error.data
Les raisons de revert ne peuvent pas être décodées par votre bibliothèque
A revert arrives as message text - "execution reverted: 0x<returndata>" - and error.data is absent.
Libraries decode custom errors and revert strings out of error.data, so on this chain they cannot. ethers and viem will both surface the raw message instead of a decoded error. If you need the reason, parse the hex out of the message yourself and decode it against your own ABI.
La page des écarts porte le contournement.
Sending a transaction
| Limite | Valeur | Variable | En cas de dépassement |
|---|---|---|---|
| Raw transaction sizechecked on the hex string BEFORE decoding, so an oversized transaction is a limit error rather than a decode error | 128 KiB | constante de compilation | -32005 |
| Admission queuequeued transactions across all senders | 4,096 total | ADMISSION_CAPACITY | -32005 "sequencer admission queue is full" |
| Per sendercompile-time, so one sender cannot fill the queue with unfillable nonces | 64 | constante de compilation | -32005 |
| Execution waitthe coordinator's own deadline is 5 s; the call waits until the transaction executes or this expires | 6 s | constante de compilation | -32005 "transaction timed out waiting for execution" |
| Per execution batchMAX_ADMIT_PER_BATCH - a throughput mechanism, not a caller-visible limit | 512 | constante de compilation | - |
Expensive reads
| Limite | Valeur | Variable | En cas de dépassement |
|---|---|---|---|
| Token bucket burstguards eth_call, eth_estimateGas and eth_getLogs together | 256 | HEAVY_READ_BURST | -32005 "rate limit exceeded for expensive read methods" |
| Refill rateprocess-wide and shared by every caller - explicitly a backstop, not per-client limiting | 128/s | HEAVY_READ_PER_SEC | - |
| eth_getLogs spana span of 5,000 or more is refused outright | under 5,000 blocks | constante de compilation | -32005 "log block range is too wide" |
| eth_getLogs matchesnarrow the filter or walk the range in windows | 10,000 | constante de compilation | -32005 "eth_getLogs matched too many logs" |
The HTTP listener
| Limite | Valeur | Variable | En cas de dépassement |
|---|---|---|---|
| Connections | 512 | RPC_MAX_CONNECTIONS | - |
| Request bodythe public vhost caps a request at 1 MiB before this applies, and 1 MiB of JSON-RPC batch is already thousands of calls | 2 MiB | RPC_MAX_REQUEST_BYTES | - |
| Response body | 16 MiB | RPC_MAX_RESPONSE_BYTES | - |
| Batch lengthsplit a larger batch client-side | 32 | RPC_MAX_BATCH | - |
| Keep-aliveTCP_NODELAY is on | 30 s | RPC_KEEP_ALIVE_SECS | - |
Filters
| Limite | Valeur | Variable | En cas de dépassement |
|---|---|---|---|
| Filters per node | 1,024 | MAX_FILTERS | -32005 "filter limit reached" |
| Buffer per filterthe OLDEST entries are trimmed when you stop polling, so a slow poller loses the beginning of its backlog rather than the end | 1,024 entries | MAX_FILTER_BUFFER | - |
| Idle expirymeasured since the last poll, and expiry is silent - the next poll answers -32602 "filter not found" | 300 s | FILTER_TTL_SECS | -32602 |
Deux valeurs qui ne sont pas de la configuration
MIN_GAS_PRICE (1 wei) et EXECUTION_SPEC (Cancun) ressemblent à des réglages et sont délibérément des constantes de compilation.
Both are compile-time constants rather than environment variables, and that is a correctness requirement rather than an oversight. Either one made operator-tunable would let a replica reject or re-price a transaction the leader had accepted, and derivation would halt on the divergence. Pinning the hardfork also means a revm upgrade cannot silently change gas accounting underneath an already-settled chain.
Bien gérer les limites
Il n'y a ni limitation de débit par client, ni en-tête de budget restant, donc un client ne peut pas s'auto-brider à partir d'un signal - il doit être bien élevé par construction. Trois choses comptent :
- Temporisez sur
-32005, ne réessayez pas immédiatement. Le seau de lectures lourdes est partagé entre tous les appelants, donc une boucle de réessai serrée est le moyen le plus rapide de le garder vide pour tout le monde, vous compris. - Fenêtrez vos plages
eth_getLogsen dessous de 5 000 blocs et attendez-vous au plafond de 10 000 correspondances. Sur une chaîne qui conserve environ deux minutes de blocs, la limite pratique que vous rencontrez d'abord est la rétention plutôt que la portée. - Tenez les lots à 32. Au-delà le lot est rejeté plutôt que tronqué.
// RPC_URL : https://rpc.picklechain.xyz sur le réseau de test public, ou un nœud à vous.
async function call(body, attempt = 0) {
const res = await fetch(RPC_URL, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(body),
});
const json = await res.json();
// -32005 is a limit, not a mistake: the same request works later.
if (json.error?.code === -32005 && attempt < 5) {
await new Promise((r) => setTimeout(r, 2 ** attempt * 250));
return call(body, attempt + 1);
}
return json;
}