NOUVEAU : Helius acquiert Light Protocol
Exécution asynchrone des programmes : l’aube d’une nouvelle APE-poque pour Solana
Blog/Recherche

Exécution asynchrone des programmes : l’aube d’une nouvelle APE-poque pour Solana

ChercheurLostin sur X
29 min de lecture

Introduction

Au milieu des débats animés et des conférences riches en annonces de l’effervescente édition de Breakpoint de cette année, Anatoly Yakovenko, cofondateur de Solana, a pris le temps d’organiser un unique atelier technique, improvisé et non enregistré. Armé d’un chevalet de conférence et de marqueurs, il a exploré les subtilités d’un sujet qu’il défend avec passion comme la prochaine évolution de Solana et qui constitue le thème central de cet article : l’exécution asynchrone.

Pour aborder la vision ambitieuse de l’exécution asynchrone (abrégée AE dans la suite de cet article), nous commencerons par présenter à un niveau général ses concepts fondamentaux et ses objectifs. Nous examinerons ensuite les mécanismes actuels d’exécution et de consensus de Solana afin d’établir une base pour l’analyse comparative des futures architectures proposées. Nous étudierons alors les différentes propositions relatives à l’AE, en commençant par les Bankless Leaders, qui constituent une étape indispensable à cette transition. Nous explorerons également les premières propositions de conception datant de 2022, puis progresserons chronologiquement jusqu’aux propositions plus récentes d’« architecture finale », qui vont au-delà de l’AE et prévoient plusieurs producteurs de blocs simultanés.

Vue d’ensemble de l’AE

C’est assez étrange quand on y pense. Tout ce qu’il [un validateur] fait, c’est produire des blocs et voter. Il n’a jamais besoin d’exécuter ces blocs. Lorsqu’il crée des blocs, il ne sait pas quel type de blocs il crée… La seule chose qui compte, c’est de s’accorder sur l’ordre. Les valeurs lui importent peu.

Anatoly Yakovenko
Anatoly Yakovenko
Cofondateur de Solana

Dans le contexte du protocole central de Solana, l’AE désigne une approche architecturale qui sépare l’exécution du consensus afin qu’ils puissent fonctionner indépendamment l’un de l’autre. Pour ce faire, le réseau parvient à un consensus sur l’ordre des transactions sans réellement les exécuter. Une fois cet ordre accepté, n’importe qui peut exécuter les transactions pour révéler la vérité.

Selon cette approche, les leaders construiraient les blocs sans exécuter les transactions autres que les votes et les propageraient sur le réseau via Turbine. Les validateurs seraient également libres de voter pour les blocs sans exécuter les transactions autres que les votes. Le consensus porterait uniquement sur l’ordre et la disponibilité des transactions, ce qui réduirait considérablement le temps et le nombre d’étapes nécessaires pour l’atteindre. Pour paraphraser un résumé de Jon Charbonneau de DBA : l’ordre détermine la vérité, et l’exécution la révèle.

Cette approche diffère fortement du fonctionnement actuel du consensus, dans lequel les leaders exécutent les transactions avant de les regrouper en blocs, tandis que tous les validateurs rejouent les transactions d’un bloc avant de voter pour celui-ci.

L’AE est possible pour les raisons suivantes :

  1. Le choix de la branche ne dépend pas de l’exécution des programmes
  2. Une seule version correcte de l’état peut être calculée à partir d’une fonction déterministe de transition d’état. À terme, tout le monde calculera le même état final
  3. Les transactions non valides peuvent être abandonnées. Le coût du spam de transactions échouées pour le réseau est relativement faible : il se limite à la bande passante Turbine nécessaire à leur propagation et à l’espace supplémentaire requis pour les stocker dans le registre
  4. Les machines nécessitant un calcul en temps réel et à faible latence de l’état complet, comme celles exploitées par des fournisseurs de services RPC dédiés, peuvent être spécialement dimensionnées à cette fin

L’AE présente de nombreux avantages potentiels.

Yakovenko va jusqu’à affirmer : « L’exécution asynchrone est l’un des rares cas où il n’existe pratiquement aucun compromis. »

  1. Des temps de bloc plus courts (200 millisecondes)
  2. Des temps de bloc plus fiables
  3. Des exigences réduites pour les validateurs
  4. Une meilleure expérience utilisateur (finalité plus rapide)
  5. Une meilleure résistance à la censure
  6. Une fenêtre réduite pour réordonner les transactions
  7. Le report de la capacité inutilisée d’un bloc à l’autre
  8. Une voie vers les producteurs de blocs multiples et simultanés (nous y reviendrons)

Tout au long de cet article, nous examinerons précisément comment l’AE offre ces avantages.

Une autre façon de comprendre l’AE consiste à considérer qu’elle permet au programme de vote de fonctionner indépendamment de tous les autres programmes. Le programme de vote et le programme système (qui est toujours requis) sont les seuls programmes nécessaires au consensus au sein d’une époque.

Les discussions autour de l’AE sur Solana se poursuivent depuis plusieurs années. La première proposition formelle d’Anatoly Yakovenko, initialement intitulée APEX (Asynchronous Program Execution), remonte à avril 2022. Les détails concrets de la mise en œuvre pratique de l’AE sur Solana sont répartis entre plusieurs SIMD et articles, que nous aborderons ici dans un ordre essentiellement chronologique. Yakovenko est sans conteste le principal partisan et défenseur public de l’AE au sein de la communauté Solana, et il manque rarement une occasion d’aborder ce sujet lors d’interviews et de podcasts.

