Aller au contenu
Blockchain Association of Cameroon
BAC-L1-FOUND-1184 h

API, JSON-RPC et intégration de nœuds

Parler à une chaîne depuis du code : appels, abonnements, erreurs, limites de débit, et la discipline de ne jamais faire confiance à une seule source.

  • Interroger un nœud en JSON-RPC et gérer ses codes d'erreur
  • S'abonner à des événements par WebSocket
  • Concevoir une stratégie de reprise sur point de terminaison défaillant

Une application de chaîne ne lit pas la chaîne directement : elle interroge un nœud, le plus souvent par JSON-RPC, et croit ce qu'il répond. Cet atelier vous apprend à écrire une requête JSON-RPC correcte, à lire ses codes d'erreur sans les confondre avec une panne réseau, à suivre les nouveaux blocs par abonnement WebSocket et à survivre à la disparition de votre point de terminaison. Vous réutilisez ce que vous savez des comptes, des nonces et des transactions. Cette page n'ouvre pas de vrai WebSocket vers un nœud (le navigateur sait en ouvrir, mais ces exercices ne le font pas) : les exercices en ligne combinent des épreuves générées (écrire une requête, lire une erreur) et des diagnostics sur des journaux ; le client réel se code dans le laboratoire autonome.

Leçons 1/4 · 15 min

Interroger un nœud : requête et réponse JSON-RPC

Comment un portefeuille connaît-il votre solde ?

Il ne lit aucun disque : il envoie une question à un nœud, qui répond. JSON-RPC est un protocole très simple pour cela : « RPC » veut dire appel de procédure à distance (appeler une fonction qui s'exécute ailleurs), et les messages sont du JSON. La version décrite ici est la 2.0 (spécification « JSON-RPC 2.0 »). Plusieurs familles de nœuds la parlent : les nœuds de type Ethereum, ceux construits sur Substrate, et Bitcoin Core propose lui aussi une interface JSON-RPC avec ses propres méthodes. Les noms de méthodes changent d'un écosystème à l'autre.

Dans cet atelier, le nœud d'entraînement utilise des noms inventés : chain_blockNumber, chain_getBalance, chain_getBlockByNumber. Retenez la forme, pas les noms. Autre différence avec Ethereum : ici les quantités (comme la hauteur d'un bloc) sont des nombres JSON, alors que les nœuds de type Ethereum les écrivent en chaînes hexadécimales.

Une requête a quatre champs

{"jsonrpc":"2.0","method":"chain_getBalance","params":["0xAAAA…","latest"],"id":7}
  • jsonrpc : toujours la chaîne "2.0".
  • method : le nom de la procédure.
  • params : les arguments, soit une liste (par position, comme ci-dessus), soit un objet (par nom). Facultatif quand il n'y a rien à passer.
  • id : un identifiant choisi par vous (nombre ou chaîne). Le serveur le recopie dans sa réponse, ce qui permet d'associer chaque réponse à sa question quand plusieurs sont en vol.

On l'envoie dans le corps d'une requête HTTP POST avec l'en-tête Content-Type: application/json, vers l'adresse du point de terminaison (<endpoint> ci-dessous), par exemple avec curl :

curl -s -X POST <endpoint> -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"chain_blockNumber","params":[],"id":7}'

Une réponse a un résultat OU une erreur

{"jsonrpc":"2.0","result":"0x1f4","id":7}
{"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":7}

Une réponse contient result ou error, jamais les deux. Ici "0x1f4" est un nombre en hexadécimal : 1×256 + 15×16 + 4 = 500. Les nœuds de type Ethereum renvoient ainsi la plupart des nombres, sous forme de chaîne hexadécimale ; d'autres écosystèmes renvoient des nombres JSON. Lisez la documentation de votre nœud et convertissez explicitement : n'additionnez jamais deux chaînes hexadécimales.

Une grosse valeur (un solde en plus petite unité) dépasse souvent ce qu'un nombre JavaScript sait représenter exactement ; on la garde en chaîne ou en bigint jusqu'à l'affichage. Vous le reverrez dans l'atelier sur TypeScript.

