Article de Griffin Ichiba Hotchkiss sur blog.ethereum.org, traduit par Jean Zundel

Cet article – toujours aussi technique – revient sur l’amélioration du réseau Ethereum actuel, celui qui tourne en production en attendant les bouleversements d’ETH 2.0. Le sommet de Paris a permis de mieux dégager les grandes lignes de la recherche, résumées ici dans une nouvelle version de ce fameux arbre des technologies.

Désolé pour le retard de cet article ; certaines distractions inévitables sont récemment venues perturber ma vie, tout comme la vôtre certainement. J’espère que vous faites du mieux que vous pouvez dans ces circonstances et je vous supplie de monter votre niveau d’empathie à 11 dans les mois qui viennent et d’aider autant que possible les gens à risque dans votre communauté. 

Cela dit, parlons de Stateless Ethereum et des changements dans l’arbre des technologies !

D’un point de vue graphique, l’arbre a été complètement retravaillé, mais si vous le comparez à l’original, vous remarquerez qu’une grande partie du contenu est identique. Dans un souci d’exhaustivité et pour éviter toute confusion, cet article passera en revue tous les sujets : vous pouvez aussi bien fermer cet onglet que vous venez d’ouvrir en arrière-plan. Sans plus attendre, je vous présente l’Arbre des Technologies Du Sans État mis à jour :

Chaque étape majeure en rose représente une catégorie définie à grosses mailles qui doit être « résolue » avant de passer aux suivantes. Elles sont volontairement un peu vagues, et ne représentent pas d’EIP ni de fonctionnalité homogène, bien que certaines d’entre elles puissent y correspondre.

Les petits éléments en violet représentent des dépendances plus spécifiques qui mèneront au « déblocage » des étapes. Elles sont requises dans le sens où elles doivent être pleinement comprises avant que l’étape puisse être considérée comme atteinte, mais elles n’ont pas besoin d’être implémentées ou acceptées. Par exemple, il est possible qu’après certaines recherches, nous découvrions que la merklisation du code ne réduise pas suffisamment la taille des signatures témoins (les witnesses) pour justifier le temps et les efforts nécessaires à leur implémentation ; nous le considérerions comme « fini », parce qu’il ne serait plus nécessaire de l’étudier.

Comme vous pouvez déjà le deviner, les cases en vert représentent les « quêtes parallèles » qui seraient théoriquement utiles pour Stateless Ethereum, mais qu’un chercheur peut ne pas considérer comme prioritaires. D’autres pourront être découvertes en chemin ; je les ajouterai au fur et à mesure.

Nous avons aussi des éléments en jaune qui tombent dans la catégorie des outils. Encore inexistants, ils nous aideront à valider des hypothèses et des implémentations de test, et, plus généralement, ils accélèreront les travaux. Idéalement, ces outils seront d’une qualité suffisante et seront assez correctement maintenus pour bénéficier à tout l’écosystème des développeurs, y compris hors du contexte de Stateless Ethereum.

Un autre protocole de synchronisation

La plus importante des leçons à retenir du sommet est que la synchronisation est la première étape majeure pour Stateless Ethereum. Plus précisément, nous devons trouver un moyen pour que les nouveaux nœuds récupèrent le trie d’état actuel sans se reposer sur la primitive réseau GetNodeData. Tant qu’une autre méthode n’a pas été trouvée (beam sync et fast sync en dépendent), les efforts pour arriver à Stateless Ethereum seront entravés voire contre-productifs. Il nous faut maintenant creuser un peu ce sujet pour expliquer en quoi il pose problème. Si vous n’êtes pas familier avec les bases de l’état dans Ethereum, je recommande de consulter mes précédents articles dans cettes série.

D’abord, démystifions ce jargon. Il n’existe pas vraiment de définition technique pour le terme « primitive réseau » dans ce contexte, sinon « la grammaire de base des communications réseau d’Ethereum ». Un client demande « Hola, quelles sont les données du nœud avec le hash 0xtoto ? Et un pair peut répondre « Hmm, c’est 0xlulu ». Dans la plupart des cas, la réponse contient des hashs supplémentaires de nœuds fils dans le trie, que l’on peut ensuite requêter de la même manière. Ce jeu de colin-maillard continue jusqu’à ce que le requérant soit satisfait, généralement après avoir demandé chacun des 400 millions de nœuds dans le trie d’état actuel.