Terminologie

Il est utile de définir brièvement deux termes clés qui occuperont une place importante dans notre analyse de l’AE : les Bankless Leaders et les Multiple Concurrent Block Producers (MCBP). En résumé :

  • Bankless Leader : leader capable de créer des blocs sans exécuter les transactions
  • Exécution asynchrone (AE) : séparation complète du consensus et de l’exécution
  • Multiple Concurrent Block Producers (MCBP) : comme leur nom l’indique, plusieurs blocs produits simultanément dans un même slot‍

Les Bankless Leaders constituent une étape indispensable pour permettre une AE complète. De même, la réussite de la mise en œuvre de l’AE est essentielle à l’introduction ultérieure des Multiple Concurrent Block Producers (MCBP), également appelés Multiple Concurrent Leaders (MCL). Les discussions sur l’AE s’accompagnent souvent de discussions sur les MCBP. Yakovenko défend les deux comme des éléments essentiels de l’« architecture finale » de Solana.

Solana n’est pas la seule blockchain à étudier ces améliorations architecturales. Monad prévoit de mettre en œuvre l’AE en dissociant le consensus et l’exécution dans des threads distincts. De même, la communauté de recherche d’Ethereum étudie depuis quelque temps la possibilité d’introduire plusieurs proposants simultanés.

Les propositions de Yakovenko font toujours l’objet de débats au sein de la communauté, car leur mise en œuvre nécessiterait d’importantes modifications du protocole central de Solana. Tout le monde ne considère pas l’AE comme la meilleure voie à suivre. Il n’est pas exagéré d’affirmer que la mise en œuvre complète de l’architecture finale proposée par Yakovenko transformerait radicalement le fonctionnement de Solana et augmenterait la complexité globale du protocole.

Avant d’examiner l’AE plus en détail, nous devons nous remémorer le fonctionnement actuel de l’exécution et du consensus sur Solana, en prêtant une attention particulière aux aspects qui seront évoqués plus loin dans cet article. Nous analyserons également les données relatives aux transactions de vote et autres afin de dégager des informations supplémentaires utiles à la suite de notre analyse. Les lecteurs qui connaissent déjà bien ces mécanismes peuvent passer la section suivante.

Exécution synchrone (Solana aujourd’hui)

Exécution

Solana utilise une construction continue des blocs, qui consiste à assembler et diffuser dynamiquement les blocs à mesure qu’ils sont créés pendant un slot alloué de 400 millisecondes. Les leaders se voient attribuer quatre slots consécutifs (1,6 seconde) avant la rotation. Pour qu’un bloc soit accepté par le réseau, le leader doit vérifier et exécuter chaque transaction du bloc. En outre, tous les autres validateurs actifs participant au consensus revérifient et réexécutent chaque transaction du bloc.

Un leader reçoit les paquets de transactions via Gulfstream et QUIC. Ceux-ci entrent dans la Transaction Processing Unit (TPU), la logique centrale du leader chargée de la production des blocs. La TPU reçoit les paquets sur trois ports ouverts :

  • tpu : traite les transactions ordinaires comme les transferts de tokens, la création de NFT et les instructions de programmes
  • tpu_vote : traite exclusivement les transactions de vote
  • tpu_forwards : si le leader actuel ne peut pas traiter toutes les transactions, il transmet les paquets non traités au leader suivant par ce port‍

Avant tout classement ou toute exécution, l’ensemble des paquets de transactions est soumis à des contrôles rigoureux de validité et de cohérence, notamment la vérification des signatures, le contrôle du nombre correct de signatures et l’élimination des transactions en double. Notez que les transactions de vote et les autres transactions font l’objet de processus distincts de vérification des signatures.

La construction des blocs se déroule lors de la Banking Stage. Une banque représente l’état à un bloc donné. Les transactions sont traitées en parallèle et regroupées en entrées du registre, c’est-à-dire des lots de 64 transactions sans conflit. Toutes les transactions comprennent une liste exhaustive des comptes qu’elles liront et modifieront. Cette conception permet aux validateurs de sélectionner facilement, pour chaque entrée, uniquement des transactions sans conflit à exécuter. Des transactions sont en conflit si elles écrivent dans le même compte (deux écritures), ou si elles lisent et écrivent dans le même compte (lecture + écriture). Les transactions en conflit sont placées dans des entrées différentes et exécutées séquentiellement, tandis que les transactions sans conflit sont exécutées en parallèle.

Six threads traitent les transactions en parallèle : quatre sont consacrés aux transactions autres que les votes, tandis que deux traitent exclusivement les transactions de vote. Lors de la Banking Stage, les votes de consensus sont considérés comme des transactions privilégiées : leur prix est fixé uniformément à 0,000005 SOL, ils consomment 2 100 unités de calcul (CU) et sont exécutés par le Vote Program. 

Une fois les transactions regroupées en entrées, elles sont exécutées par la Solana Virtual Machine (SVM). Les comptes nécessaires à la transaction sont verrouillés. Des contrôles confirment que la transaction est récente, mais qu’elle n’a pas déjà été traitée. Les comptes sont chargés et la logique de la transaction est exécutée, ce qui met à jour leur état. Un hash de l’entrée est envoyé au service Proof of History (PoH) pour être enregistré. En cas de réussite, toutes les modifications sont validées dans la banque et les verrous de chaque compte sont levés.