Notifications et lots

  • Une requête sans id est une notification : le serveur ne répond rien. Utile pour prévenir, inutile pour interroger.
  • Un lot (batch) est un tableau de requêtes envoyé d'un coup ; la réponse est un tableau, dans un ordre qui n'est pas garanti : on associe par id. Pratique pour économiser des allers-retours sur une connexion lente, mais certains fournisseurs limitent la taille d'un lot.

Ce que cela ne garantit PAS

  • JSON-RPC ne dit rien sur l'authenticité de la réponse : un nœud peut se tromper, être en retard ou mentir. Rien ici ne prouve que le solde annoncé est celui de la chaîne.
  • La spécification ne dit rien de HTTP : certains serveurs répondent « 200 » même pour une erreur JSON-RPC. Ne vous fiez pas au statut HTTP seul ; regardez le corps.
  • Une méthode chain_getBalance n'existe sur aucun nœud réel sous ce nom ; allez lire la liste des méthodes du vôtre.

À retenir : quatre champs en entrée, résultat OU erreur en sortie, id pour associer.

Leçons 2/4 · 15 min

Lire les erreurs, décider de réessayer ou non

Trois sortes d'échec qu'il ne faut pas confondre

Votre code envoie une requête et n'obtient pas ce qu'il voulait. Trois situations très différentes.

  1. Le transport échoue : pas de réponse, délai dépassé, connexion coupée. Vous ne savez même pas si le serveur a reçu la requête.
  2. HTTP signale un problème : par exemple 429 (trop de requêtes, vous dépassez la limite de débit) ou un code 5xx (le serveur est en difficulté).
  3. JSON-RPC répond par une erreur : le serveur a bien reçu et compris que quelque chose cloche. Le champ error contient un code (nombre) et un message (texte pour humains).

Un programme décide avec le code, jamais en analysant le texte du message.

Les codes standard

CodeNomSens
-32700Parse errorle serveur n'a pas pu analyser le JSON reçu
-32600Invalid RequestJSON valide, mais pas une requête JSON-RPC valide
-32601Method not foundla méthode n'existe pas ou n'est pas disponible
-32602Invalid paramsles paramètres sont invalides
-32603Internal errorerreur interne de JSON-RPC

De plus, la spécification réserve la plage -32000 à -32099 aux erreurs « de serveur » définies par l'implémentation. Les codes de cette plage, et ceux qui sont hors de la plage standard (« solde insuffisant », « nonce trop bas »…), diffèrent d'un logiciel de nœud à l'autre : ne les mémorisez pas, lisez la documentation de votre nœud et testez-les.

Que faire de chaque erreur ?

SituationRéessayer ?Pourquoi
Délai dépassé, connexion coupéeoui, avec attentepanne probablement passagère
HTTP 429 (ou erreur JSON-RPC propre au fournisseur pour une limite de débit, parfois renvoyée avec HTTP 200)oui, après l'attente demandéel'en-tête Retry-After, s'il est présent, dit combien attendre
HTTP 5xxoui, quelques foisserveur en difficulté
-32700, -32600, -32601, -32602nonc'est un bogue de votre requête : la renvoyer à l'identique échouera à l'identique (sauf documentation contraire de votre nœud : certains répondent -32602 pour un bloc pas encore disponible ou un état élagué)
-32603 ou erreur de serveurprudencepeut être passager ; limitez le nombre d'essais

Réessayer une lecture, réessayer un envoi

Relire un solde deux fois est inoffensif : on dit que la lecture est idempotente. Renvoyer une transaction est plus délicat, mais votre connaissance du nonce aide : une transaction signée a un hachage et un nonce fixes. Si vous la renvoyez, le réseau ne l'exécutera pas deux fois. Le nœud répondra plutôt « déjà connue » ou, si elle est déjà incluse, « nonce trop bas ». Ces réponses ne sont pas des échecs : cherchez la transaction par son hachage avant de conclure. En revanche, resigner une nouvelle transaction avec un nonce frais à chaque essai peut créer deux paiements : à éviter.