Cette synchronisation peut quand même être rapide parce qu’un client est évidemment multi-tâches et peut demander à de nombreux autres nœuds complets des fragments différents de l’état en même temps. Mais il reste un problème plus fondamental dû à la façon dont fonctionne la primitive : ceux qui demandent l’état – les leechers – le font à leur convenance, et il ne peuvent obtenir ce dont ils ont besoin que de seeders, des nœuds avec un état complet. Cette relation asymétrique constitue la base du fonctionnement actuel et, jusqu’ici, tout va bien en raison de deux faits liés concernant le réseau. D’abord, il existe un nombre suffisant de nœuds complets qui présentent l’état aux requêtes. Ensuite, ceux qui demandent l’état finissent par devenir des nœuds complets, et la demande d’état se limite d’elle-même.

Nous voyons maintenant en quoi cela représente un problème pour un Ethereum sans état : dans ce dernier paradigme, les nœuds qui ne conservent pas les données de l’état vont demander continûment des données. S’il est plus facile de faire tourner un nœud sans état qu’un nœud complet (c’est le cas), nous pouvons nous attendre à ce que le nombre de ceux-là dépasse rapidement le nombre de ceux-ci, jusqu’à ce que le réseau soit finalement incapable de propager assez rapidement l’état. Aïe.

Nous n’avons pas le temps d’aller plus avant dans les détails. Je vous renvoie à la présentation de ce problème par Piper, et nous allons pouvoir passer aux solutions émergentes, qu’il s’agisse d’améliorer le protocole de synchronisation de l’état, d’atténuer le problème ou de le résoudre complètement. Voici les trois protocoles les plus prometteurs :

Ethereum Snapshot Protocol (SNAP). Nous en avons déjà parlé, mais je l’avais appelé state tiling, « mosaïque de l’état ». Il a été plus longuement décrit par Peter dans le repo devp2p. Snap sépare l’état en quelques parties de grande taille avec leurs preuves (de l’ordre de 10000 nœuds de trie) qui peuvent être réassemblées pour constituer un nœud complet, et en un court laps de temps obtenir une image presque valide de l’état en accolant une centaine de racines d’état similaires. Pour finir, le client complète cette image en repassant à getNodeData, ceci jusqu’à obtenir un état valide.

Fire Queen’s Sync. Pas de grand changement depuis ce qui en a été dit dans le premier article sur l’arbre des technologies, sinon pour le nom, qui est une combinaison de firehose (bouche d’incendie) et Red Queen’s. Ce sont des propositions très similaires de remplacement de getNodeData par un autre ensemble de primitives pour divers aspects de l’état.

Merry-go-round. Il s’agit d’une nouvelle idée exposée rapidement sur ethresear.ch et plus concrètement décrite dans les notes. Dans cette synchronisation en manège, tout l’état est passé dans un ordre prédéterminé, afin que tous les participants diffusent la même partie de l’état au même moment. Pour synchroniser tout l’état, il faut terminer une « révolution » complète sur le manège en ayant couvert toutes les parties de l’état. Ce concept possède quelques propriétés intéressantes. D’abord, il permet aux nouveaux nœuds de contribuer immédiatement à la propagation de l’état au lieu de ne devenir utiles au réseau qu’après une synchronisation complète. Ensuite, il inverse le modèle actuel de synchronisation gouvernée par la demande où ceux qui n’ont pas de données peuvent demander des parties de l’état à volonté. Ces nouveaux nœuds sauraient quelles parties de l’état seraient offertes à un moment donné et pourraient s’ajuster en conséquence.

La dernière méthode de synchronisation qui vaille la peine d’être mentionnée ici est beam sync, maintenant supportée par deux clients. Beam sync repose toujours sur getNodeData, mais il offre un point d’entrée idéal pour expérimenter et collecter des données pour les autres méthodes de synchronisation. Il faut noter qu’il reste de nombreuses inconnues concernant la synchronisation et qu’il est important de multiplier les approches différentes pour résoudre ce problème. Les prochains mois pourront ressembler à une sorte de hackathon, dont les idées seront prototypées et testées. Idéalement, les meilleurs aspects de chacun de ces protocoles pourront être assemblés dans un nouveau standard pour Stateless Ethereum.

Prototype de spécification de signature

Il existe une ébauche dans le repository des spécifications pour Stateless Ethereum qui décrit à un haut niveau la structure d’une signature témoin de bloc, et les sémantiques de création et de modification depuis le trie d’état. Le but de ce document est de définir sans ambiguïté les signatures afin que les programmeurs, quelque soit le langage utilisé, puissent écrire leur propre implémentation avec une bonne probabilité d’aboutir au même résultat qu’une autre écrite d’après les mêmes spécifications.

