Le guide faisant autorité pour le partage de blockchain

Salut, je suis l'un des développeurs du protocole Blockchain Nearded sharded, et dans cet article je veux parler de ce qu'est le partage de blockchain, comment il est mis en œuvre et quels problèmes existent dans les conceptions de partage de blockchain.


Il est bien connu qu'Ethereum, la blockchain à usage général la plus utilisée au moment de la rédaction de ce document, ne peut traiter que moins de 20 transactions par seconde sur la chaîne principale. Cette limitation, couplée à la popularité du réseau, conduit à des prix élevés du gaz (le coût d'exécution d'une transaction sur le réseau) et à de longs délais de confirmation; malgré le fait qu'au moment d'écrire ces lignes, un nouveau bloc est produit toutes les 10 à 20 secondes environ, le temps moyen qu'il faut pour qu'une transaction soit ajoutée à la blockchain est de 1,2 minute, selon ETH Gas Station . Le faible débit, les prix élevés et la latence élevée font que Ethereum n'est pas adapté pour exécuter des services qui doivent évoluer avec l'adoption.


Quelle est la principale raison du faible débit d'Ethereum? La raison en est que chaque nœud du réseau doit traiter chaque transaction. Les développeurs ont proposé de nombreuses solutions pour résoudre le problème du débit au niveau du protocole. Ces solutions peuvent être principalement séparées en celles qui délèguent tout le calcul à un petit ensemble de nœuds puissants, et celles qui ont chaque nœud dans le réseau ne font qu'un sous-ensemble de la quantité totale de travail. Un cas extrême de l'ancienne approche est Thunder qui a un seul nœud traitant toutes les transactions et prétend atteindre 1200 tx / sec, une amélioration de 100x par rapport à Ethereum (je n'approuve cependant pas Thunder, ni n'atteste de la validité de leurs revendications ) Algorand , SpaceMesh , Solana entrent tous dans la première catégorie, construisant diverses améliorations dans le consensus et la structure de la blockchain elle-même pour exécuter beaucoup plus de transactions, mais toujours limitées par ce qu'une seule machine (bien que très puissante) peut traiter.


Cette dernière approche, dans laquelle le travail est réparti entre tous les nœuds participants, est appelée sharding. C'est ainsi que la Fondation Ethereum prévoit actuellement de faire évoluer Ethereum. Au moment d'écrire ces lignes, la spécification complète n'est toujours pas publiée. Voici des liens vers un aperçu détaillé des chaînes de fragments Ethereum et de la chaîne Beacon .


Dans cet article, je résume les idées fondamentales du partage de chaînes de blocs, sur lesquelles reposent à la fois Near et la majorité des autres protocoles fragmentés. Le post suivant décrira des sujets plus avancés dans le partage.


Le sharding le plus simple, alias haricot magique


Commençons par l'approche la plus simple de partage, que nous appellerons tout au long de cette rédaction un Beanstalk. C'est aussi ce que Vitalik appelle «la mise à l'échelle par mille altcoins» dans cette présentation.


Dans cette approche, au lieu d'exécuter une blockchain, nous en exécuterons plusieurs et appellerons chacune de ces blockchain un "fragment". Chaque fragment aura son propre ensemble de validateurs. Ici et ci-dessous, nous utilisons un terme générique de «validateur» pour désigner les participants qui vérifient les transactions et produisent des blocs, soit par extraction, comme dans Proof of Work, soit via un mécanisme basé sur le vote. Pour l'instant, supposons que les fragments ne communiquent jamais entre eux.


La conception de Beanstalk, bien que simple, est suffisante pour souligner certains défis majeurs dans le partage.


Partitionnement du validateur et chaînes de balises


Le premier défi est qu'avec chaque fragment ayant ses propres validateurs, chaque fragment est désormais 10 fois moins sécurisé que la chaîne entière. Donc, si une chaîne non fragmentée avec X validateurs décide de hard-fork en une chaîne fragmentée et divise X validateurs en 10 fragments, chaque fragment n'a désormais plus que X / 10 validateurs, et la corruption d'un fragment ne nécessite que la corruption de 5,1% (51% / 10) du nombre total de validateurs.


Ce qui nous amène au deuxième point: qui choisit les validateurs pour chaque fragment? Le contrôle de 5,1% des validateurs n'est préjudiciable que si tous ces 5,1% de validateurs sont dans le même fragment. Si les validateurs ne peuvent pas choisir dans quel fragment ils valident, un participant contrôlant 5,1% des validateurs a très peu de chances d'obtenir tous leurs validateurs dans le même fragment, ce qui réduit considérablement leur capacité à compromettre le système.


