Accès aux données indexées dans un cluster centralisé

Je continue ma réflexion sur l’accès aux données de la blockhain par les clients riches de Duniter.

Mon constat est que les clients « riches », c’est à dire ceux qui doivent proposer un maximum de fonctionnalités et d’informations utiles, ne peuvent pas se passer d’indexation. Or les index ne sont pas accessibles en réseau p2p, il sont centralisés sur les serveurs d’indexation.

La solution qui me paraît la plus simple et la plus efficace est de bien sécuriser et administrer des serveurs centralisés pour les clients riches en utilisant la technologie des clusters (comme Docker swarm ou Kubernetes). Les technologies des containers et des clusters permettent de faire du load balancing (répartition de charge) et du fail safe (reprise après panne) et permettent une montée en charge modulaire.

Les serveurs pourraient renvoyer une réponse signée au client pour garantir que celui-ci est bien connecté à un serveur de confiance de la communauté.

Pour administrer correctement ce type de serveur, il faut au minimum 3 instances dans le cluster. Si un serveur affiche des infos différentes, il est plus facile de déterminer quel serveur est en panne avec 3 serveurs (principe de la levée de doute).

Les outils de surveillance tel que prometheus ou Kibana ou Graphana permettent de détecter rapidement une dé-synchro sur un serveur et donc des indexes corrompus. Le serveur est alors déconnecté de l’extérieur en attendant sa réparation.

Pour la montée en charge, il suffit d’ajouter des serveurs, comme dans tout cluster.

Voici un schéma de principe du cluster :

duniter_v2s_cluster

Ouvrez le schéma dans un nouvel onglet ou une nouvelle fenêtre pour le voir correctement…

Avec ce principe :

  • L’ API rpc de Duniter est développée uniquement pour les besoins de l’indexeur (séparation des responsabilités).
  • L’ API graphQL de l’indexeur est développée uniquement pour les besoins des clients riches (séparation des responsabilités).
  • Les clients n’ont qu’une seule API à gérer (KISS).
  • Les clients ont un cluster dédié par défaut, mais peuvent choisir un autre cluster plus rapide car plus proche géographiquement.
1 « J'aime »

Merci @vit d’ouvrir la réflexion là-dessus, je réfléchis justement à ces sujets en ce moment :slight_smile:

Concernant les indexeur, le mieux me semble être que chaque responsable/propriétaire d’indexeur doivent publier son endpoint en blockchain. Ça permet:

  1. De limiter les droits, on peut imposer que le propriétaire/responsable soit un membre certfiié voir unr membre forgeron
  2. D’avoir une seule version de tout les endpoint qui fait consensus, grâce au consensus de la blockchain :slight_smile:

Ça prendra un peu de storage onchain, mais c’est négligeable, car la volumétrie serait faible (on aura pas 10000 indexeurs), et pour éviter le spam il suffit de demander un dépôt de Ğ1 pour pouvoir publier son endpoint.

Concernant tes conclusions par contre, il y a certaines choses que je ne ferai pas car ça représentera beaucoup trop de travail supplémentaire:

L’API RPC est fournie par substrate, je ne l’ai pas développé et ne vais pas la cassée, surtout que tout les outis de l’écosystème substrate en dépendent, dont les nombreuses lib qui aide aux développemts de wallet et autres outils interagissant avec la blockchain.

Il existe déjà plusieurs indexeurs pour substrate, et tous se suffisent de l’API RPC de base de substrate, y compris squid, donc je ne ferai pas de développements spécifiques coté API RPC pour les besoins des indexeurs.

Ça sert aussi aux outils de statistiques, et à qui veut s’en servir.
Avec squid on peut créer plusieurs processors qui indexent des choses différentes, on peut imaginer un processor dédié aux besoins des clients riches oui :slight_smile:

Ça nécessiterait de développer un serveur proxy qui fusionne 2 API en une, c’est un travail que je ne ferai pas, si quelqu’un veut le faire tant mieux, mais ça ne simplifierait pas forcément le développement des wallet, car toutes les lib qui aident à s’interfacer avec une blockchain substrate utilisent l’AP RPC directement.