Exemple chiffré

Un client reçoit successivement :

  1. {"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params"},"id":3} : il avait oublié le second paramètre. Pas de nouvel essai ; on corrige le code.
  2. HTTP 429 avec Retry-After: 4 : on attend au moins 4 secondes.
  3. Aucune réponse pendant 10 secondes : on abandonne cet essai (le délai maximal), puis on réessaie après une attente croissante.

Ce que cela ne garantit PAS

  • Une absence d'erreur n'est pas une preuve d'exactitude : le nœud peut répondre sans erreur et se tromper.
  • Un code d'erreur dit ce que le nœud a vu ; il ne dit pas ce que la chaîne décidera. Une transaction acceptée dans le pool peut encore être abandonnée plus tard.
  • Aucune table de codes d'un nœud ne vaut pour un autre.

À retenir : classer l'échec d'abord (transport, HTTP, JSON-RPC), puis décider de réessayer ou de corriger.

Leçons 3/4 · 15 min

S'abonner aux blocs par WebSocket

Interroger toutes les deux secondes, ou être prévenu ?

Un bloc arrive, disons, toutes les 12 secondes. Si votre application demande « quelle est la hauteur ? » toutes les 2 secondes, elle envoie 6 requêtes par bloc, dont 5 ne ramènent rien de nouveau. Sur une connexion limitée, c'est du forfait gaspillé, et vous risquez la limite de débit du fournisseur.

Un WebSocket est une connexion qui reste ouverte après un premier échange HTTP : serveur et client peuvent s'y envoyer des messages quand ils veulent. Beaucoup de nœuds y proposent des abonnements : vous dites une fois « prévenez-moi à chaque nouvel en-tête de bloc », et le serveur pousse chaque événement. Chez les nœuds de type Ethereum, c'est la méthode eth_subscribe avec le sujet "newHeads" ; les noms varient selon l'écosystème.

Forme simplifiée d'un abonnement

Les messages ci-dessous sont simplifiés et schématiques : consultez votre nœud pour la forme exacte.

-> {"jsonrpc":"2.0","method":"<méthode d'abonnement>","params":["newHeads"],"id":1}
<- {"jsonrpc":"2.0","result":"0x9a","id":1}
<- {"jsonrpc":"2.0","method":"<méthode de notification>","params":{"subscription":"0x9a","result":{"number":"0x64","hash":"0xaa…","parentHash":"0x99…"}}}

La première réponse donne l'identifiant d'abonnement. Les messages suivants n'ont pas d'id : ce sont des notifications, qui portent l'identifiant d'abonnement pour dire à quel abonnement elles se rattachent.

Ce qui se passe quand la connexion tombe