image


Aujourd'hui, presque toutes les conceptions de partitionnement reposent sur une source aléatoire pour attribuer des validateurs aux fragments. L'aléatoire sur la blockchain en soi est un sujet très difficile et mériterait un article de blog distinct à une date ultérieure, mais pour l'instant supposons qu'il existe une source d'aléatoire que nous pouvons utiliser.


Le caractère aléatoire et l'affectation des validateurs nécessitent un calcul qui n'est pas spécifique à un fragment particulier. Pour ce calcul, pratiquement toutes les conceptions existantes ont une chaîne de blocs distincte chargée d'effectuer les opérations nécessaires à la maintenance de l'ensemble du réseau. Outre la génération de nombres aléatoires et l'attribution de validateurs aux fragments, ces opérations incluent souvent la réception de mises à jour à partir de fragments et la prise de clichés de ceux-ci, le traitement des enjeux et des coupures dans les systèmes de preuve de participation et le rééquilibrage des fragments lorsque cette fonctionnalité est prise en charge. Cette chaîne est appelée chaîne Beacon dans Ethereum and Near, chaîne relais dans PolkaDot et Cosmos Hub dans Cosmos.


Tout au long de ce post, nous ferons référence à une telle chaîne comme une chaîne Beacon . L'existence de la chaîne Beacon nous amène au prochain sujet intéressant, le sharding quadratique.


Partage quadratique


Le partage est souvent annoncé comme une solution qui évolue à l'infini avec le nombre de nœuds participant au fonctionnement du réseau. Bien qu'il soit en théorie possible de concevoir une telle solution de partage, toute solution qui a le concept d'une chaîne Beacon n'a pas une évolutivité infinie. Pour comprendre pourquoi, notez que la chaîne Beacon doit effectuer certains calculs de comptabilité, tels que l'attribution de validateurs aux fragments ou la capture instantanée de blocs de chaînes de fragments, qui est proportionnelle au nombre de fragments dans le système. Étant donné que la chaîne Beacon est elle-même une chaîne de blocs unique, le calcul étant limité par les capacités de calcul des nœuds qui l'exploitent, le nombre de fragments est naturellement limité.


Cependant, la structure d'un réseau fragmenté confère un effet multiplicatif sur toute amélioration de ses nœuds. Prenons le cas dans lequel une amélioration arbitraire est apportée à l'efficacité des nœuds du réseau, ce qui leur permettra des temps de traitement des transactions plus rapides.


Si les nœuds exploitant le réseau, y compris les nœuds de la chaîne Beacon, deviennent quatre fois plus rapides, alors chaque fragment sera en mesure de traiter quatre fois plus de transactions, et la chaîne Beacon pourra maintenir 4 fois plus de fragments. Le débit à travers le système augmentera du facteur 4 x 4 = 16 - d'où le nom de découpage quadratique .


Il est difficile de fournir une mesure précise du nombre de fragments viables aujourd'hui, mais il est peu probable que dans un avenir prévisible, les besoins de débit des utilisateurs de la blockchain dépassent les limites du sharding quadratique. Le nombre de nœuds nécessaires pour faire fonctionner un tel volume de fragments en toute sécurité est de plusieurs ordres de grandeur supérieur au nombre de nœuds exploitant toutes les chaînes de blocs combinées aujourd'hui.


Cependant, si nous voulons construire des protocoles à l'épreuve du temps, il pourrait être utile de commencer à rechercher des solutions à ce problème aujourd'hui. La proposition la plus développée à ce jour est le partage exponentiel, dans lequel les fragments eux-mêmes forment un arbre, et chaque fragment parent orchestre une série de fragments enfants, alors qu'il peut lui-même être un enfant d'un autre fragment.


Vlad Zamfir de Ethereum Foundation est connu pour travailler sur une conception de sharding qui n'implique pas une chaîne de balise; J'ai travaillé avec lui sur l'un des prototypes, dont l'aperçu détaillé est ici .


Partage d'état


