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). Non, voir commentaire ELois.
  • Les clients n’ont qu’une seule API à gérer (KISS). Non, voir commentaire ELois.
  • L’ API graphQL de l’indexeur est développée uniquement pour les besoins des clients riches (séparation des responsabilités).
  • Les clients ont un cluster dédié par défaut, mais peuvent choisir un autre cluster plus rapide car plus proche géographiquement.
  • Les clients ont deux API a gérer : API RPC et API indexeur. Fournir un couple d’url correspondant au même cluster intégrant des couples duniter/indexeur ajoute en fiabilité sur la synchro entre les deux APIs.
2 Likes

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 Like

J’ai mis à jour mon billet d’origine en tenant compte des commentaires d’@Elois et de ma meilleure compréhension de l’API RPC.

Dans un tel cluster, la notion de node est en fait :

  • Un full node duniter v2s (archive des blocs) avec endpoint RPC.
  • Un indexeur avec un serveur PostgreSQL
  • Outils de monitoring (ex: prometheus).

Avec docker-compose et Ansible, on devrait pouvoir mettre en place une telle plateforme.

Ça me fait penser que ce serait assez magique d’avoir un rôle Ansible fonctionnel pour les pods Cesium+, puisque ça permettrait de répondre au manque cruel d’instance actives :slight_smile:

@Hugo et @immae, je rebondis sur ce besoin d’avoir plus d’indexeurs Cesium+

Ce principe de cluster, pensé pour la migration vers Duniter V2S, peut déjà être expérimenté avec Duniter V1/Pod Cesium+.

Cela peut commencer par un docker-compose permettant d’installer un « full node V1 », blockchain + indexeur :

  • Duniter V1 avec historique des tx et endpoint BMA
  • Pod Cesium+
  • Outil de monitoring avertissant si dé-synchro.

Puis une fois le « full node » maîtrisé, la mise en place d’un cluster de trois machines avec failsafe/load balancing, pour une reprise sur panne/répartition de charge.

Pour moi, le cluster est l’étape ultime et idéal pour servir des applications utilisateurs. Mais si déjà on arrive à faire des nodes complets blockchain/indexeur qui fonctionne bien, on avancera vers plus de stabilité.

1 Like

Pour le moment je suis beaucoup en train d’apprendre l’organisation de duniter en regardant son infra, du coup je ne suis pas encore très à l’aise pour mettre en place de nouvelles choses. Mais dès que j’aurai fini de clarifier la configuration de l’infra je pourrai me pencher sur ce genre de questions

3 Likes

Oui, ce serait une super idée pour faciliter la vie aux espagnols qui doivent mettre en oeuvre tout d’un coup. Du coup je me permets de tagger les personnes qui ont des compétences ou un intérêt pour ce genre de choses d’après le recensement :

@Pini @trayeur @moul @1000i100 @bpresles @PacoVelobs @Philou

1 Like