Le protocole n’impose pas l’ordre des transactions valides au sein d’un bloc. L’état final de la chaîne résulte de toutes les transactions confirmées. Cet état peut toujours être recréé de manière déterministe à partir de l’historique de la blockchain, par exemple en rejouant le registre depuis le bloc Genesis ou un snapshot.

Chaque banque possède un BankHash correspondant, un hash SHA256 des éléments suivants :

  • BankHash parent : le BankHash du bloc parent direct
  • DeltaHash des comptes : une racine d’arbre de Merkle à 16 branches de tous les comptes dont l’état a changé dans le bloc actuel
  • Nombre de signatures : le nombre total de signatures de transactions dans le bloc actuel
  • Dernier hash de bloc
Code
hashv(&[
	parent_bankhash,
	accounts_delta_hash,
	num_sigs,
	blockhash,
])

Le BankHash est l’engagement cryptographique sur lequel les validateurs votent pour chaque slot.

Consensus

Les validateurs ont besoin de trois comptes pour permettre le processus de vote :

Compte d’identité

Ce compte système est le signataire et le payeur des frais pour toutes les transactions de vote. Il s’agit d’une paire de clés active stockée directement sur le matériel du serveur. Comme son nom l’indique, la clé publique de ce compte sert d’identité réseau au validateur. Le compte d’identité est nécessaire pour créer un compte de vote.

Compte de vote

Il s’agit du compte auquel les délégateurs délèguent leurs SOL. Son adresse sert à rechercher le compte, et non à signer des transactions.

Compte de retrait

Ce compte permet de retirer des fonds du compte de vote. Il peut modifier le compte d’identité. La clé privée de ce compte est généralement conservée dans un portefeuille multisignature sécurisé ou hors ligne, et doit être distincte des paires de clés de l’identité du validateur et de l’autorité de vote.

Chaque vote (exemple) signé par le validateur comprend sa clé publique ainsi qu’un hash identifiant le bloc pour lequel il vote. Lorsque les validateurs soumettent des votes corrects et valides, ils gagnent des crédits.

Le réseau n’attend pas que tous les validateurs s’accordent sur un bloc nouvellement produit avant de produire le suivant. Par conséquent, il n’est pas rare que deux blocs différents soient liés au même bloc parent, ce qui crée des branches. Les validateurs doivent voter sur ces branches et utiliser Tower BFT, une variante du mécanisme original Practical Byzantine Fault Tolerance (pBFT), pour déterminer laquelle adopter. 

Lorsque plusieurs branches sont en concurrence, le réseau en finalise une seule et les validateurs abandonnent les blocs des branches écartées. Chaque slot possède un leader prédéterminé, et seul le bloc de ce leader peut être accepté. Deux blocs ne peuvent donc pas être proposés pour un même slot. Le nombre de branches potentielles se limite ainsi à une liste de slots « présent/absent » pouvant apparaître aux limites des slots de rotation des leaders. 

Lorsqu’un validateur choisit une branche, il s’engage à la suivre jusqu’à l’expiration d’un délai de verrouillage. Il doit donc maintenir son choix pendant une période minimale. Ce mécanisme incite les validateurs à choisir avec soin la branche qui, selon eux, a le plus de chances d’être retenue, c’est-à-dire la branche la plus « lourde ».

Un bloc est considéré comme confirmé de manière optimiste dès qu’une supermajorité des deux tiers vote pour lui. Il est considéré comme finalisé une fois que 31 blocs ont été construits par-dessus. Dans toute l’histoire de Solana, aucun bloc confirmé de manière optimiste n’a jamais manqué d’être finalisé.

Lorsqu’une branche est finalisée, le bloc devient enraciné avec les mises à jour des comptes de la banque, et ses ancêtres sont écrits sur disque. En outre, toutes les mises à jour de comptes provenant de banques antérieures qui ne sont pas des ancêtres de la banque finalisée sont élaguées.

Transactions de vote et autres

Comme nous l’avons vu sur Solana, les processus d’exécution des transactions et d’obtention du consensus via Tower BFT sont étroitement liés. Les transactions de vote et les autres transactions suivent le même parcours : elles sont regroupées en entrées, exécutées par la SVM, horodatées dans le flux Proof of History (PoH), puis diffusées sur le réseau via Turbine. Ce processus unifié garantit que les validateurs perçoivent l’état du consensus de manière cohérente, car une propagation des votes uniquement par le service de gossip pourrait entraîner des divergences entre les validateurs. Ceux-ci pourraient alors avoir des avis différents sur la branche la plus susceptible d’être correcte. La construction continue des blocs exige un vote continu, particulièrement pendant la confirmation des blocs précédents.

Ce regroupement alimente la controverse autour des mesures de transactions par seconde (TPS) de Solana. Dans leur forme brute, celles-ci comprennent à la fois les transactions de vote et les autres transactions, contrairement à la plupart des réseaux comparables du secteur. Cela a conduit à l’adoption d’une mesure des « TPS réelles », qui exclut les transactions de vote et mesure plus précisément la capacité transactionnelle.

En examinant l’activité récente de Solana, nous constatons que les transactions de vote sont plus nombreuses que les autres, avec une moyenne légèrement inférieure à 1 000 par bloc.

Les transactions de vote ne représentent qu’une faible part du total des unités de calcul par bloc. Elles consomment en moyenne un peu plus de 2 millions de CU par bloc, dans une plage stable comprise entre 2,1 et 2,3 millions de CU. Cela ne représente que 4,5 % de la limite de calcul de 48 millions de CU des blocs Solana.