Jusqu'à présent, nous n'avons pas très bien défini ce qui est exactement et n'est pas séparé lorsqu'un réseau est divisé en fragments. Plus précisément, les nœuds de la blockchain effectuent trois tâches importantes: non seulement ils 1) traitent les transactions, mais également 2) relaient les transactions validées et les blocs terminés à d'autres nœuds et 3) stockent l'état et l'historique de l'ensemble du grand livre du réseau. Chacune de ces trois tâches impose une exigence croissante aux nœuds exploitant le réseau:


  1. La nécessité de traiter les transactions nécessite plus de puissance de calcul avec le nombre accru de transactions en cours de traitement;
  2. La nécessité de relayer les transactions et les blocs nécessite plus de bande passante réseau avec l'augmentation du nombre de transactions relayées;
  3. La nécessité de stocker des données nécessite plus de stockage à mesure que l'état se développe. Surtout, contrairement à la puissance de traitement et au réseau, les besoins de stockage augmentent même si le taux de transaction (nombre de transactions traitées par seconde) reste constant.

De la liste ci-dessus, il peut sembler que l'exigence de stockage serait la plus urgente, car c'est la seule qui augmente au fil du temps même si le nombre de transactions par seconde ne change pas, mais en pratique, l'exigence la plus urgente aujourd'hui est la puissance de calcul. L'état d'Ethereum au moment de la rédaction de ce document est de 100 Go, facilement gérable par la plupart des nœuds. Mais le nombre de transactions qu'Ethereum peut traiter est d'environ 20, des ordres de grandeur inférieurs à ce qui est nécessaire pour de nombreux cas d'utilisation pratiques.


Zilliqa est le projet le plus connu pour le traitement des fragments mais pas pour le stockage. Le partage du traitement est un problème plus facile car chaque nœud a l'état entier, ce qui signifie que les contrats peuvent appeler librement d'autres contrats et lire toutes les données de la blockchain. Une ingénierie minutieuse est nécessaire pour s'assurer que les mises à jour de plusieurs fragments mettant à jour les mêmes parties de l'état n'entrent pas en conflit. À cet égard, Zilliqa adopte une approche très simpliste, dont les critiques peuvent être trouvées dans ce billet .


Bien que le partage du stockage sans partage du traitement ait été proposé, je ne suis au courant d'aucun projet y travaillant. Ainsi, dans la pratique, le partage du stockage, ou partage de l'état, implique presque toujours le partage du traitement et le partage du réseau.


En pratique, sous State Sharding, les nœuds de chaque fragment créent leur propre blockchain qui contient des transactions qui affectent uniquement la partie locale de l'état global qui est affectée à ce fragment. Par conséquent, les validateurs du fragment n'ont besoin que de stocker leur partie locale de l'état global et d'exécuter, et en tant que tels, de relayer uniquement, les transactions qui affectent leur partie de l'état. Cette partition réduit linéairement les exigences en matière de puissance de calcul, de stockage et de bande passante réseau, mais introduit de nouveaux problèmes, tels que la disponibilité des données et les transactions entre fragments, que nous aborderons ci-dessous.


Transactions entre fragments


Beanstalk en tant que modèle n'est pas une approche très utile du partage, car si des fragments individuels ne peuvent pas communiquer entre eux, ils ne valent pas mieux que plusieurs chaînes de blocs indépendantes. Même aujourd'hui, lorsque le partage n'est pas disponible, il existe une énorme demande d'interopérabilité entre les différentes chaînes de blocs.


Pour l'instant, considérons uniquement les transactions de paiement simples, où chaque participant a un compte sur un seul fragment. Si l'on souhaite transférer de l'argent d'un compte à un autre au sein du même fragment, la transaction peut être entièrement traitée par les validateurs de ce fragment. Si, cependant, Alice qui réside sur le fragment # 1 veut envoyer de l'argent à Bob qui réside sur le fragment # 2, ni les validateurs sur le fragment # 1 (ils ne pourront pas créditer le compte de Bob) ni les validateurs sur le fragment # 2 ( ils ne pourront pas débiter le compte d'Alice) peuvent traiter l'intégralité de la transaction.