Personnellement si je devais développer un wallet riche, je préfère utiliser une lib qui me simplifie la vie et qui passe par RPC, et utiliser une 2ème API pour l’indexation, que de devoir tout coder à la main pour passer par une API fusionnée.

Merci beaucoup pour ces précisions qui vont me permettre de creuser un peu mieux le modèle proposé.

Très bonne idée. C’était le point le plus faible de ce modèle, car si on a des endpoints non p2p, il est nécessaire de maintenir un annuaire pour les trouver facilement. Si en plus cet annuaire donne une certaine garantie de confiance de ses sources, c’est encore mieux !

Ok, entendu. Mais il me semblait que tu comptais en développer. Si tu développes de nouvelles méthodes pour l’API RPC, tu viserais quels types d’application ou de besoins ?

Non pas forcément, avec Hasura qui est inclus dans Subsquid, tu peux agréger plusieurs API en une en plus de l’accès à la base de données. Si cette piste s’avère concluante (je vais creuser la question) je préfère toujours n’avoir qu’une API à gérer. Parce que si un wallet doit gérer deux API, tu décales juste le problème aux développeurs des clients riches qui vont chacun faire leur implémentation du proxy d’agrégation dans leur langage au final. Cela me paraît contre productif. Si on (je ne parle pas de toi mais des développeurs de clients riches) concentre nos efforts sur un agrégateur commun (idéalement subsquid), on évite l’éparpillement des énergies.

Si on ne peut pas tout agréger dans subsquid, alors oui, le problème sera décalé dans le code des clients riches, mais si on peut l’éviter je pense que cela vaut le coût

Je suis évidemment d’accord, si et seulement si, l’affirmation :

devoir tout coder à la main

.s’avère vrai. Mais si les développeurs de clients riches réussissent à le faire en se concentrant sur Subsquid, alors je préfère largement que tous les clients riches utilisent la même API pour les fonctions.

Je disais qu’on peut en rajouter si on a besoin, il nous en faudra peut-être pour le système de stockage libre, sauf si on décide que ce soit gérer par un binaire séparé.
Peut-être aussi une méthode RPC unsafe pour calculer la distance, mais ça peut aussi être un binaire à part.
Je n’ai pas encore de développement spécifique coté RPC dont je sois certain de la nécessité.

Concernant les besoins des wallet, je pense que l’API RPC de base déjà incluse fournie déjà tout le nécessaire, mais elle est très générique et complexe a utilisée, c’est pour cela que dans la pratique tous les développeurs de walllet utilisent des bibliothèques intermédiaires qui font une grande partie du travail.

Je pense que ce sera infiniment plus facile pour vous de passer par une lib substrate pour gérer l’API RPC et vous n’aurez que l’API de duniter-squid à gérer manuellement.

Ce que tu veux faire va s’avérer beaucoup plus difficile et complexe que de gérer 2 API, tu vas être obliger de recoder toute une lib substrate pour refaire ce que fait polkadot/apipy-substrate-interface.

Ça revient à réinventer la roue, ça me semble très contre-productif.

En plus il y a toute une partie qui n’est pas déplaçable sur un serveur: l’encodage SCALE de l’extrinsic, ça doit nécessairement être fait par le client car il doit vérifier ce qu’il signe, ce ne serait pas acceptable de signer une opaque payload fournie par un serveur.

Or cet encodage SCALE se base sur des métadonnées que les lib récupèrent via l’api RPC.

Ah oui, là évidemment on peut pas faire l’impasse sur l’API RPC…

Je vais donc avancer sur une implémentation de py-substrate-interface dans Tikka pour voir comment se répartissent les fonctionnalités disponibles entre l’API RPC et l’indexeur Subsquid. Comme toi, j’ai besoin d’avancer dans l’implémentation pour valider ou pas mes intuitions. :wink:

1 « J'aime »