
Consensus sur Solana
Enseignements pratiques
- Le rôle de la preuve d’historique (PoH) dans la synchronisation : la PoH n’est pas un algorithme de consensus, mais un outil utilisé par le mécanisme de consensus de Solana pour la synchronisation. De même, la preuve d’enjeu (PoS) n’est pas un consensus, mais un mécanisme de résistance aux attaques Sybil.
- Les transactions de vote sont nécessaires au consensus : les votes inclus dans les blocs ne sont pas des transactions superflues destinées à gonfler artificiellement les métriques de TPS. Si les votes étaient simplement propagés par gossip (communication informelle de pair à pair), cela pourrait créer des divergences dans la perception qu’ont les validateurs de l’état de la Tower (des votes).
- Solana possède deux règles principales de confirmation : l’une pour la sélection des forks à court terme (confirmation optimiste) et l’autre pour le consensus PoS complet garantissant la finalité (finalisé/enraciné). Les clients et les utilisateurs peuvent suivre ces règles de confirmation afin d’obtenir les propriétés de sécurité souhaitées et de personnaliser leur UX. Cela se traduit par deux niveaux d’engagement : « confirmé » et « finalisé ».
- Comprendre le risque de censure : les validateurs et les développeurs doivent connaître le risque d’attaques par censure, lors desquelles un validateur tente de perturber la séquence de production des blocs. Ils doivent comprendre le fonctionnement de ces attaques ainsi que le rôle de la puissance de calcul et de l’enjeu dans leur exécution.
- De futures mises à niveau du protocole se profilent : les validateurs et les développeurs doivent se préparer activement aux prochaines évolutions du mécanisme de consensus de Solana, telles que l’exécution asynchrone et le slashing programmatique.
Introduction
Alors que l’activité s’intensifie sur Solana, les différentes couches de sa stack sont sollicitées à des niveaux sans précédent. Les sujets « tendance », comme les marchés de frais locaux, ont fait couler beaucoup d’encre, mais le consensus sur Solana a longtemps été négligé. Pourtant, l’augmentation de l’activité et de l’intérêt exige que la communauté comprenne précisément le consensus, car les incitations aux attaques malveillantes et les profits tirés d’éventuelles exploitations augmentent.
Le consensus est l’un des aspects les plus importants de Solana que l’ensemble de la communauté doit comprendre, car il détermine comment des milliers de validateurs s’accordent sur un ordre canonique des transactions.
Le consensus est étudié depuis de nombreuses années dans les systèmes distribués. Le problème des généraux byzantins, rédigé par Lamport, Shostak et Pease, a été publié au début des années 1980. Des algorithmes de consensus comme RAFT sont utilisés depuis longtemps dans le web2. Dans l’univers crypto, la plupart des algorithmes de consensus sont différentes implémentations du consensus BFT, notamment Gasper (Ethereum), Tendermint (Cosmos), MonadBFT (Monad), HotShot (Espresso) et Narwhal/Tusk (Sui).
Cet article ne cherche pas à démontrer formellement le mécanisme de consensus de Solana (TowerBFT). Il vise plutôt à expliquer aux développeurs et à l’ensemble de la communauté le fonctionnement du consensus sur Solana, un sujet qui, jusqu’à présent, réside surtout dans l’esprit des contributeurs de Solana Labs et Firedancer. Certains compromis et certaines limites sont également abordés.
Brève introduction au consensus
L’objectif d’un protocole de consensus est de parvenir à un accord sur les transactions et leur ordre relatif au sein d’un bloc. Il existe deux principaux types de protocoles permettant aux validateurs d’un réseau de s’accorder sur l’ordre canonique des transactions :
- Protocoles de la chaîne la plus longue : ces protocoles, comme le consensus Nakamoto de Bitcoin, rendent canonique la chaîne dont la construction a nécessité le plus d’effort de calcul. Bien que cela corresponde souvent à la chaîne comptant le plus grand nombre de blocs, il est plus exact de parler de la chaîne représentant la plus grande quantité cumulée de travail ou de puissance de calcul.
- Protocoles de type BFT : la plupart des protocoles PoS implémentent une version d’un algorithme de consensus BFT. Ces protocoles, comme pBFT, reposent sur des seuils de vivacité et de sécurité. La cohérence et la disponibilité sont deux garanties du théorème CAP, selon lequel tout système distribué de stockage de données ne peut offrir que deux des trois garanties suivantes : cohérence, disponibilité et tolérance au partitionnement.
Les protocoles de consensus reposant sur la chaîne la plus longue comme ceux de type BFT tirent leur sécurité de leurs règles de confirmation respectives. La sécurité, qui comprend à la fois la sûreté et la vivacité, découle d’une règle de confirmation donnée et n’est pas une propriété d’une chaîne. Selon la définition de l’Ethereum Foundation, une règle de confirmation est « un algorithme exécuté par les nœuds qui indique si un bloc donné est confirmé. Lorsque c’est le cas, le bloc est assuré de ne jamais subir de réorganisation, sous certaines hypothèses concernant principalement la synchronisation du réseau et le pourcentage d’enjeu honnête ».
En définitive, tout repose sur le consensus social, établi par les personnes qui écrivent le code des clients exprimant ce qui définit la sécurité au moyen de règles de confirmation données.
La preuve d’enjeu ajoute des couches au modèle BFT en obligeant les participants à engager leur propre enjeu. Ils sont récompensés lorsqu’ils respectent un ensemble de règles, mais peuvent subir un slashing en cas de faute avérée, par exemple une double signature. Ce principe est appelé « sécurité responsable » et permet au protocole d’identifier et de sanctionner les nœuds malveillants sans externalités pour les nœuds honnêtes. Il ne remplace pas le mécanisme de sécurité fondamental des protocoles de consensus BFT : le réseau doit toujours compter moins d’un tiers de nœuds malhonnêtes pour éviter un arrêt et moins de deux tiers pour empêcher la validation de transactions incorrectes. Le système fondé sur l’enjeu impose des conséquences aux actions susceptibles de perturber ou de dégrader l’efficacité du réseau.
Un tel réseau BFT comporte deux seuils critiques :
- 1/3 : si les nœuds malhonnêtes représentent au moins un tiers du total, le réseau peut « s’arrêter ». Dans ce scénario, ces nœuds peuvent simplement choisir de ne plus participer, empêchant les autres d’atteindre la supermajorité des deux tiers requise pour le consensus. Le réseau ne produit alors pas de transactions incorrectes : il cesse entièrement d’en produire. Une métrique courante, bien que rudimentaire, est le coefficient de Nakamoto, qui représente le nombre minimal de nœuds requis pour provoquer une défaillance de vivacité et arrêter la production de blocs.
- 2/3 : si les nœuds malhonnêtes représentent au moins deux tiers du total, ils peuvent s’entendre pour valider les transactions de leur choix. Il s’agit du pire scénario : le réseau cesse de fonctionner correctement et traite les transactions dictées par la supermajorité malhonnête. Si un adversaire contrôle plus de 67 % de l’enjeu, il peut potentiellement isoler un nœud honnête, comme celui d’une grande plateforme d’échange telle que Binance. Cette isolation peut être réalisée en s’entendant avec un centre de données afin de restreindre le trafic réseau du nœud. L’entité malveillante peut ensuite faire finaliser par ce nœud isolé un bloc qu’elle a créé, tout en diffusant simultanément un bloc contradictoire au reste du réseau. Ce type d’attaque exploite la vision limitée du nœud isolé et peut entraîner une double dépense, car le reste du réseau et le nœud isolé ont des vues différentes de l’état on-chain.
Une attaque similaire est possible avec un enjeu inférieur, mais supérieur à 33 %. Elle nécessiterait toutefois de créer une partition du réseau plutôt qu’une simple isolation. Dans cette situation, le détenteur d’enjeu byzantin peut exploiter la partition pour manipuler différents segments du réseau avec des informations contradictoires, créant à nouveau un risque de double dépense et d’autres défaillances de sécurité.
En règle générale, un nombre plus élevé de nœuds complique la tâche de toute partie cherchant à en corrompre une proportion suffisante pour atteindre ces seuils, à condition qu’ils soient géographiquement séparés. Toutefois, cette volonté d’agrandir le réseau entre souvent en conflit avec l’efficacité. Un plus grand nombre de nœuds peut ralentir le consensus en raison de l’augmentation des besoins de transmission des données, notamment du temps requis pour propager les votes. Certains protocoles imposent donc une limite stricte au nombre maximal de nœuds.
Preuve d’historique (PoH)
Alors que la preuve d’enjeu (PoS) assure le consensus dans un réseau, Solana intègre la preuve d’historique (PoH) à son mécanisme de consensus PoS afin de permettre la synchronisation nécessaire à la production continue de blocs. Solana y parvient en ignorant les slots dont les leaders sont lents ou ne répondent pas, sans attendre un tour de consensus synchronisé. La PoH ne cherche pas à prouver l’heure exacte à laquelle un événement s’est produit, mais plutôt la séquence et le temps écoulé entre les événements.
Contrairement à une idée répandue, la preuve d’historique (PoH) n’est pas en elle-même un mécanisme ni un algorithme de consensus. Bien que l’implémentation actuelle du consensus utilise certains aspects de la PoH, il serait théoriquement possible de supprimer la PoH et d’apporter quelques modifications mineures à l’implémentation tout en conservant un consensus fonctionnel sur Solana.
Au cœur de la PoH se trouve un simple algorithme de hachage semblable à une fonction de délai vérifiable (VDF), sans être techniquement une VDF. Solana utilise pour cela une fonction de hachage séquentielle résistante à la préimage (SHA-256), exécutée en continu et dont la sortie d’une itération devient l’entrée de la suivante. Ce calcul s’exécute sur un seul cœur de chaque validateur.
Bien que la génération de la séquence soit séquentielle et monothread, la sortie peut être vérifiée en parallèle, ce qui permet une vérification efficace sur les systèmes multicœurs. La vitesse de hachage possède une limite supérieure, mais les progrès matériels peuvent potentiellement apporter des gains de performances supplémentaires.
Prenons l’exemple de quatre validateurs du réseau Solana : les validateurs A, B, C et D. Dans cet exemple, le calendrier des leaders peut imposer la séquence de production A - B - C - D. Le validateur A commence par générer un bloc à son tour. Pour cela, il utilise le mécanisme PoH, qui exécute de manière itérative la fonction de hachage SHA-256 afin de former une échelle temporelle de « ticks ». Ce processus de hachage crée une trace unique et vérifiable du temps écoulé, garantissant que le bloc du validateur A reflète précisément ce temps. Une fois le bloc du validateur A terminé, le validateur B produit le bloc suivant, puis vient le tour du validateur C.
Supposons que le validateur C tente de perturber la séquence en émettant un bloc hors de son tour afin de succéder directement au validateur A et de contourner le validateur B. Pour prendre la place du validateur B de manière crédible, il devrait reproduire la séquence de hachage PoH qu’aurait générée le validateur B. Il lui faudrait donc produire une séquence de hachages représentant le temps qu’aurait mis le validateur B à produire un bloc. Les performances de hachage sur un seul cœur ont une limite physique. Nous savons donc qu’un certain temps s’est écoulé, puisqu’un ordinateur ne peut générer qu’un nombre maximal de hachages dans un intervalle donné.
Le validateur C peut tenter de censurer le validateur B dans le calendrier des leaders en générant une chaîne de blocs vides à partir de la fin d’un bloc légitime précédent, celui du validateur A, sans inclure aucune transaction. Pour censurer B, C doit remplir deux conditions. Premièrement, C doit disposer de la puissance de calcul nécessaire pour générer la chaîne PoH vide. Deuxièmement, C doit diffuser rapidement son bloc à un nombre suffisant de nœuds détenant de l’enjeu afin qu’il soit accepté pendant son propre slot, censurant ainsi B. Cette diffusion est plus rapide pour un validateur fortement pondéré par l’enjeu grâce à Turbine, qui priorise le flux d’informations selon le poids d’enjeu des validateurs.
Ce scénario d’attaque est possible, mais la fenêtre permettant une censure réussie est limitée. Le nœud attaquant doit disposer de ressources de calcul considérables pour le hachage SHA-256 et d’un enjeu important, car le nombre de blocs qu’il peut générer est proportionnel à son enjeu.
En plus de devoir atteindre le réseau plus rapidement que le nœud A, C doit également générer le hachage à grande vitesse. Cette attaque cible principalement le scénario dans lequel un validateur désigné comme leader au slot n cherche à censurer les validateurs associés aux slots de leaders précédents, antérieurs à n. L’ampleur de la censure que ce validateur peut exercer dépend de son enjeu, car sa capacité à obtenir des slots de leader est directement liée au montant de son enjeu.
Le mécanisme PoH garantit également que les blocs sont produits à un rythme constant. Comme chaque validateur peut vérifier indépendamment la séquence PoH, aucune synchronisation temporelle externe n’est nécessaire. Ethereum, par exemple, utilise le protocole NTP (Network Time Protocol) dans chaque bloc pour le consensus. Sur Solana, chaque validateur vérifie de façon autonome que chaque bloc a été produit dans le bon slot temporel, de manière endogène et sans protocole externe.
Tower BFT, le mécanisme de consensus de Solana
Tower BFT, le mécanisme de consensus de Solana, intervient après la propagation des shreds (blocs partiels) aux autres validateurs :
Comme indiqué précédemment, Solana exécute Tower BFT conjointement avec la preuve d’historique. Tower BFT est un algorithme de consensus semblable à pBFT, conçu pour tirer parti des calculs d’horloge synchronisés de la preuve d’historique. Cela établit une horloge universelle sur le réseau, qui peut ainsi ignorer efficacement les slots attribués à des leaders lents ou inactifs. Le réseau n’a donc pas besoin d’effectuer un tour de consensus synchrone pour chaque slot, ce qui permet une production continue des blocs : les validateurs n’ont pas à attendre l’arrivée des blocs précédents avant de construire le bloc suivant.
Une autre idée fausse consiste à croire que le mécanisme de consensus de Solana implémente actuellement le slashing programmatique. Bien que le slashing figure sur la feuille de route, le réseau s’arrête actuellement après une violation de sécurité et s’appuie sur le consensus social pour appliquer le slashing si nécessaire.
Le mécanisme de consensus de Solana accorde des degrés d’influence variables aux différents nœuds. Les votes du réseau ne sont pas égaux : ils sont pondérés selon l’enjeu de chaque nœud, suivant les mêmes principes que la QoS pondérée par l’enjeu et Turbine. Toutes choses égales par ailleurs, un nœud possédant un enjeu plus élevé exerce davantage d’influence sur la détermination du consensus canonique qu’un nœud dont l’enjeu est plus faible.
Par exemple, dans un réseau composé de quatre nœuds détenant au total 100 unités d’enjeu, la répartition et l’influence peuvent être les suivantes :
- Le nœud A détient 10 unités d’enjeu.
- Le nœud B détient 20 unités d’enjeu.
- Le nœud C détient 30 unités d’enjeu.
- Le nœud D détient 40 unités d’enjeu.
Dans cette configuration, les capacités de chaque groupe de nœuds malhonnêtes varient. Un seul nœud, comme le nœud D, pourrait arrêter le réseau bien qu’il ne représente que 25 % du nombre total de nœuds, en raison de son enjeu élevé. De même, une combinaison des nœuds C et D pourrait approuver des transactions incorrectes : ils ne représentent que 50 % des nœuds, mais détiennent un enjeu suffisant pour influencer le résultat.
Le seuil d’un tiers nécessaire pour arrêter le réseau peut être atteint au moyen de nœuds malhonnêtes, compromis ou bloqués. En revanche, le seuil des deux tiers nécessaire pour valider des transactions incorrectes exige une collusion active et ne peut pas reposer sur le simple blocage de nœuds honnêtes. Il est donc beaucoup plus difficile à atteindre. Il faut en effet corrompre ou compromettre des nœuds pour qu’ils participent activement au stratagème malhonnête, plutôt que de simplement bloquer les nœuds honnêtes.
Contexte au sein des slots
Sur Solana, les leaders de slots se voient attribuer quatre slots consécutifs d’une durée totale d’environ 1,6 seconde (4 blocs x 400 ms par bloc). Les leaders sont choisis au début de chaque époque (432 000 slots, soit environ 2 à 3 jours). Le calendrier des leaders est déterminé aléatoirement en fonction du poids d’enjeu de chaque validateur.
Le leader doit construire et proposer un nouveau bloc pour chacun des slots qui lui sont attribués. Il n’existe pas de séparation entre proposant et constructeur comme dans l’écosystème Ethereum. Les autres validateurs attestent la validité d’un bloc donné au moyen de transactions de vote, en appliquant la règle de choix du fork à leur propre vue locale de la tête du réseau Solana.
Les leaders doivent publier les blocs dans une plage donnée de ticks PoH pour que ces blocs soient valides. Un bloc non publié dans cette plage est considéré comme ignoré.
Prenons l’exemple suivant d’un calendrier de leaders comprenant quatre participants (A, B, C et D), dans lequel D tente de perturber la séquence. Si D essaie d’intervenir pendant le tour de C, il doit créer une séquence de ticks PoH qui ignore effectivement le bloc de C, produisant une chaîne de la forme suivante :
A - B - [C manquant] - D.
Si le bloc de C est manquant, un D honnête doit générer une séquence PoH couvrant toute la durée du slot de C avant de commencer le sien. Le bloc de D semble alors valide, car il succède au bloc de B une fois écoulé le temps attribué au slot de C.
Pendant que D produit la séquence PoH correspondant au slot de C, C diffuse normalement son bloc, relié à celui de B par une séquence PoH appropriée. Deux résultats sont alors possibles :
- Si le calcul PoH de D n’est pas plus rapide que celui de C : lorsque C termine son bloc à peu près au moment où D commence à diffuser le sien, le réseau, qui a déjà vu le bloc de C, rejette celui de D.
- Si D calcule la PoH plus rapidement que C : D commence à diffuser son bloc avant que C ne termine le sien. Malgré cela, D devrait être nettement plus rapide que C pour affecter sensiblement la séquence, ce qui est peu probable compte tenu de la vitesse élevée et de la limite supérieure relativement similaire des capacités des CPU utilisés par les validateurs pour le calcul SHA-256.
Dans les deux cas, les chances que D remplace C sont minimes. De plus, si la tentative de D échoue, il perd la possibilité d’émettre un bloc pendant son propre slot. Émettre un bloc juste après B, puis en tenter un autre après C, constitue une violation, car D crée deux blocs pour son slot, ce qui expose D au slashing. Chaque tentative échouée empêche D de produire son propre bloc. Il est donc peu probable que D adopte cette stratégie.
Du point de vue du réseau, les intentions de D sont indéterminables. Il est difficile, voire impossible, de distinguer le cas où D n’a simplement pas vu le bloc de C, sans intention de censurer C, du cas où D avait l’intention de censurer B. Ce comportement n’est donc ni facilement détectable ni sanctionnable par le réseau.
Transactions de vote
Le mécanisme de consensus de Solana s’appuie sur les transactions de vote pour parvenir au consensus. Ces transactions sont incluses dans un bloc, mais bénéficient d’une priorité afin de ne pas être noyées parmi les transactions ordinaires. Actuellement, la majorité des transactions d’un bloc donné sont des transactions de vote :
Toutefois, ce ne sera pas nécessairement toujours le cas, car le pourcentage de transactions de vote dans un bloc donné représente le rapport entre l’activité et le nombre de validateurs participant au consensus. À l’avenir, les transactions de vote pourraient être minoritaires dans un bloc donné.
Les transactions de vote sont indispensables au consensus : ce ne sont pas des transactions superflues destinées à gonfler artificiellement les métriques de TPS. Si les votes étaient simplement propagés par gossip (communication informelle de pair à pair), cela pourrait créer des divergences dans la perception qu’ont les validateurs de l’état de la Tower (des votes). Ces divergences pourraient amener les validateurs à avoir des points de vue différents sur le fork le plus susceptible d’être correct, entraînant une séparation potentielle lorsque les validateurs font des choix opportunistes à partir d’informations incomplètes ou incohérentes. La production continue de blocs exige un vote continu, en particulier lorsque les blocs précédents sont encore en cours de confirmation. Cela requiert une vue fiable et cohérente de l’état de la Tower.
Comme les transactions ordinaires initiées par les utilisateurs, les transactions de vote doivent également payer les frais de base (0,000005 SOL). Ils sont payés par l’identité du validateur, qui doit se trouver dans un portefeuille à chaud pour assurer une signature constante, tandis que le compte de vote sert à la recherche de compte et à la délégation.
Chaque vote, signé par le validateur, comprend la clé publique de celui-ci et le hachage du bloc en faveur duquel il vote.
Lorsqu’un validateur reçoit plusieurs blocs pour le même slot, il suit tous les forks possibles jusqu’à pouvoir déterminer le « meilleur ». Les validateurs exécutent localement la fonction de transition d’état correspondante, ce qui changera avec l’exécution asynchrone, puis votent sur les nouveaux blocs après leur relecture. Ils expriment leurs votes pour un fork donné au moyen de transactions de vote on-chain.
Dans chaque transaction de vote, un validateur publie des votes assortis d’une période de verrouillage. Ce verrouillage fait office de mécanisme d’engagement : il lie les validateurs au fork choisi et impose un coût d’opportunité à leurs décisions. Aujourd’hui, les verrouillages ne sont pas appliqués par le runtime, mais par le consensus social. Un validateur qui enfreint régulièrement les verrouillages de vote subira très probablement un slashing manuel. Le slashing programmatique des violations de périodes de verrouillage devrait être ajouté prochainement, car la perte des crédits de vote n’est pas suffisamment dissuasive.
Le validateur signe également un hachage du bloc pour chaque bloc ancêtre situé entre son vote précédent et les blocs enracinés ou finalisés. Cette opération est nécessaire pour détecter les blocs en double. Si un leader envoyait des blocs distincts à chaque nœud, chaque nœud finirait par voter pour un prédécesseur différent du même slot. Toutefois, dans une époque composée de 65 000 slots, la taille de chaque vote pourrait atteindre 2 Mo dans le scénario le plus extrême. En effet, il pourrait être nécessaire d’inclure un hachage de 32 octets pour chacun des 65 000 slots. Ce sujet sera approfondi dans un prochain article.
Les validateurs gèrent une « Vote Tower », une pile séquentielle de votes dans laquelle chaque vote renforce un fork et constitue un ancêtre du fork situé au-dessus de lui dans la tour. L’ajout d’un nouveau vote à cette tour double les verrouillages de tous les votes précédents de la pile, augmentant progressivement l’engagement et la période de verrouillage des décisions antérieures. Le processus de vote lui-même est régi par plusieurs contrôles : les validateurs doivent respecter les périodes de verrouillage des votes précédents, vérifier qu’une part significative du réseau, généralement deux tiers, s’est également engagée sur le même fork, et obtenir une majorité substantielle, supérieure à 38 %, de votes sur des forks alternatifs avant de pouvoir passer à un nouveau fork.
Pour un bloc au slot n, les votes autres que celui du leader commencent à apparaître on-chain dès n+1. Il n’existe pas de sous-comités de vote : tous les validateurs peuvent voter sur tous les blocs. Ces votes apparaissent d’abord dans les blocs d’autres validateurs proches, à un saut de distance, dans l’arbre Turbine. Les votes pour le slot n peuvent apparaître jusqu’au slot n+512, car un validateur est autorisé à voter pour tout slot dont le « hachage de slot » est encore connu, et ces hachages sont conservés pendant 512 slots (merci à Shinobi). Il n’existe pas de limite supérieure prédéterminée à un bloc donné pour le slot n. Toutefois, les slots enracinés sur lesquels au moins 32 blocs continus ont été construits n’acceptent plus de votes et deviennent finalisés.
Le système de vote comporte certaines particularités qui ne sont pas entièrement contrôlées par le runtime. Par exemple, les validateurs sont actuellement incités à ne voter que pour les slots « enracinés », en ignorant la tête de la chaîne, sans être sanctionnés par le consensus. Un validateur peut ainsi continuer à gagner des crédits de vote pour des forks ayant une probabilité extrêmement élevée de devenir canoniques, sans contribuer à la tête de la chaîne pour les opérations réelles de consensus. Cela se produit aujourd’hui, avec un validateur dont la « latence de vote » moyenne dépasse 68 slots. Une fonctionnalité proposée, appelée Timely Vote Credits, vise à corriger ce désalignement des incitations.
Règle de choix du fork de Solana
Comme Ethereum (LMD Ghost et Casper FFG), Solana possède deux règles de confirmation : l’une pour la sélection des forks à court terme et l’autre pour le consensus PoS complet assurant la finalité. Les utilisateurs et les clients peuvent ainsi personnaliser leur UX selon différentes règles de confirmation. Cela se traduit par deux niveaux d’engagement : « confirmé » et « finalisé ».
Les blocs « confirmés », également appelés confirmation optimiste, exigent qu’au moins 2/3 des validateurs aient voté pour un bloc donné au moyen de transactions de vote. Environ 4,6 % de l’enjeu actuel devrait subir un slashing pour rendre possibles des violations de finalité. Les blocs « finalisés » nécessitent des votes sur au moins 32 slots ultérieurs ou une supermajorité (>2/3) des votes. Une attaque malveillante nécessiterait le slashing de plus d’un tiers de l’enjeu. Ce processus prend beaucoup plus de temps que pour les blocs « confirmés », car il doit attendre que les blocs datant de 32 blocs soient enracinés pour obtenir une finalité complète.
Une règle de choix du fork permet au réseau de parvenir à un consensus sur la tête de la chaîne. L’implémentation de Solana Labs gère principalement le choix du fork au moyen d’un fichier Rust d’environ 4 600 lignes judicieusement nommé heaviest_subtree_fork_choice.rs. Ce fichier fournit la logique nécessaire aux validateurs pour déterminer quel fork est le plus susceptible de devenir canonique. Une analyse plus détaillée du code sera proposée dans un prochain article, mais voici le fonctionnement général du choix du fork :
- Les votes sont ajoutés avec
add_votes():
Cette opération parcourt les nouveaux votes, soustrait si nécessaire les enjeux des comptes de vote des anciens slots et ajoute l’enjeu aux nouveaux slots ayant reçu des votes.
generate_update_operations()est appelé pour créer un lot d’opérations de mise à jour des forks :
Cette opération :
- Soustrait l’enjeu de l’ancien fork
- Ajoute l’enjeu au nouveau fork
- Agrège l’enjeu de chaque fork jusqu’à la racine
process_update_operations():
- Appelle
mark_fork_valid()/invalid()si nécessaire - Appelle
aggregate_slot()en remontant chaque fork afin de mettre à jour son poids - Appelle
add_slot_stake()/subtract_slot_stake()pour mettre à jour les enjeux
aggregate_slot():
- Additionne l’enjeu de tous les slots enfants
- Identifie le fork enfant le plus lourd selon le poids d’enjeu
- Identifie le fork enfant le plus profond selon sa hauteur
- Propage ces valeurs vers le haut afin d’identifier le fork le plus lourd et le plus profond à partir de ce slot
select_forks():
- Renvoie le fork globalement le plus lourd pour la production de blocs
- Renvoie le fork le plus lourd descendant du dernier vote
L’enjeu est ajouté ou soustrait en fonction des votes, l’agrégation recalcule de bas en haut le poids de chaque fork, et la racine dont le sous-arbre pondéré est le plus lourd est choisie comme meilleur fork sur lequel construire et voter.
Probabilité d’inclusion
La probabilité d’inclusion d’une transaction évolue au cours de son cycle de vie après satisfaction des exigences associées aux règles de confirmation correspondantes.
Même si des slots peuvent être « ignorés », par exemple lorsque le leader est hors ligne, la transaction peut être incluse dans des blocs ultérieurs ou ne jamais être incluse.
Les slots présentés ici sont des approximations, mais ils donnent une idée du moment où les votes ont tendance à s’accumuler. De plus, ce processus est propre à chaque bloc : les blocs peuvent atteindre les niveaux de confirmation « confirmé » ou « finalisé » après des durées différentes. Le risque de réversion diminue de manière monotone tout au long du cycle de vie de la transaction. Même après la finalisation ou l’enracinement d’un bloc, il reste théoriquement possible de créer un fork par consensus social et de le retirer de la chaîne « canonique ».
Futurs axes de recherche et conclusion
Cet article a présenté le fonctionnement interne de Tower BFT, le mécanisme de consensus de Solana, ainsi que d’autres mécanismes pertinents. Nous avons étudié le rôle de la preuve d’historique, des transactions de vote et du choix du fork dans le contexte de Solana afin de créer un fork canonique pour l’ordonnancement des transactions.
Ces mécanismes ouvrent de nombreuses autres pistes de recherche et de formalisation, notamment :
- Des chercheurs d’Ethereum ont quantifié l’intérêt de participer à des Timing Games, dans lesquels les producteurs de blocs attendent la fin du slot pour soumettre leurs blocs. À quoi ressemblent quantitativement ces stratégies sur Solana et sont-elles déjà utilisées aujourd’hui ?
- L’exécution asynchrone doit devenir la principale évolution du protocole en 2024. Quels sont les vecteurs d’attaque potentiels et les considérations de sécurité pertinentes pour les nœuds qui se contentent de voter sur les forks existants au lieu de calculer localement les transitions d’état ?
- Aujourd’hui, une minorité significative de validateurs (<20 %) exécute des versions modifiées du client Solana Labs ou Jito-Solana. Quels seuils non régis par le runtime ou les règles de confirmation modifient-ils ?
- Implémenter le slashing programmatique. À l’heure actuelle, en dehors du consensus social, les incitations économiques à ne pas exécuter des stratégies de trading très rentables sans subir de slashing sont faibles.
- Quelles sont les performances du mécanisme de consensus de Solana lorsque deux clients entièrement différents sont exécutés, même s’ils tentent de suivre les mêmes règles de confirmation ?
- Quels gains attendus en matière de performances et de réduction de l’état les sous-comités de vote apporteraient-ils ?
- Quels sont les vecteurs d’attaque potentiels lors d’un redémarrage à partir d’un slot confirmé de manière optimiste plutôt que d’un slot finalisé ? Comment les solutions off-chain tierces, comme les plateformes d’échange, doivent-elles envisager l’utilisation de la confirmation optimiste ou de la finalité complète ?
- Les fonds soumis au slashing doivent-ils servir d’assurance pour les transactions incluses lors de violations de sécurité ? Quels seraient le fonctionnement et les incitations d’un fonds d’assurance libellé en SOL ?
Dans cet article, nous avons étudié certains mécanismes et seuils implémentés par Solana dans son mécanisme de consensus, ainsi que leur relation avec la production habituelle de blocs par les leaders au sein de slots donnés. L’augmentation récente de l’activité sur Solana soumet ces mécanismes à des tests réels de vivacité et de sécurité, tandis que les incitations aux attaques malveillantes se renforcent.
Merci à anoushk (Tinydancer), dubbel06 (Overclock), Prithvi (Helius), Mert (Helius) et Jarry (Ellipsis Labs) pour leurs discussions et leurs commentaires.
Articles associés
Abonnez-vous à Helius
Suivez les dernières actualités du développement sur Solana et recevez une notification à chaque publication