Les transactions de vote sont très prévisibles en termes de temps et de calcul par rapport aux autres transactions. Il s’agit d’un point essentiel sur lequel nous reviendrons plus loin. La consommation en CU des transactions autres que les votes est irrégulière, ce qui entraîne une utilisation inefficace du matériel. ‍

Il est difficile de garantir une durée d’exécution précise dans l’environnement d’exécution, car il s’agit plutôt d’une mesure approximative. En moyenne, les blocs visent à rester sous les 400 millisecondes, mais des pics se produisent parfois. Ces pics peuvent être considérés comme des bugs. Des efforts continus sont déployés pour les identifier et les corriger, ce qui permet une amélioration constante.

Une époque comprend 432 000 slots. Si chacun durait exactement 400 millisecondes, une époque durerait précisément 48 heures. Pourtant, comme le montrent les données historiques, les époques atteignent rarement, voire jamais, cet objectif. Au cours de l’année écoulée, elles ont généralement duré entre 2,1 et 2,3 jours.

L’exécution synchrone impose à tous les validateurs stakés participant au consensus d’être surdimensionnés pour faire face au pire temps d’exécution possible dans n’importe quel bloc. Par conséquent, les exigences matérielles de Solana pour les validateurs sont relativement élevées.

Ainsi s’achève notre présentation du fonctionnement actuel du consensus et de l’exécution sur Solana, principalement axée sur les éléments utiles aux analyses suivantes. Pour des présentations plus complètes, nous vous recommandons de lire nos précédents articles du blog Helius sur le consensus, la PoH, Turbine et le fonctionnement de Solana. Dans les sections suivantes, nous examinerons les futures modifications de la conception du protocole Solana.

APEX, 2022

La première proposition formelle de Yakovenko concernant l’AE remonte à avril 2022 et s’intitule APEX (Asynchronous Program EXecution). Cette proposition relativement courte présente les modalités pratiques d’une séparation entre consensus et exécution. Elle introduit l’idée de diviser l’état en deux domaines isolés : le « Domain 0 » par défaut et le « Domain 1 » du Vote Program. Cette configuration sépare le Vote Program du reste de la banque.‍

Tous les comptes appartiennent à un seul domaine. Les transactions ne peuvent ni lire ni modifier des comptes appartenant à plusieurs domaines. Toute transaction qui tente de le faire échoue immédiatement et est ignorée. Le System Program existe dans les deux domaines, tandis que le Vote Program est le seul autre programme du Domain 1.

Une instruction système spéciale (SystemInstruction::MoveDomains) fournit un mécanisme permettant aux comptes de changer de domaine une fois par époque afin de faciliter le transfert de SOL vers et depuis les comptes de vote.

La proposition introduit également le concept de ForkHash, pendant du BankHash. Le calcul du ForkHash évalue uniquement les instructions du Vote Program provenant du Domain 1, tandis que le BankHash évalue toutes les instructions qui ne relèvent pas du Vote Program et proviennent du Domain 0. Les instructions de vote font référence au ForkHash. Le calcul du BankHash s’effectue en dehors de la racine sur laquelle votent les validateurs du consensus. Auparavant, la sélection d’une branche et le vote correspondant exigeaient l’évaluation et l’exécution complètes de toutes les transactions de la banque. Désormais, seules les transactions impliquant le Vote Program sont évaluées lors de la sélection d’une branche.

Cette première conception laisse de nombreuses questions sans réponse, mais établit le concept fondamental des domaines isolés, sur lequel nous reviendrons.

Bankless Leaders

Un Bankless Leader est un leader libre de produire des blocs sans exécuter les transactions autres que les votes, une condition préalable essentielle à la mise en œuvre de l’AE. Dans un article intitulé The Road to Bankless, Andrew Fitzgerald, ingénieur chez Anza, développe une proposition antérieure de Bankless Leader (SIMD-005, décembre 2022, clôturée) rédigée par Tao Zhu, également chez Anza. Fitzgerald décrit plusieurs changements nécessaires pour introduire les Bankless Leaders sur Solana. Il distingue notamment trois grandes catégories de contraintes imposées par le protocole qui limitent la mise en œuvre de l’AE : les contraintes de bloc, d’entrée et de transaction.

À l’heure actuelle, toute violation de l’une de ces contraintes invalide l’intégralité du bloc. En éliminant ces restrictions, le protocole Solana ouvrirait la voie à l’AE et gagnerait en flexibilité dans la production et la validation des blocs. Voici un résumé des différentes formes de contraintes :‍

Contraintes de bloc

Ces contraintes s’appliquent à l’ensemble du bloc et comprennent les règles suivantes : 

  • Les blocs doivent inclure 64 ticks
  • La dernière entrée du bloc doit être un tick
  • Les transactions de toutes les entrées du bloc doivent respecter les limites du bloc

Contraintes d’entrée

La principale contrainte de cette catégorie interdit aux entrées de contenir des transactions en conflit. En novembre dernier, Fitzgerald a soumis la proposition SIMD 0083: Relax Entry Constraints, qui traite spécifiquement ce problème. La SIMD a été acceptée.

Contraintes au niveau des transactions

Il s’agit de la catégorie la plus importante, qui peut être divisée en trois sous-catégories :

Contraintes statiques

Ces contraintes peuvent être vérifiées sans connaître d’état supplémentaire. Elles comprennent la vérification des signatures, la taille de la transaction, le nombre de comptes répertoriés dans la liste des adresses en lecture/écriture et la conformité du format des données de la transaction (une transaction doit notamment pouvoir être désérialisée)‍

Cette sous-catégorie de contraintes au niveau des transactions n’a pas besoin d’être modifiée.

