Resolve "Add RPC method to list peers"
#97 (closed)
ClosesMR en français pour faciliter l'écriture de la MR et la revue de code.
duniter_peerings
Fonctionnalité : nouvelle méthode RPC Cette méthode renvoie une liste de fiches de pairs contenant, pour chaque pair, une liste d'endpoints publics que le nœud déclare liés à sa propre clé publique.
Les endpoints sont déclarés par chaque nœud grâce aux options suivantes lancées à leur démarrage :
--public-rpc <PUBLIC_RPC>
Public RPC endpoint to gossip on the network and make available in the apps
--public-squid <PUBLIC_SQUID>
Public Squid graphql endpoint to gossip on the network and make available in the apps
--public-endpoints <PUBLIC_ENDPOINTS>
Public endpoints from a JSON file, using following format where `protocol` and `address` are strings (value is free) :
```json { "endpoints": [ { "protocol": "rpc", "address": "wss://gdev.example.com" }, { "protocol": "squid", "address": "gdev.example.com/graphql/v1" }, { "protocol": "other", "address":
"gdev.example.com/other" } ] } ```
Exemple d'utilisation
curl -X POST http://localhost:9944 \
-H 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","id":1,"method":"duniter_peerings","params":{}}'
Exemple de réponse
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"peers": [
{
"peer_id": "12D3KooWHyUiZges2LWtwKjcd8wJzu8LidKR3533Wz4VhBGxt1ux",
"endpoints": [
{
"protocol": "rpc",
"address": "localhost:8000/ws"
},
{
"protocol": "squid",
"address": "localhost:8001"
}
]
},
{
"peer_id": "12D3KooWEjx6iQQkGcbD3D5BBDjgCx3f3hpM5SkVjUYF7aAjoUpU",
"endpoints": [
{
"protocol": "squid",
"address": "localhost:3000/v1/graphql"
}
]
}
]
}
}
Protocole d'échange de fiches de pair
Cette MR reprend le principe appliqué dans Duniter v1, c'est-à-dire de disposer d'un document qui lie une clé publique de nœud à certaines variables, ici pour le moment des endpoints publics pour l'API RPC du nœud et l'API Squid.
Le protocole repose sur les mécaniques réseau exposées par Substrate, et notamment sur le protocole de notifications qui abstrait très largement la couche réseau. L'autre protocole disponible, non utilisé ici, est celui de requête/réponse.
Principe général de la couche de notifications de Substrate
C'est un protocole unidirectionnel d'envoi de message, par opposition au protocole bidirectionnel type requête/réponse. Ici, la notification est envoyée à discrétion par le nœud local à chaque pair qui a accepté un canal de communication pour ce protocole. Le pair distant peut également avoir un canal de communication dans l'autre sens, mais il ne s'agit pas d'un canal de réponse.
Cette couche se base elle-même sur la couche réseau (implémentation litep2p, inspiré de libp2p), et stipule que, lors de l'établissement d'une connexion du nœud local avec un pair distant, si ceux-ci ont en commun des sous-protocoles supportés, alors le nœud local tente d'établir un sous-canal de communication avec le pair distant pour chaque protocole.
Le nœud distant faisant de même, il y a alors 3 situations possibles qui sont gérées automatiquement par Substrate :
- Le nœud local est l'initiateur du canal et acceptera l'ouverture du canal réciproque
- Le nœud local n'est pas l'initiateur et va tenter d'ouvrir le canal réciproque
- Les deux nœuds ont tenté en même temps de se connecter, fermeture du canal pour re-tenter plus tard (quelques secondes tout au plus)
/duniter-peerings/1
(Duniter Gossip v1)
Principe spécifique au protocole Une fois le canal vers le pair distant établi, le nœud local tente d'envoyer sa fiche de pair (informations portées par les options --public_rpc <adresse>
et --public-squid <adresse>
). Le nœud distant l'accepte telle quelle, du moment que le format correspond (simple sérialisation/déserialisation). Les valeurs ne sont pas vérifiées, étant entendu que le canal garantit que les échanges sont sécurisés et que le message provient bien du nœud qui émet le message. La fiche est alors stockée en mémoire vive, et sera rendue visible en cas d'appel à la méthode RPC duniter_peerings
par le nœud qui a reçu la fiche de pair.
Au démarrage, chaque nœud auto-génère sa propre fiche également et la rend disponible via cette même méthode RPC.
Contraintes
Anti-spam
Une fiche de pair n'est accepté qu'une et une seule fois par connexion. C'est-à-dire que, pour en transmettre une nouvelle version, en l'état actuel du code le nœud distant doit redémarrer. Cela est toutefois cohérent avec le cycle de vie de la définition des endpoints qui se font par option au lancement du nœud (options --public_rpc <adresse>
et --public-squid <adresse>
).
L'envoi reste possible, mais le nœud distant ne mettra pas à jour la fiche de pair de son côté. Celle-ci sera juste droppée et le nœud distant abaissera la note de fiabilité du nœud connecté, jusqu'à d'éventuelles sanctions (dont probablement la déconnexion et la bannissement temporaire, je n'ai pas creusé davantage la question). Toutefois, le code de la présente MR ne renvoie pas deux fois la fiche de pair locale au nœud distant.
Émetteur
La fiche de pair reçu d'un canal et interprétée comme étant celle de l'initiateur du canal. Etant donné le point précédent sur l'anti-spam, un canal ne doit donc théoriquement (hors fork de Duniter) voir passer qu'un seul message dans la vie du canal.
Types et valeurs d'endpoints
Il n'y a pas de contrainte. Un nœud peut déclarer les protocoles Duniter qu'il souhaite, même des nouveaux.
Toutefois, les protocoles squid
et rpc
sont supposés signifier ce qu'on entend aujourd'hui par API RPC Substrate et API Squid dans le cadre du projet Duniter v2.
Autres
Par défaut (SetConfig::default()
dans le code) pour la configuration du canal de notifications :
- Nombre de pairs entrants max : 25
- Nombre de pairs sortants max : 75
- Pas de nœuds réservés pour ce protocole, ouvert à tous
Détails de la couche de notification
- Il faut créer une configuration de protocole de notifications (nom, nombre de pairs acceptés en réception/émission, ...)
- Et une tâche de fond qui écoute les notifications réseau (reçues si le nœud est appairé avec un autre)