Comme je l’ai mentionné dans le dernier call digest, il ne semble pas qu’il y ait des inconvénients à écrire une implémentation de référence pour les signatures témoins de bloc et à l’incorporer dans les clients existant à fins de tests. Une fonctionnalité de prototype de signature serait une option externe à activer, et quelques testeurs sur le réseau produisant et relayant les signatures fourniraient des informations intéressantes que les chercheurs pourraient intégrer dans les améliorations ultérieures.

Deux problèmes doivent être « résolus » avant que les signatures soient assez résilientes pour être considérées prêtes pour une généralisation de leur usage.

Indexation des signatures. Celle-ci est relativement simple : nous avons besoin d’une manière fiable de déterminer si la signature correspond à un bloc donné et à son état associé. Cela pourrait être aussi simple qu’un champ witnessHash dans l’en-tête du bloc, ou bien quelque chose similaire mais d’une autre manière.

Validation de transactions sans état. C’est un problème intéressant apparu dès le départ et décrit exhaustivement sur les forums de etheresear.ch. En bref, les clients doivent rapidement vérifier si les transactions entrantes (qui attendent d’être minées) sont au moins éligibles pour être incluses dans un futur bloc. Cela empêche les attaquants de spammer le réseau par des transactions invalides. La vérification actuelle, cependant, demande d’accéder à des données faisant partie de l’état, à savoir le nonce et le solde du compte de l’expéditeur. Un client sans état ne pourra pas effectuer cette vérification.

Il y a certainement plus de pain sur la planche que ces deux problèmes spécifiques qui nous attendent avant que de pouvoir disposer d’un prototype fonctionnel de signatures, mais ces deux-là doivent absolument être résolus pour mettre à disposition un prototype viable de nœud beam sync près de chez vous.

EVM

Comme dans la version originelle de l’arbre des technologies, des changements seront nécessaires à l’intérieur de l’abstraction de l’EVM. Les signatures, en particulier, doivent être générées et propagées à travers le réseau, et cette activité doit être prise en compte dans les opérations de l’EVM. Les sujets liés à cette étape sont liés aux incitations et aux coûts induits, ainsi qu’à la façon de les estimer et de les implémenter avec un impact minimal sur les couches supérieures.

Prise en compte du gaz des signatures. Rien ne change par rapport aux articles précédents. Chaque transaction sera responsable d’une petite partie de la signature du bloc. La génération d’icelle implique des calculs effectués par le mineur du bloc et se verra donc associer un coût en gaz, payé par l’émetteur de la transaction.

Merklisation du code. L’une des principales composantes d’une signature est le code qui l’accompagne. Sans cela, une transaction contenant un appel à un contrat devrait contenir le code complet de celui-ci pour vérifier son codeHash, ce qui peut représenter beaucoup de données selon le contrat. La « merklisation » du code consiste à éclater le bytecode du contrat pour que seule la portion du code appelé soit requise pour générer et vérifier la signature témoin d’une transaction. Cette technique réduit drastiquement la taille moyenne des signatures témoins, mais n’a pas encore été étudiée à fond.

Les changements de UNGAS / Versionless Ethereum ont maintenant été retirés du « chemin critique » de Stateless Ethereum. Ces fonctionnalités restent potentiellement intéressantes mais il est devenu clair au cours du sommet que leurs mérites et leurs particularités peuvent et doivent être traités indépendamment des buts du sans-état.

La transition vers un trie binaire

Le passage à une structure de trie binaire de l’état est la clef pour obtenir des tailles de signatures assez petites pour être diffusées dans le réseau sans se heurter à des problèmes de bande passante ou de latence. On devrait théoriquement obtenir au moins une réduction d’un facteur 3, mais elle devrait être en pratique moins importante (à cause de la taille du code des contrats dans les signatures, d’où l’importance potentielle de la merklisation du code).

La transition vers une représentation des données complètement différente constitue un changement radical, et l’activation de cette transition par un hard fork sera un processus délicat. Deux stratégies soulignées dans l’article précédent restent inchangées :

