Aller au contenu principal

Découverte de pairs

Un nœud rejoint en composant un entrypoint et trouve le reste du réseau lui-même. La découverte de pairs (OFS-1100) échange les pairs connus sur la même connexion que le gossip utilise déjà, donc un nœud apprend des pairs qu’on ne lui a jamais donnés et annonce les adresses où il est atteignable.

Cela vaut la peine d’être énoncé clairement car ce n’a pas toujours été vrai, et l’échec était invisible : le service de découverte était pleinement implémenté et a fait converger cinq nœuds dans son propre test, et aucun nœud en marche n’en a jamais construit un. Les nœuds n’annonçaient aucune adresse et n’apprenaient aucun pair qu’on ne leur avait donné statiquement, tout en paraissant entièrement sains à chaque vérification locale. Un nœud a un swarm libp2p, une seule chose peut piloter la boucle d’événements de ce swarm, et le gossip la tenait — donc le service qui n’était pas propriétaire du swarm ne recevait rien, à jamais. Les deux partagent désormais une connexion, et les messages sont routés vers l’un ou l’autre par le propre numéro de spec OFS de l’enveloppe.

La découverte n’est pas un flag et ne peut être désactivée.

La première connexion

Rien ne peut trouver un réseau à partir de rien, donc --entrypoint est encore la façon dont un nœud démarre :

openfiat-node --entrypoint /dns4/openfiat.allenhark.com/udp/4001/quic-v1/p2p/12D3KooW...

Répétez-le pour plusieurs. Un nom d’hôte fonctionne et est préféré — le nœud le résout au démarrage via le propre résolveur du système d’exploitation, donc le cluster survit au changement d’IP de l’entrypoint. Gardez le suffixe /p2p/<peer id> : le DNS n’est pas authentifié, et le peer id est ce qui fait qu’un enregistrement détourné échoue la poignée de main au lieu de devenir en silence votre unique pair.

Un entrypoint qui ne se résoudra pas arrête le nœud au démarrage au lieu d’être sauté. Un nœud qui en écarterait un en silence démarrerait sans aucun pair et paraîtrait parfaitement sain tout en ne parlant à personne — ce qui est exactement l’échec par lequel cette section a ouvert.

Démarrez sans aucun entrypoint et le nœud le dit, en WARN. C’est correct pour le premier nœud d’un nouveau cluster et faux pour tous les autres.

Ce que votre nœud annonce sur lui-même

Chaque adresse sur laquelle le nœud sait qu’il écoute, moins le joker de bind. 0.0.0.0 et :: sont des instructions d’écoute signifiant « chaque interface locale », pas des destinations — et comme --gossip-bind-address vaut par défaut exactement cela, l’annoncer sans filtre est précisément le bug qui laisse les pairs sans rien à composer.

Les plages loopback et privées ne sont délibérément pas filtrées. Des processus sur un hôte s’atteignent par loopback, un cluster docker-compose ou un LAN n’atteint ses pairs que par adresse privée, et un cluster mono-hôte est un déploiement réel, et non un artefact de test.

Derrière un NAT, dans un conteneur, ou sur un hôte cloud avec une IP mappée

L’adresse que votre nœud lie n’est pas l’adresse où les pairs peuvent l’atteindre, et le nœud ne peut déduire la publique. Ce n’est pas un oubli — par construction, seul quelque chose de l’autre côté du NAT peut observer l’adresse publique. L’opérateur la déclare donc :

--external-addr /ip4/203.0.113.7/udp/4001/quic-v1

Répétable. Les adresses déclarées sont annoncées avant les liées, donc un pair qui les essaie dans l’ordre se connecte à la première tentative au lieu d’expirer sur 172.17.0.2. Les adresses liées sont encore annoncées aussi — les écarter corrigerait le cas distant en cassant le local.

Omettez le flag si votre nœud est vraiment sur une interface publique. Son adresse liée est déjà sa publique.

Demander à un nœud ce qu’il sait

curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"getPeers","params":{}}' | jq
{
"self_peer_id": "12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1",
"announced_addresses": ["/ip4/203.0.113.7/udp/4001/quic-v1"],
"peers": [
{
"peer_id": "12D3KooW...",
"addresses": ["/ip4/198.51.100.4/udp/4001/quic-v1"],
"node_version": "openfiat/0.1.0",
"supported_ofs": [1000, 1100, 1200, 1300, 1400, 1500, 2000, 2100, 2200, 2300, 2400, 3000, 4000, 4300, 6000, 7000, 8200],
"roles": ["MerchantGateway", "OracleProvider", "NotificationGateway", "RiskIntelligenceProvider"],
"last_seen": 1753800000000,
"latency_ms": 42,
"successes": 17,
"failures": 0
}
]
}

Trois choses valent la peine d’être sues sur cette réponse.

self_peer_id est la forme 12D3Koo… qui va dans l’entrypoint que vous publiez à d’autres opérateurs. Un nœud qui ne peut énoncer son propre peer id ne peut être rejoint, et l’assembler depuis une ligne de journal est la façon dont il est mal tapé.

announced_addresses est ce que vous dites aux pairs de composer, dans l’ordre où ils les essaieront. « Mon nœud n’annonce rien » était invisible de l’extérieur tant que c’était vrai, et un opérateur qui vérifie si son --external-addr a pris effet n’a nulle part ailleurs où regarder.

successes et failures sont le décompte propre à ce nœud des échanges avec ce pair. Il n’y a délibérément pas de pourcentage de disponibilité ni de score de santé : replier les deux décomptes en un nombre présenterait l’expérience locale d’un seul nœud comme un verdict à l’échelle du réseau, et deux nœuds honnêtes peuvent être en désaccord sur les deux.