Contraintes liées à l’état de la banque

Celles-ci comprennent la vérification de l’unicité de la signature de la transaction afin de s’assurer qu’elle n’a pas déjà été incluse dans un bloc récent, ainsi que la vérification de son ancienneté (les transactions doivent notamment inclure un hash de bloc récent)

Cette sous-catégorie nécessite de connaître l’état récent de la banque.

Contraintes des transactions liées à l’état des comptes

Il s’agit de la sous-catégorie de contraintes la plus restrictive. Elle comprend la résolution des tables de recherche d’adresses (ALT), les contrôles des nonces, du payeur des frais et du caractère exécutable

Cette sous-catégorie nécessite de connaître les transactions précédentes.

Fitzgerald a officiellement proposé de modifier cette catégorie de contraintes dans la proposition SIMD 0082: Relax Transaction Constraints, qui est actuellement ouverte.

Comme le souligne Fitzgerald, la principale exigence de l’AE est que la vérification des blocs ne puisse pas dépendre de l’état des comptes. Si la vérification d’un bloc nécessite le résultat de transactions précédentes, celui-ci ne peut pas être exécuté de manière asynchrone. Il est donc nécessaire d’éliminer les dépendances à l’état des comptes lors de la vérification des blocs. En outre, bon nombre de ces contraintes sont inutilement restrictives.

Par exemple, une transaction dont le signataire ne dispose pas d’un nombre suffisant de lamports pour payer les frais ne doit être exécutée ni dans le protocole actuel ni avec les modifications proposées. Avec ces modifications, toutefois, l’inclusion d’une telle transaction n’invalidera pas le reste du bloc.

Dans l’ensemble, les travaux de Fitzgerald fournissent un cadre pratique pour modifier la Banking Stage afin d’ouvrir la voie à l’AE. Ils décrivent de nombreuses étapes nécessaires, qui modifieraient le consensus, pour faire de l’AE une réalité.

APExB 2023 : AE rencontre MCBP

L’exécution asynchrone des programmes va transformer tout l’état de Solana en rollup.

Anatoly Yakovenko
Anatoly Yakovenko
Cofondateur de Solana

En mars 2023, près d’un an après la conception initiale d’APEX, Yakovenko a présenté une proposition plus complète et détaillée intitulée Exécution et diffusion asynchrones des programmes (APExB) SIMD 0023. Cette proposition va au-delà de la mise en œuvre d’AE et expose une vision plus large qui inclut l’intégration de plusieurs producteurs de blocs simultanés (MCBP).

La proposition introduit le concept de « builders », des entités distinctes des leaders. Les builders sont des nœuds stakés qui créent des UserBlocks composés exclusivement de transactions hors vote. Ces UserBlocks sont propagés dans l’arbre Turbine et possèdent leurs propres « UserBlockSlots ». Par défaut, chaque slot standard comprend deux UserBlockSlots.

Les builders disposent de leur propre calendrier, indépendant de celui du leader. Plusieurs builders peuvent être programmés pour construire simultanément des UserBlocks. Les unités de calcul sont réparties équitablement entre les builders et les slots UserBlock. Par exemple, un bloc comprenant deux builders, deux slots UserBlock et une limite de 48 millions de CU aura une limite de 12 millions de CU par slot UserBlock (48/4).

Comme d’habitude, les leaders créent des blocs de votes de consensus en suivant le calendrier des leaders, tandis que les builders produisent et transmettent simultanément des UserBlocks de transactions utilisateur. Les UserBlocks indiquent leur numéro de slot et sont signés par le builder afin d’empêcher le leader de manipuler ou d’exclure une partie du bloc. Lorsque le leader reçoit un UserBlock via Turbine, il génère un UserBlockEntry à partir d’un hash du UserBlock, puis ajoute ce UserBlockEntry à la preuve d’historique (PoH).

Les validateurs ne peuvent pas voter pour des blocs dont ils n’ont pas encore reçu les UserBlocks associés ; autrement, rien ne garantit que tous puissent exécuter les données, car celles-ci pourraient être retenues. Ils peuvent toutefois voter pour les blocs du leader en exécutant uniquement les votes avant les transactions UserBlock. Les validateurs n’exécutent les UserBlocks que sur le fork le plus lourd et doivent uniquement soumettre leur BankHash le plus récent lors du vote, lequel peut concerner un ancien slot parent. Les validateurs votent sur des VoteHashes, qui remplissent la même fonction que les ForkHashes dans la proposition APEX 2022, c’est-à-dire essentiellement un BankHash limité aux transactions de vote.

Calendrier des builders

S’il existe dix builders UserBlock par bloc du réseau, chacun se verra attribuer 10 % des shreds Turbine et 10 % de la capacité de calcul disponible. Les builders sont programmés selon deux processus : aléatoire et persistant.

À la limite de chaque époque, les builders aléatoires sont attribués selon un processus de sélection pondéré par le stake. Les slots UserBlock persistants sont alloués au moyen d’un système d’enchères hollandaises et accordés aux plus offrants prêts à brûler le plus de SOL.

Ordre de priorité des transactions 

Chaque UserBlock est considéré comme ayant été créé simultanément pendant le UserBlockSlot dans lequel le leader l’a encodé. Pour chaque UserBlock du UserBlockSlot, les transactions sont classées selon leurs frais de priorité avant leur exécution. Si les transactions de deux blocs différents ont la même priorité, leur ordre dépend du UserBlock qui apparaît en premier dans la PoH du leader. Cela signifie que les frais de priorité déterminent la priorité d’exécution. Les transactions UserBlocks dupliquées ou non valides sont ignorées sans modification de l’état. Si plusieurs UserBlockEntries contiennent la même transaction, la seconde est ignorée.