Progressive. Le trie d’état sénaire serait transformé petit à petit sur une longue période de temps. Toute transaction, toute exécution de l’EVM touchant à une partie de l’état encoderait de ce fait les changements de l’état dans la nouvelle forme binaire. Cela implique l’adoption d’une structure de trie « hybride » laissant les parties dormantes de l’état dans leur représentation sénaire actuelle. Le processus resterait de fait toujours incomplet et complexifierait l’implémentation des clients, mais isolerait en grande partie les utilisateurs et les développeurs d’applications des changements opérés en couche 0.

En masse. Cette stratégie calculerait une nouvelle représentation binaire du trie de l’état à un moment prédéterminé, puis continuerait sous forme binaire une fois le nouvel état calculé. Bien que plus simple à mettre en œuvre, une action de masse demande la coordination de tous les opérateurs de nœuds, et elle impliquerait presque certainement une perturbation limitée du réseau en affectant les utilisateurs et les développeurs pendant la transition.

Il existe cependant une nouvelle proposition de transition qui offre un compromis entre ces deux stratégies. Elle est intégralement décrite sur les forums de ethresear.ch.

Overlay. Dans ce scénario de superposition, les nouvelles valeurs issues de transactions après un certain temps sont stockées directement dans un arbre binaire situé « au-dessus » du sénaire, alors que l’arbre sénaire « historique » est converti en tâche d’arrière-plan. Quand la couche de base aura été complètement convertie, les deux pourront être fusionnées.

Un facteur supplémentaire à prendre en compte pour la transition vers un trie binaire est l’organisation de la base de données des clients. Actuellement, tous les clients utilisent l’approche « naïve » pour le trie d’état, en stockant chaque nœud du trie sous forme de paire [clef, valeur] où le hash du nœud est la clef. Il est possible que la stratégie de transition puisse offrir aux clients l’opportunité de basculer vers une autre structure de base de données, suivant en cela l’exemple de turbo-geth.

Un vrai Ethereum sans état

Les dernières parties de l’arbre s’assembleront après avoir testé et amélioré le prototype de signature témoin, effectué les changements nécessaires sur l’EVM et passé le trie d’état en binaire. Ces quêtes plus lointaines et ces quêtes parallèles doivent être réalisées à la fin, mais il vaut mieux ne pas trop y penser avant que des sujets plus pressants aient été terminés.

Signatures obligatoires. Les signatures témoins doivent être générées par les mineurs, et on ne sait pas si ceux-ci vont chercher à éviter les quelques millisecondes de génération de la signature. Cela peut être en partie compensé en ajustant les frais que les mineurs touchent des signatures partielles incluses avec les transactions, mais le moyen le plus sûr est de l’intégrer au protocole d’Ethereum. Ce changement ne peut se produire qu’après nous être assurés que tout fonctionne comme prévu, et il se retrouve donc à la fin de l’arbre.

Découpage des signatures. Autre fonctionnalité à envisager, la possibilité pour un réseau sans état de diffuser des morceaux de signatures au lieu de blocs entiers. Cela bénéficierait surtout aux nœuds à état partiel, qui pourraient choisir de conserver les parties de l’état qui les intéressent en premier lieu puis de récupérer d’autres parties pour d’autres transactions.

Accumulateurs historiques. Conçus à l’origine comme un système mathématique vaudou à divulgation nulle de connaissance, un accumulateur historique faciliterait grandement la vérification d’une signature historique. Cela permettrait à un nœud sans état d’effectuer des requêtes et des vérifications sur, par exemple, le solde historique d’un compte qui l’intéresse, sans avoir besoin de récupérer une partie spécifique d’état archivé.

Données de chaîne sur DHT. Bien que l’idée d’un réseau de distribution de données d’état par table de hachage ait été plus ou moins abandonné, il resterait utile et plus facile à implémenter pour les données de chaîne historiques comme les reçus de transactions. Cela pourrait fournir une autre approche pour permettre aux clients sans état d’accéder à volonté aux anciennes données qui seraient normalement obtenues depuis un nœud archive.

Restez chez vous, restez en ligne

Merci d’avoir lu, et merci pour tous les commentaires positifs que j’ai récemment reçu sur ces mises à jour. J’ai quelque chose de plus… magique en prévision pour les articles suivants sur la recherche concernant Stateless Ethereum, que je posterai occasionnellement sur le forum Fellowship of the Ethereum Magicians, ainsi que sur ce blog quand je le jugerai utile. En attendant, restez à distance et lavez-vous souvent les mains !

Comme toujours, si vous avez des retours, des questions ou des requêtes de nouveaux sujets, vous pouvez joindre @gichiba ou @JHancock sur Twitter.