Il existe deux familles d'approches pour les transactions entre fragments:


  1. Synchrone : chaque fois qu'une transaction entre fragments doit être exécutée, les blocs de plusieurs fragments qui contiennent une transition d'état liée à la transaction sont tous produits en même temps, et les validateurs de plusieurs fragments collaborent à l'exécution de ces transactions. La proposition la plus détaillée que je connaisse est Merge Blocks, décrite ici .
  2. Asynchrone : une transaction inter-fragments qui affecte plusieurs fragments est exécutée de manière asynchrone dans ces fragments, le fragment "Crédit" exécutant sa moitié une fois qu'il a suffisamment de preuves que le fragment "Débit" a exécuté sa portion. Cette approche a tendance à être plus répandue en raison de sa simplicité et de sa facilité de coordination. Ce système est aujourd'hui proposé dans Cosmos, Ethereum Serenity, Near, Kadena et autres. Un problème avec cette approche réside dans le fait que si des blocs sont produits indépendamment, il y a une chance non nulle qu'un des multiples blocs soit orphelin, rendant ainsi la transaction seulement partiellement appliquée. Considérez la figure ci-dessous qui représente deux fragments qui ont tous deux rencontré une fourchette, et une transaction inter-fragments qui a été enregistrée dans les blocs A et X 'en conséquence. Si les chaînes AB et V'-X'-Y'-Z 'finissent par être canoniques dans les fragments correspondants, la transaction est entièrement finalisée. Si A'-B'-C'-D 'et VX deviennent canoniques, alors la transaction est complètement abandonnée, ce qui est acceptable. Mais si, par exemple, AB et VX deviennent canoniques, alors une partie de la transaction est finalisée et l'autre est abandonnée, créant un échec d'atomicité. Nous verrons comment ce problème est traité dans les protocoles proposés dans la deuxième partie, lorsque nous aborderons les modifications apportées aux règles de choix de fourche et aux algorithmes de consensus proposés pour les protocoles fragmentés.

image


Notez que la communication entre les chaînes est également utile en dehors des chaînes de blocs fragmentées. L'interopérabilité entre les chaînes est un problème complexe que de nombreux projets tentent de résoudre. Dans les blockchains fragmentées, le problème est un peu plus facile car la structure des blocs et le consensus sont les mêmes entre les fragments, et il existe une chaîne de balises qui peut être utilisée pour la coordination. Dans une blockchain fragmentée, cependant, toutes les chaînes de fragments sont les mêmes, tandis que dans l'écosystème mondial des blockchains, il existe de nombreuses blockchains différentes, avec différents cas d'utilisation cibles, décentralisation et garanties de confidentialité.


Construire un système dans lequel un ensemble de chaînes a des propriétés différentes mais utilise un consensus et une structure de blocs suffisamment similaires et a une chaîne de balise commune pourrait permettre un écosystème de chaînes de blocs hétérogènes qui ont un sous-système d'interopérabilité fonctionnel. Il est peu probable qu'un tel système comporte une rotation du validateur, donc certaines mesures supplémentaires doivent être prises pour garantir la sécurité. Cosmos et PolkaDot sont tous deux de tels systèmes. Cet article écrit par Zaki Manian de Cosmos fournit un aperçu détaillé et une comparaison des aspects clés des deux projets.


Comportement malveillant


Vous avez maintenant une bonne compréhension de la façon dont le partage est implémenté, y compris les concepts de la chaîne de balises, les rotations de validateur et les transactions entre fragments.


Avec toutes ces informations, il y a une dernière chose importante à considérer. Plus précisément, quel comportement contradictoire les validateurs malveillants peuvent-ils exercer?


Fourches malveillantes


Un ensemble de validateurs malveillants peut tenter de créer une fourchette. Notez que peu importe si le consensus sous-jacent est BFT ou non, la corruption d'un nombre suffisant de validateurs permettra toujours de créer un fork.


Il est beaucoup plus probable que plus de 50% d'un seul fragment soient corrompus que plus de 50% de l'ensemble du réseau soient corrompus (nous approfondirons ces probabilités dans la deuxième partie). Comme indiqué ci-dessus, les transactions entre fragments impliquent certains changements d'état dans plusieurs fragments, et les blocs correspondants dans ces fragments qui appliquent ces changements d'état doivent être tous finalisés (c'est-à-dire apparaître dans les chaînes sélectionnées sur leurs fragments correspondants), ou tous être orphelins (c'est-à-dire ne pas apparaître dans les chaînes sélectionnées sur leurs fragments correspondants). Étant donné que la probabilité de corruption des fragments n'est généralement pas négligeable, nous ne pouvons pas supposer que les fourches ne se produiront pas même si un consensus byzantin a été atteint parmi les validateurs de fragments, ou si de nombreux blocs ont été produits au-dessus du bloc avec le changement d'état. .


Ce problème a plusieurs solutions, la plus courante étant la réticulation occasionnelle du dernier bloc de chaîne de fragments à la chaîne de balises. La règle de choix de fourche dans les chaînes de fragments est ensuite modifiée pour toujours préférer la chaîne qui est réticulée, et n'applique la règle de choix de fourche spécifique aux fragments qu'aux blocs qui ont été publiés depuis la dernière réticulation.


Approuver des blocs invalides