Ci-dessus : dans le scénario 1, la transaction B sera prioritaire bien qu’elle arrive plus tard dans le flux PoH. Dans le scénario 2, la transaction C sera prioritaire, car elle présente les mêmes frais de priorité que la transaction D, mais son bloc apparaît plus tôt dans le flux PoH.

Dans cette conception, les builders capteront l’intégralité de la MEV. La proposition laisse ouverte la question de la répartition des frais de transaction utilisateur entre builders et leaders.

Les builders peuvent également créer des BundleTransactions, qui sont des groupes de transactions au sein du UserBlock conçus pour être exécutés en un seul lot ordonné. Ces transactions peuvent aussi ajouter des frais de priorité afin que l’ensemble du bundle soit prioritaire et exécuté comme un lot, à l’image de l’implémentation actuelle des bundles Jito.

Limites d’époque

Les pondérations par stake influencent le choix du fork et sont actualisées à chaque limite d’époque. Cela a d’importantes conséquences sur la conception. Les validateurs doivent avoir rattrapé l’exécution des transactions hors vote avant de pouvoir continuer à voter au-delà de cette limite d’époque.

Cependant, Yakovenko remarque : « Les nœuds ne peuvent pas prendre autant de retard, car les limites globales de CU sont définies pour une exécution synchrone. Mais l’option d’exécution asynchrone facilite considérablement le rattrapage. Le traitement brut du registre sans gestion du réseau est 20 à 30 fois plus rapide. »

Considérations

La présence de plusieurs builders complexifie la gestion des ressources. Les clients peuvent choisir le builder le plus proche, mais les frais de priorité peuvent varier pour chaque UserBlock, et les utilisateurs ne sauront probablement pas quel bloc risque d’être saturé lorsqu’ils envoient leurs transactions.

Parmi les avantages figure la prévisibilité de la planification. Les applications peuvent enchérir pour obtenir le pourcentage de bande passante de bloc nécessaire à leur fonctionnement et créer des séquenceurs dédiés garantissant un règlement ultérieur sur la chaîne. L’inclusion de builders UserBlock aléatoires est essentielle, car elle empêche les builders de blocs persistants de censurer des transactions et d’empêcher leur inclusion définitive.

APE dans Solana en 2024

Dans un article publié sur X en juin de cette année et intitulé Exécution asynchrone des programmes (APE), Yakovenko développe davantage le concept de domaines d’exécution initialement décrit dans la proposition APEX de 2022.

Les domaines d’exécution, auparavant appelés Domaine 0 et Domaine 1, sont désormais renommés domaine d’exécution des votes (VED) et domaine d’exécution utilisateur (UED). Leur objectif reste identique : isoler complètement le vote de consensus de l’exécution des transactions.

Les domaines d’exécution sont définis comme des ensembles distincts de programmes, ainsi que les clés et valeurs avec lesquelles ils interagissent, exécutés indépendamment des autres ensembles :

  • Les domaines d’exécution peuvent fonctionner sur différents threads et cœurs et se terminer à des moments différents sur des machines physiquement séparées 
  • Le domaine d’exécution A ne peut lire ni écrire aucune valeur du domaine d’exécution B 
  • Les domaines peuvent partager un état qui reste cohérent pendant l’exécution de l’un ou l’autre domaine
  • Le payeur des frais détermine le domaine dans lequel une transaction est exécutée
  • Un protocole est nécessaire pour synchroniser l’état entre les domaines et faciliter le déplacement des clés et des valeurs

Composants du domaine d’exécution des votes (VED)

  • SystemProgram : utilisé pour les transferts
  • VoteProgram : programme central du vote. Ce programme est statique et doit être présent à la fois dans l’UED et le VED
  • Sysvars du VoteProgram : variables utilisées pour le vote
  • Autorité de vote : comptes autorisés à voter
  • Payeur des frais de vote : comptes qui paient les frais liés au vote
  • Compte de financement du payeur des frais : compte actualisable pouvant servir à transférer des SOL dans le VED

Les comptes qui ne figurent pas dans le VED sont considérés comme faisant partie de l’UED.

Les comptes de vote doivent être activés. Ils sont inclus dans le VED à l’époque suivant leur activation. Une fois désactivés, ils sont retirés du VED à l’époque suivante. Des processus formels définissent les mouvements de fonds entrant et sortant du VED.

Les comptes suivent le domaine d’exécution auquel ils sont associés selon une convention similaire aux permissions de fichiers Linux (R pour lecture, W pour écriture et X pour exécution). Il existe quatre associations valides :

Seuls les comptes du Vote Program et du System Program peuvent passer du VED à l’UED et inversement. Le System Program fournit une interface permettant de déplacer les comptes System et les comptes Vote Program vers ou depuis le VED. Cette approche élimine le besoin d’un compte FeePayerFunding explicite. Tout compte System peut être réassocié entre le VED et l’UED afin de transférer des fonds entre les domaines.

Les leaders exécutent uniquement le domaine VED pour les blocs qu’ils créent, ce qui signifie qu’ils peuvent disposer d’informations partielles ou incomplètes sur l’état des payeurs de frais de l’UED. Après réception d’un bloc, les validateurs exécutent d’abord les transactions VED. L’état VED obtenu sert à calculer le hash VED, que les validateurs utilisent ensuite pour voter. 