C'est l'essentiel du métier. Un WebSocket peut mourir sans prévenir (changement de réseau mobile, boîtier intermédiaire qui coupe les connexions inactives). Et surtout :

  • Pas de rattrapage. Un abonnement ne rejoue pas ce que vous avez manqué. Après une reconnexion, vous devez vous réabonner et combler le trou avec des requêtes ordinaires.
  • Le silence est ambigu. Pas de message depuis 40 secondes : pas de nouveau bloc, ou connexion morte ? Prévoyez un délai (par exemple deux ou trois fois l'intervalle attendu entre blocs) après lequel vous considérez la connexion comme suspecte et la rouvrez.

Exemple chiffré de rattrapage

Vous avez traité les blocs jusqu'au numéro 101. La connexion tombe, vous vous reconnectez, vous vous réabonnez, et le premier en-tête reçu porte le numéro 105. Il manque 102, 103 et 104 : 105 − 101 − 1 = 3 blocs. Vous les demandez un par un (ou en lot) avec la méthode de lecture de bloc, puis vous traitez 105.

Les réorganisations

Les en-têtes que vous recevez peuvent être remplacés : deux blocs numéro 105 différents, chacun avec son hachage, arrivent l'un après l'autre. C'est une réorganisation de la chaîne (vous avez vu les bifurcations dans les ateliers de consensus). Un client sérieux garde pour chaque bloc son numéro, son hachage et le hachage de son parent, et vérifie que le parent du nouveau bloc est bien celui qu'il a mémorisé au numéro précédent. Sinon, il remonte la chaîne jusqu'au point commun et annule ce qu'il avait enregistré au-delà. Cette précaution suppose une chaîne à finalité probabiliste (le cas des chaînes à preuve de travail et de beaucoup d'autres) ; sur une chaîne à finalité immédiate (certains protocoles BFT), un bloc décidé ne change plus et ce cas ne se présente pas.

C'est pourquoi on attend un certain nombre de confirmations (blocs construits par-dessus) avant d'agir sur de l'argent. Ce nombre dépend de la chaîne et de ce que vous risquez ; aucune valeur universelle n'existe.

Une boucle de reconnexion (esquisse)

async function follow(state: { lastDone: number }) {
  while (true) {
    let socket;
    try {
      socket = await connect();                // ouvre le WebSocket
      await subscribeToHeads(socket);          // réabonnement à chaque fois
      const head = await firstHead(socket);
      for (let n = state.lastDone + 1; n < head.number; n++) {
        await handleBlock(await getBlock(n));  // rattrapage du trou
        state.lastDone = n;                    // progression notée bloc par bloc
      }
      await handleBlock(head);
      state.lastDone = head.number;
      await consume(socket, state);            // met à jour state.lastDone à chaque bloc
    } catch (e) {
      await waitBeforeRetry();                 // voir la leçon suivante
    } finally {
      socket?.close();                         // ferme toujours l'ancienne connexion
    }
  }
}

La progression est notée bloc par bloc dans state : si consume lève une erreur au milieu (cas habituel d'une connexion coupée), le prochain tour repart du dernier bloc réellement traité, sans en rejouer des dizaines. Malgré cela, un bloc peut encore arriver deux fois (par exemple si la coupure survient entre le traitement et la mise à jour de state) : handleBlock doit donc être idempotent, c'est-à-dire donner le même résultat s'il traite deux fois le même bloc.

Ce que cela ne garantit PAS

  • Un abonnement ne garantit ni l'exhaustivité (des messages peuvent manquer) ni l'unicité (un même bloc peut arriver deux fois après un rattrapage).
  • Un en-tête reçu n'est pas final.
  • Le WebSocket n'authentifie pas les données : même remarque que pour HTTP.

À retenir : s'abonner, détecter le silence, se réabonner, combler le trou, vérifier les parents.

Leçons 4/4 · 20 min

Résister aux pannes, ne pas croire une seule source

Votre point de terminaison va tomber

Un fournisseur RPC a des pannes, des maintenances, des limites de débit. Votre application doit prévoir ce jour-là. Quatre outils.

1. Attendre de plus en plus longtemps, avec du hasard

Réessayer immédiatement et sans fin aggrave la panne. On utilise un recul exponentiel (exponential backoff) : l'attente double à chaque échec jusqu'à un plafond. Exemple avec une base de 0,5 s et un plafond de 8 s : 0,5 → 1 → 2 → 4 → 8 → 8 → 8… secondes. On ajoute du hasard (jitter) : on attend une durée tirée au sort entre 0 et la valeur calculée. Pourquoi ? Si 1 000 clients perdent la connexion au même instant et réessayent tous exactement à la même seconde, ils reforment ensemble le pic qui a saturé le serveur.

2. Toujours un délai maximal et un nombre d'essais borné

Une requête sans délai maximal peut attendre pour toujours. Fixez un délai (par exemple 10 s), un nombre maximal d'essais, et à la fin affichez un état clair à l'utilisateur. Un disjoncteur (circuit breaker) pousse l'idée plus loin : après K échecs de suite sur un point de terminaison, on cesse de l'appeler pendant un temps de repos et on passe au suivant.

3. Plusieurs points de terminaison, et un contrôle de fraîcheur

Gardez une liste de fournisseurs (ou un nœud à vous plus un fournisseur) et basculez de l'un à l'autre. Mais un point de terminaison qui répond n'est pas forcément à jour. Exemple : A annonce la hauteur 1 000 120, B 1 000 121, C 1 000 050. C a 71 blocs de retard : il répond sans erreur, avec des données périmées. Un client sérieux compare les hauteurs et écarte C.

4. Ne jamais croire une source unique pour une décision importante

Pour créditer un dépôt ou déclencher un paiement, interrogez deux fournisseurs indépendants : demandez le hachage du même bloc (à une profondeur de confirmations suffisante) et comparez. S'ils concordent, la confiance monte ; s'ils divergent, n'agissez pas, et interrogez un troisième ou attendez. Limites honnêtes : deux fournisseurs peuvent dépendre de la même infrastructure en amont, et la concordance ne remplace pas la vérification cryptographique qu'offre un nœud complet ou un client léger que vous exécutez vous-même.

Limites de débit

Quand le fournisseur répond 429, respectez Retry-After. Réduisez votre consommation : mettez en cache ce qui ne change pas (un bloc ancien ne change plus), utilisez des lots, préférez l'abonnement au sondage, et ne lancez pas de centaines de requêtes en parallèle.

Vie privée : le fournisseur voit tout

Un fournisseur RPC voit votre adresse IP, la liste des adresses que vous consultez, les méthodes appelées et l'heure. Si votre portefeuille affiche cinq comptes, le fournisseur apprend que ces cinq adresses sont liées, et il peut les relier à votre IP et à une identité. HTTPS (TLS) protège le trajet contre les observateurs intermédiaires ; il ne cache rien au fournisseur lui-même, puisque c'est lui qui termine la connexion.

Parades, aucune parfaite : exécuter votre propre nœud ; répartir les requêtes entre plusieurs fournisseurs de sorte qu'aucun ne voie toutes vos adresses ; passer par un relais qui masque l'IP ; ne consulter que ce qui est nécessaire. Autre point : une clé d'API placée dans le code d'une page web est publique, puisque tout navigateur la télécharge. Elle sert à identifier un compte, pas à protéger un secret ; limitez-la côté fournisseur (domaines autorisés, plafond de débit) ou passez par votre propre serveur.

Ce que cela ne garantit PAS

  • Plus de fournisseurs ne rend pas une réponse vraie : cela diminue la probabilité de croire une erreur isolée.
  • Le hasard et le recul réduisent la charge des reprises, ils ne réparent pas la panne.
  • Un nœud local élimine la fuite de vie privée vers un tiers, mais pas votre propre exposition réseau.

À retenir : recul avec hasard, délais bornés, plusieurs sources comparées, et conscience de ce que chaque fournisseur voit.

Laboratoire guidé

Ce que le navigateur peut faire ici : vous faire écrire une vraie requête JSON-RPC et lire une vraie erreur, dont les données sont générées pour vous et corrigées par le serveur, puis analyser deux journaux de client. Ce qu'il ne peut pas faire : ouvrir un WebSocket vers un nœud ni couper un point de terminaison. Le client résilient, testé par coupure volontaire, est le laboratoire autonome. Le nœud d'entraînement utilise des méthodes fictives (chain_*), dont les noms figurent dans l'énoncé de chaque épreuve.

Le navigateur ne remplace pas un vrai terminal : ce laboratoire entraîne la lecture et le raisonnement ; la pratique réelle est dans le laboratoire autonome.

Un compte certifié est nécessaire

Les activités notées enregistrent des résultats à votre nom et servent de base à un titre. Elles exigent donc un dossier certifiant complet et un consentement en vigueur. Remplir le dossier ne vérifie pas votre identité ; le Secrétariat peut ensuite la vérifier (badge « Vérifié »).

  1. 1.Écrire une requête JSON-RPC

    Une épreuve générée vous décrit un appel (solde, bloc ou hauteur) avec la méthode et l'identifiant à utiliser. Écrivez le corps JSON complet de la requête dans le champ prévu : les quatre champs de la leçon 1 (jsonrpc, method, params si besoin, id), sans champ superflu. Attention à l'ordre des paramètres et à leur type : un nombre n'est pas une chaîne, et false n'est pas "false". Vérifiez votre JSON avant d'envoyer : une virgule en trop donnerait une erreur -32700 sur un vrai nœud.

  2. 2.Lire une erreur JSON-RPC

    Une épreuve générée affiche la réponse d'un nœud contenant l'un des cinq codes d'erreur standard (-32700, -32600, -32601, -32602, -32603). Choisissez la signification exacte de ce code dans la liste. Rappel de la leçon 2 : décidez par le code, pas par le texte. Avant de répondre, demandez-vous aussi ce que vous feriez dans votre client : réessayer, ou corriger la requête ?

  3. 3.Combler le trou après une reconnexion

    Journal d'un client qui suit les nouveaux blocs (l'heure et les numéros sont fictifs) :

    12:00:01 abonné aux en-têtes (id=0x9a)
    12:00:13 en-tête 100 traité
    12:00:25 en-tête 101 traité
    12:00:37 (aucun message)
    12:01:05 silence > 40 s : connexion jugée suspecte, fermée
    12:01:07 reconnexion, réabonnement (id=0x9b)
    12:01:11 premier en-tête reçu : 105

    Répondez à la question de la grille : combien de blocs le client doit-il aller chercher avec des requêtes ordinaires avant de traiter le bloc 105 ?

  4. 4.Calculer une attente de reprise

    Un client utilise un recul exponentiel sans hasard pour simplifier. Sa règle : la première reprise attend 1 s, chaque reprise suivante attend le double de la précédente, avec un plafond de 10 s.

    reprise 1 : attente 1 s
    reprise 2 : attente 2 s
    reprise 3 : attente 4 s
    …

    Répondez à la question de la grille : combien de secondes le client attend-il avant la 5e reprise ?

Exercice de sécurité — Ce que voit le fournisseur RPC

Un portefeuille mobile de la BAC affiche les soldes de cinq comptes de l'utilisateur. Pour cela, au démarrage, il envoie cinq requêtes de solde, l'une après l'autre, au même fournisseur RPC public, depuis la même adresse IP. Les journaux de ce fournisseur sont conservés trois mois. Sur la page d'accueil, la clé d'API du fournisseur est écrite en clair dans le code JavaScript.

Voici ce que cinq lignes de journal (fictives) montrent au fournisseur :

2026-10-12 08:00:01  IP 203.0.113.9  chain_getBalance  0xAAAA…01
2026-10-12 08:00:01  IP 203.0.113.9  chain_getBalance  0xAAAA…02
2026-10-12 08:00:02  IP 203.0.113.9  chain_getBalance  0xAAAA…03
2026-10-12 08:00:02  IP 203.0.113.9  chain_getBalance  0xAAAA…04
2026-10-12 08:00:02  IP 203.0.113.9  chain_getBalance  0xAAAA…05

(L'adresse IP est une adresse de documentation, non réelle.) Le fournisseur n'est pas accusé de malveillance : le sujet est ce qu'il PEUT apprendre, et ce qu'un journal conservé ou une fuite peut exposer à un tiers.

Question de la grille : quelle conséquence est exacte, et quelle parade réduit réellement la fuite ?

Questionnaire de l'atelier

Huit questions tirées d'une réserve plus large, seuil de réussite 70 %. Il s'ouvre quand tous les points de contrôle du laboratoire sont réussis. Vous pouvez le repasser : le tirage change.

Un compte certifié est nécessaire

Les activités notées enregistrent des résultats à votre nom et servent de base à un titre. Elles exigent donc un dossier certifiant complet et un consentement en vigueur. Remplir le dossier ne vérifie pas votre identité ; le Secrétariat peut ensuite la vérifier (badge « Vérifié »).

Laboratoire autonome (hors du site)

Non noté en ligne : à réaliser sur votre machine et à publier sur votre dépôt Git.

À faire sur votre machine, hors du site. Non noté en ligne ; évalué par une coupure volontaire du point de terminaison.

  1. En TypeScript sous Node.js (ou le langage de votre choix), écrivez un client qui : se connecte à un nœud de test par WebSocket, s'abonne aux nouveaux en-têtes et affiche numéro, hachage et hachage du parent de chaque bloc. Choisissez les bibliothèques en consultant leur documentation et notez leurs versions dans votre README : ce cours n'en impose pas.
  2. Ajoutez une détection de silence (délai égal à deux ou trois fois l'intervalle entre blocs), la reconnexion avec recul exponentiel et hasard, le réabonnement, et le rattrapage des blocs manqués par requêtes ordinaires.
  3. Gardez numéro, hachage et parent de chaque bloc traité ; détectez une réorganisation (parent inattendu) et journalisez-la.
  4. Testez : démarrez un nœud local (voir l'atelier Docker), coupez-le avec docker compose stop pendant une minute, relancez-le, et montrez dans le journal le trou comblé sans bloc manquant ni doublon.
  5. Étendez le client : interrogez deux fournisseurs RPC (ou un nœud à vous et un fournisseur) pour le hachage d'un bloc ancien de quelques confirmations, et émettez une alerte s'ils divergent.
  6. Pour la vie privée, écrivez dix lignes dans le README : ce que chaque fournisseur voit de votre client et la parade que vous avez retenue.

À retenir

  • Une requête JSON-RPC 2.0 a quatre champs (jsonrpc, method, params, id) ; la réponse contient un result OU une error, et l'id sert à les associer.
  • On décide avec le code d'erreur, jamais avec le texte : -32602 se corrige, un délai dépassé se réessaie.
  • Un abonnement WebSocket ne rejoue rien : après une coupure, on se réabonne et on comble le trou, en vérifiant les parents à cause des réorganisations.
  • Recul exponentiel avec hasard, délais et essais bornés, plusieurs points de terminaison dont on contrôle la fraîcheur.
  • Pour une décision importante, une seule source ne suffit pas ; et le fournisseur voit votre IP et toutes les adresses que vous consultez.

Idées fausses courantes

  • Idée reçue : Si le serveur répond HTTP 200, la requête a réussi.

    En réalité : Beaucoup de serveurs renvoient 200 avec un champ error dans le corps. Il faut lire le corps JSON-RPC : result ou error.

  • Idée reçue : En cas d'erreur, il suffit de renvoyer la même requête jusqu'à ce que ça passe.

    En réalité : Une erreur de paramètres ou de méthode (-32602, -32601) échouera à chaque fois ; et des reprises immédiates et sans fin aggravent une panne. On réessaie seulement les pannes passagères, avec attente croissante.

  • Idée reçue : Avec HTTPS, mon fournisseur RPC ne peut pas savoir quelles adresses je consulte.

    En réalité : HTTPS protège le trajet contre les intermédiaires. Le fournisseur termine la connexion : il lit chaque requête, avec votre IP.

Glossaire

JSON-RPC
Protocole d'appel de procédure à distance dont les messages sont du JSON : requête avec method, params et id ; réponse avec result ou error.
Point de terminaison (endpoint)
Adresse à laquelle un nœud ou un fournisseur accepte des requêtes RPC (HTTP ou WebSocket).
Recul exponentiel (backoff)
Stratégie de reprise où l'attente double après chaque échec jusqu'à un plafond, souvent avec du hasard (jitter) pour désynchroniser les clients.
Idempotent
Se dit d'une opération que l'on peut répéter sans changer le résultat au-delà de la première exécution, comme lire un solde.
Confirmations
Nombre de blocs construits au-dessus du bloc qui contient une transaction ; plus il est grand, moins une réorganisation est probable.