Un ensemble de validateurs peut tenter de créer un bloc qui applique incorrectement la fonction de transition d'état. Par exemple, en commençant par un état dans lequel Alice a 10 jetons et Bob a 0 jetons, le bloc peut contenir une transaction qui envoie 10 jetons d'Alice à Bob, mais se termine avec un état dans lequel Alice a 0 jetons et Bob a 1000 jetons.


image


Dans une blockchain classique non partagée, une telle attaque n'est pas possible, car tous les participants au réseau valident tous les blocs, et le bloc avec une transition d'état non valide sera rejeté par les autres producteurs de blocs et les participants du réseau qui ne créent pas de blocs. Même si les validateurs malveillants continuent de créer des blocs au-dessus d'un tel bloc invalide plus rapidement que les validateurs honnêtes construisent la chaîne correcte, ayant ainsi la chaîne avec le bloc invalide étant plus longue, cela n'a pas d'importance, car chaque participant qui utilise la blockchain pour n'importe quel but valide tous les blocs et rejette tous les blocs construits au-dessus du bloc invalide.


image


Sur la figure ci-dessus, il y a cinq validateurs, dont trois sont malveillants. Ils ont créé un bloc invalide A ', puis ont continué à construire de nouveaux blocs par-dessus. Deux validateurs honnêtes ont rejeté A 'comme invalide et construisaient au-dessus du dernier bloc valide qu'ils connaissaient, créant une fourchette. Comme il y a moins de valideurs dans la fourche honnête, leur chaîne est plus courte. Cependant, dans la blockchain classique non partagée, chaque participant qui utilise la blockchain à quelque fin que ce soit est responsable de valider tous les blocs qu'il reçoit et de recalculer l'état. Ainsi, toute personne qui a un intérêt dans la blockchain observerait que A 'n'est pas valide, et donc rejetterait immédiatement B', C 'et D', en prenant ainsi la chaîne AB comme la chaîne valide actuelle la plus longue.


Dans une blockchain fragmentée, cependant, aucun participant ne peut valider toutes les transactions sur tous les fragments, ils doivent donc avoir un moyen de confirmer qu'à aucun moment de l'historique d'un fragment de la blockchain aucun bloc non valide n'a été inclus.


Notez que contrairement aux fourches, la réticulation à la chaîne Beacon n'est pas une solution suffisante, car la chaîne Beacon n'a pas la capacité de valider les blocs. Il ne peut valider qu'un nombre suffisant de validateurs dans ce fragment ont signé le bloc (et en tant que tel, attesté de son exactitude).


Je ne connais que deux solutions à ce problème, dont aucune n'est vraiment satisfaisante aujourd'hui:


  1. Avoir un mécanisme raisonnable qui alertera le système si une tentative d'application incorrecte de la transition d'état est effectuée. En supposant que chaque fragment exécute une sorte de consensus BFT, tant que le nombre de validateurs malveillants dans un fragment particulier est inférieur à ⅔, au moins un validateur honnête devra attester d'un bloc et vérifier que la fonction de transition d'état est appliqué correctement. Si plus des ⅔ des nœuds sont malveillants, ils peuvent finaliser un bloc sans qu'un seul nœud honnête n'y participe. En supposant qu'au moins un nœud de la partition n'est pas malveillant, un mécanisme est nécessaire pour permettre à ces nœuds de surveiller les blocs en cours de production et disposer de suffisamment de temps pour défier les nœuds avec une transition d'état non valide.
  2. Avoir quelques informations dans les blocs qui sont suffisantes pour prouver que la transition d'état est appliquée correctement mais est beaucoup moins chère à valider que l'application réelle de la fonction de transition d'état. Le mécanisme le plus proche pour y parvenir est zk-SNARK (bien que nous n'ayons pas vraiment besoin de la partie «zk», ou connaissance zéro, un SNARK non-zk serait suffisant), mais les zk-SNARK sont notoirement lents à calculer à ce point.

De nombreux protocoles supposent aujourd'hui qu'avec une rotation correcte du validateur et un consensus byzantin tolérant aux pannes, ni fourches ni transitions d'état invalides ne sont possibles. La raison pour laquelle cette hypothèse est déraisonnable est un sujet pour un article séparé.


Outro


J'écris beaucoup sur les blockchains et le sharding, et nous avons également une série de vidéos où nous parlons aux fondateurs de protocoles évolutifs, tels que Cosmos et Solana, avec des plongées profondes technologiques. Vous pouvez me suivre sur twitter ici .

Source: https://habr.com/ru/post/fr437926/


All Articles