Le rejeu de l’UED ignore les transactions dont les payeurs de frais ne sont pas valides. Les mises à jour de l’état UED calculent le Bankhash, appelé hash UED. Si au moins un tiers des validateurs soumettent des hash UED différents, tous les nœuds doivent s’arrêter et alerter les opérateurs.

Activation de nouvelles fonctionnalités

Le consensus étant désormais découplé de l’exécution, le VoteProgram doit être conçu pour gérer les situations dans lesquelles les votes VED franchissent les limites d’époque, ce qui entraîne l’activation de nouvelles fonctionnalités à des moments différents de ceux des transactions qui interagissent avec le VoteProgram dans l’UED.

Architecture finale 2024

Compte tenu de la diversité des applications et des développeurs du cœur du protocole, il est judicieux de planifier une seule modification majeure du protocole par an. Si nous devons en choisir une, je voterais pour l’exécution asynchrone.

Anatoly Yakovenko
Anatoly Yakovenko
Cofondateur de Solana

Début 2024, Yakovenko a publié Architecture finale, un document présentant une vision ambitieuse de l’avenir de Solana : un réseau de 10 000 nœuds avec des temps de bloc de 120 millisecondes. Le document réaffirme et approfondit les propositions de conception précédentes, tout en mettant l’accent sur l’adoption d’AE pour concrétiser cette vision ambitieuse.

Leaders sans Bank

En résumé :

● Les leaders maintiennent un cache des soldes des comptes payeurs de frais

● Si un payeur de frais est utilisé comme compte accessible en écriture en tant que source d’un transfert système, ou transmis comme compte accessible en écriture avec le programme système à un autre programme, le solde servant au paiement des frais est fixé à 0

● Les blocs sont remplis selon les CU déclarées jusqu’à atteindre leur capacité maximale, en fonction de l’ordre de priorité local des frais et en soustrayant les frais de transaction du cache de solde du payeur de frais 

● Le cache des soldes des comptes payeurs de frais est réapprovisionné par le calcul du BankHash 

Les leaders peuvent initialement obtenir les soldes des comptes payeurs de frais en interrogeant plusieurs nœuds complets ou RPC. Dans les rares cas où des nœuds fournissent des données incorrectes, cela entraîne l’échec de transactions plutôt qu’une défaillance du consensus. Si les soldes des payeurs de frais sont obsolètes, cela peut générer du spam dans les blocs sans affecter le consensus. Le coût du spam issu des transactions échouées est relativement faible et provient principalement de la bande passante Turbine nécessaire à la propagation des transactions et de l’espace de stockage supplémentaire qu’elles occupent dans le registre. De plus, les équipes de Temporal et de Firedancer travaillent activement sur des outils qui limitent le spam avant qu’il n’atteigne les blocs. Elles mettent en œuvre des mécanismes comme le filtrage des transactions non valides, la déduplication et le blocage des transactions vouées à échouer en raison de conflits de verrous de lecture/écriture.

Ce problème est facile à détecter et à surveiller. Les opérateurs peuvent suivre les performances des leaders et évaluer le niveau de spam dans les blocs, ce qui leur permet de résoudre rapidement les problèmes et de passer à une autre source de données si nécessaire. Comme les validateurs cherchent à maximiser leurs revenus, ils sont incités à maintenir un cache exact des soldes des comptes payeurs de frais.

Sous-comités de taille fixe

La mise en œuvre d’AE sur un vaste réseau de 10 000 nœuds nécessite l’introduction de comités de vote rotatifs de taille fixe, ce qui représente une évolution majeure du mécanisme de consensus. Ce changement stabilise les coûts en ressources du vote de consensus, quel que soit le nombre total de nœuds stakés. Yakovenko estime qu’un comité rotatif de 200 ou 400 nœuds serait suffisant. Cette configuration permet aux validateurs de participer au vote de consensus avec des exigences minimales en matière d’état, limitées au quorum, aux pondérations par stake et aux soldes des comptes de vote. L’empreinte mémoire est faible, et le fichier de snapshot correspondant peut être facilement distribué et réinitialisé après un redémarrage.

La véritable ironie, c’est qu’après l’exécution asynchrone, un validateur de consensus Solana pourrait fonctionner sur un FPGA. Turbine et la tower pour 10 000 comptes de vote tiendraient facilement sur un FPGA. Il faudrait peut-être environ 4 Mo d’état à suivre.

Anatoly Yakovenko
Anatoly Yakovenko
Cofondateur de Solana

L’utilisation de sous-comités rotatifs de taille fixe dans les protocoles tolérants aux pannes byzantines (BFT) est un concept établi, déjà mis en œuvre en production par des réseaux comparables comme Tron. Il repose sur une approche d’échantillonnage des comités, qui sélectionne un comité plus restreint pour gérer le consensus et transmet les résultats à l’ensemble du réseau de réplicas.

Une première approche pour Solana pourrait consister à attribuer simplement un nombre défini de CU aux votes. Les principaux validateurs par stake pouvant tenir dans ces CU seraient sélectionnés à chaque époque pour suivre le choix du fork. Les autres validateurs continueraient de voter et de recevoir des récompenses, mais leurs votes ne seraient pas pris en compte dans le choix du fork.

Comptes de vote

● Les comptes de vote doivent détenir suffisamment de SOL pour couvrir deux époques de votes 

● Les transactions de vote doivent être de simples votes

● Le retrait de SOL du compte de vote est autorisé si le solde dépasse l’équivalent d’une époque de votes

● Pour retirer tous les lamports, l’instruction Vote CLOSE doit imposer l’écoulement d’une époque entière. Les comptes de vote sont marqués pour CLOSE pendant la première époque, mais ne peuvent être CLOSE que pendant la deuxième époque

CLOSE permet de retirer tous les SOL et de supprimer le compte de vote. Lorsqu’un compte est marqué pour CLOSE, il peut uniquement être supprimé et ne peut pas être rouvert

● Les votes contiennent un VoteBankHash au lieu d’un BankHash standard 

BankHashes

Les validateurs calculent un VoteBankHash pour les transactions de vote simples en utilisant le même format que le BankHash actuel et en ignorant toutes les autres transactions. Ces VoteBankHashes intègrent le VoteBankHash précédent plutôt que le BankHash complet.

Pour les blocs confirmés de façon optimiste par une supermajorité des deux tiers, les validateurs commencent également à calculer le UserBankHash, qui comprend toutes les transitions d’état à l’exception de celles déjà prises en compte dans le VoteBankHash.

Un BankHash est calculé pour chaque slot en combinant le VoteBankHash, le UserBankHash et le BankHash précédent. Les 99,5 % de validateurs les plus importants soumettent ce BankHash dans le cadre de leur vote tous les 100 slots. De plus, certains nœuds peuvent diffuser le BankHash sur le réseau gossip afin de signaler qu’aucun non-déterminisme n’a été détecté.

Supposons que moins des deux tiers des validateurs soumettent le BankHash complet. Dans ce cas, les leaders peuvent réduire de 50 % l’espace de bloc destiné aux transactions utilisateur et aux comptes accessibles en écriture, afin d’empêcher les exploits susceptibles d’augmenter excessivement le temps de rejeu.

L’état ne doit être calculé qu’une fois par époque pour établir le quorum suivant, ce qui garantit la synchronisation des nœuds de consensus et des leaders. L’exécution peut être agrégée et traitée par lots sur des machines distinctes des nœuds de consensus. Les utilisateurs qui ont besoin d’une exécution synchrone, notamment la plupart des applications et des RPC, peuvent dédier des ressources matérielles au traitement en temps réel de chaque transition d’état, sans attendre le reste du réseau.

Considérations

Les fournisseurs RPC qui proposent aux utilisateurs des données d’état en temps réel ne disposent pas d’une signature permettant de vérifier que l’état calculé localement correspond à celui calculé par l’ensemble du réseau. Toutefois, lorsqu’un fork est finalisé, le réseau converge vers un état canonique unique et correct, qui peut être calculé de manière déterministe. Pour réduire le risque de bugs d’exécution ou de corruption des données, les acteurs qui souhaitent fournir des données d’état précises doivent exploiter plusieurs nœuds. Si une divergence est détectée dans l’exécution de l’état, les opérations doivent être immédiatement interrompues.

Les utilisateurs peuvent également soumettre des transactions qui affirment le BankHash ou déclenchent un abandon. Le réseau ne traite ces transactions que si le BankHash calculé correspond à celui fourni à l’utilisateur par son fournisseur RPC.

Conclusion

Yakovenko imagine un avenir ambitieux pour Solana, avec des temps de bloc réduits à 120 millisecondes et une augmentation spectaculaire du nombre de nœuds, rendus possibles par l’adoption d’AE. Pour concrétiser cet avenir, il faut toutefois rallier à cette vision les différentes équipes clientes et l’ensemble de la communauté des développeurs Solana, tout en relevant les importants défis d’ingénierie liés à la mise en œuvre de tels changements. 

Des membres éminents de la communauté ont exprimé leurs inquiétudes au sujet de bon nombre de ces changements proposés. Richard Patel, de l’équipe Firedancer, a averti que « la mise en œuvre de l’exécution asynchrone pour les producteurs de blocs est assez complexe et comporte des risques importants. »

Bien que favorable à AE, Zano Sherwani de Jito Labs a critiqué MCBP en déclarant : « Les proposants simultanés multiples constituent une très mauvaise solution à la recherche d’un problème à résoudre. La complexité qu’ils ajoutent au protocole n’est pas justifiée par ce qu’ils tentent de résoudre, si tant est qu’ils résolvent quelque chose. »

Dans un podcast récent, interrogé au sujet de plusieurs builders de blocs, Mert Mumtaz de Helius a répondu : « Je ne suis pas entièrement convaincu. »

AE offre incontestablement d’importants gains de performances potentiels. Des temps de bloc plus courts accélèrent les confirmations et améliorent l’expérience utilisateur, tout en renforçant la résistance à la censure et en réduisant la fenêtre disponible pour réordonner les transactions.

Nous devons cependant aussi évaluer attentivement les inconvénients, notamment l’augmentation potentielle de la complexité du protocole et la dépendance accrue envers les fournisseurs RPC. Dans certains scénarios, ces fournisseurs pourraient être les seuls participants à disposer d’une vue actualisée et en temps réel de l’état de la chaîne.

AE représente une mise à niveau majeure pour Solana. Avec cet article, nous souhaitons sensibiliser la communauté des développeurs Solana aux changements prometteurs qu’AE introduira et encourager un débat plus éclairé sur ce sujet important.

Un grand merci à 0xIchigo et à Anatoly Yakovenko pour leur relecture des versions précédentes de ce travail.

Ressources supplémentaires

Abonnez-vous à Helius

Suivez les dernières actualités du développement sur Solana et recevez une notification à chaque publication

Image agrandie