Écrit par : Tia, Techub News
La blockchain, en raison de sa conception décentralisée, a sacrifié l'efficacité, ce qui fait que l'accélération de la vitesse d'exécution est l'un des problèmes à résoudre d'urgence. La « couche d'exécution » de la blockchain est la partie clé qui traite chaque transaction et l'ajoute à la chaîne. Pour accélérer la capacité de traitement, l'amélioration de la couche d'exécution est devenue l'une des stratégies clés, et l'exécution parallèle est une percée importante à cet égard.
Les blockchains traditionnelles traitent généralement les transactions de manière séquentielle, ce qui limite considérablement la vitesse des transactions, en particulier dans les réseaux à fort volume de transactions, entraînant des congestions. Cependant, grâce à l'exécution parallèle, plusieurs transactions peuvent être traitées simultanément, augmentant considérablement l'efficacité d'exécution et allégeant la pression sur la chaîne.
Pour mieux comprendre ce que signifie le parallélisme, nous commencerons par introduire l'exécution, en prenant Ethereum sous le modèle PBS après la fusion comme exemple pour expliquer ce qu'est l'exécution, tout en montrant où se situe l'exécution dans l'ensemble du cycle de vie des transactions.
Les étapes spécifiques de l'exécution des transactions
Les transactions entrent dans le pool de mémoire et sont filtrées et triées : c'est la phase de prétraitement après la soumission de la transaction, comprenant l'interaction entre le Mempool, le Searcher et le Builder, complétant le filtrage et le tri des transactions.
Le Builder construit le bloc (mais ne l'exécute pas) : le Builder arrange les transactions rentables en un bloc pour effectuer le regroupement et le tri des transactions.
Le proposeur vérifie et soumet le bloc : une fois le bloc construit, le Builder envoie la proposition du bloc au proposeur. Le proposeur vérifie la structure du bloc et le contenu des transactions, puis soumet officiellement le bloc au réseau pour commencer l'exécution.
Exécution des transactions : après la soumission du bloc, les nœuds exécutent les transactions dans le bloc une par une. C'est la phase clé de mise à jour de l'état, chaque transaction déclenchant des appels de contrat intelligent, des changements de solde de compte ou des modifications d'état.
Témoignage des témoins : les validateurs témoignent des résultats d'exécution des blocs et de la racine de l'état, confirmant ainsi la validité finale des blocs. Cela garantit l'authenticité et la validité des blocs à la couche d'exécution, empêchant toute incohérence.
Synchronisation d'état : chaque nœud synchronise les résultats d'exécution du bloc (comme les soldes de comptes, les mises à jour d'état des contrats, etc.) avec son état local. Après chaque transaction, le nœud calcule et stocke une nouvelle racine d'état pour l'utiliser comme état initial dans le prochain bloc.
Bien sûr, il ne s'agit que de la synchronisation d'état des transactions par bloc, pour maintenir l'état le plus récent sur la chaîne, les nœuds synchronisent généralement les données bloc par bloc et continuent de valider les blocs et les états. Mais pour atteindre la finalité sous le mécanisme POS, il est également nécessaire que les agrégateurs agrègent les signatures des témoins dans chaque Slot en une seule signature complète et les transmettent au proposeur du Slot suivant. De plus, les validateurs doivent, après un Epoch, confirmer l'état de tous les blocs dans cet Epoch sur la base du nombre de votes, formant ainsi un point de contrôle d'état de consensus temporaire. Une fois que deux Epoch consécutifs ont obtenu le soutien de la majorité des validateurs, les blocs et les transactions atteindront la finalité.
Du point de vue du cycle de vie complet de la transaction, l'exécution se produit après que le proposeur a vérifié la structure et le contenu des transactions du bloc envoyés par le Builder. Le processus d'exécution réel nécessite de traiter les transactions une par une et de mettre à jour l'état du compte ou du contrat correspondant. Une fois toutes les transactions exécutées, le proposeur calculera une nouvelle racine d'état (racine de Merkle), qui résume les résultats d'exécution de toutes les transactions du bloc et l'état global final. En termes simples, le processus complet d'exécution d'un bloc implique une série de calculs nécessaires pour passer d'un état précédent à un état suivant pour Ethereum, depuis l'exécution de chaque transaction jusqu'au calcul de la racine de Merkle.
Exécution séquentielle
En opposition au parallélisme, il y a l'exécution séquentielle, qui est la méthode d'exécution actuellement la plus courante sur les blockchains. En général, les transactions sont exécutées par étapes dans l'ordre. Lorsque l'exécution d'une transaction est terminée, Ethereum met à jour l'état du compte et les informations connexes (comme le solde, les données de stockage de contrat) dans l'arbre d'état du compte, générant un nouveau hachage d'état de compte. Une fois que tous les arbres d'état de comptes ont été mis à jour, cela forme ce qu'on appelle la racine de Merkle de l'état, le hachage de la racine de l'arbre d'état. Après avoir complété la racine de Merkle de l'état, la racine de Merkle de la transaction et la racine de Merkle des reçus, l'en-tête de bloc sera soumis à un calcul de hachage pour générer le hachage du bloc.
Dans ce contexte, l'ordre d'exécution des transactions est crucial. Puisque l'arbre de Merkle est un arbre binaire de hachages, les valeurs racines de Merkle formées dans différents ordres seront différentes.
Exécution parallèle
Dans un environnement d'exécution parallèle, les nœuds tenteront de traiter les transactions dans les blocs de manière parallèle. Ce n'est pas une exécution séquentielle transaction par transaction, mais plutôt l'affectation de transactions à différents « chemins d'exécution » afin qu'elles puissent s'exécuter simultanément. Grâce à l'exécution parallèle, le système peut traiter les transactions dans le bloc plus efficacement, augmentant le débit.
Après l'exécution de toutes les transactions, le nœud résume les résultats d'exécution (c'est-à-dire les mises à jour d'état influencées par les transactions) pour former un nouvel état de bloc. Cet état sera ajouté à la blockchain, représentant l'état global le plus récent sur la chaîne.
Conflit d'état
Étant donné que le parallélisme traite simultanément des transactions sur différents chemins, l'un des principaux défis du parallélisme est le conflit d'état. Cela signifie qu'il peut y avoir plusieurs transactions qui tentent de lire ou d'écrire simultanément sur la même partie des données (état) de la blockchain sur une période donnée. Si cette situation est mal gérée, cela peut entraîner des résultats d'exécution incertains. En raison de l'ordre différent des mises à jour d'état, le résultat final du calcul peut également varier. Un exemple serait :
Supposons qu'il y ait deux transactions, la transaction A et la transaction B, qui tentent toutes deux de mettre à jour le solde d'un même compte :
Transaction A : Augmente le solde du compte de 10.
Transaction B : Augmente le solde du compte de 20.
Le solde initial du compte est de 100.
Si nous exécutons en série, le résultat de l'ordre d'exécution est déterminé :
1. Exécutez d'abord la transaction A, puis la transaction B :
Le solde du compte augmente d'abord de 10, atteignant 110.
Puis augmente de 20, atteignant finalement 130.
2. Exécutez d'abord la transaction B, puis la transaction A :
Le solde du compte augmente d'abord de 20, atteignant 120.
Puis augmente de 10, atteignant finalement 130.
Dans ces deux ordres, le solde final est toujours de 130, car le système assure la cohérence de l'ordre d'exécution des transactions.
Mais dans un environnement d'exécution parallèle, la transaction A et la transaction B peuvent lire simultanément le solde initial de 100 et effectuer leurs calculs respectifs :
1. La transaction A lit un solde de 100, calcule et met à jour le solde à 110.
2. La transaction B lit également le solde de 100, calcule et met à jour le solde à 120.
Dans ce cas, en raison de l'exécution simultanée des transactions, le solde final n'est mis à jour qu'à 120 au lieu de 130, car les opérations des transactions A et B se « chevauchent » et produisent un conflit d'état.
Ces problèmes de conflit d'état sont souvent appelés « écrasement de données », c'est-à-dire que lorsque des transactions tentent de modifier simultanément les mêmes données, elles peuvent se chevaucher et écraser les résultats de calcul de l'autre, entraînant un état final incorrect. Un autre type de conflit d'état peut entraîner des problèmes d'impossibilité de garantir l'ordre d'exécution. Étant donné que plusieurs transactions complètent leurs opérations à différents moments, cela peut entraîner différents ordres d'exécution. Des ordres différents peuvent produire des résultats de calcul différents, rendant les résultats incertains.
Pour éviter cette incertitude, les systèmes d'exécution parallèle de blockchain introduisent généralement des mécanismes de détection des conflits et de retour en arrière, ou effectuent à l'avance une analyse de dépendance des transactions pour s'assurer qu'elles s'exécutent en parallèle sans affecter la cohérence de l'état final.
Parallélisme optimiste et parallélisme déterministe
Il existe deux approches pour aborder le problème potentiel de conflits d'état : le parallélisme déterministe et le parallélisme optimiste. Ces deux modèles présentent des compromis en matière d'efficacité et de complexité de conception.
Le parallélisme déterministe nécessite une déclaration préalable de l'accès à l'état, les validateurs ou les séquenceurs vérifiant les accès d'état déclarés lors du tri des transactions. Si plusieurs transactions tentent d'écrire le même état, ces transactions seront marquées comme conflictuelles, évitant une exécution simultanée. Les chaînes diffèrent quant à la façon de déclarer à l'avance l'accès à l'état, mais incluent généralement les méthodes suivantes :
Via des contraintes de spécifications de contrat : les développeurs définissent directement la portée d'accès à l'état dans le contrat intelligent. Par exemple, un transfert de jetons ERC-20 nécessite d'accéder aux champs de solde de l'expéditeur et du destinataire.
Via une déclaration de données structurées dans les transactions : ajout de champs spécifiques dans les transactions pour annoter l'accès à l'état.
Via l'analyse du compilateur : le compilateur de langages de haut niveau peut analyser statiquement le code du contrat et générer automatiquement un ensemble d'accès à l'état.
Via des déclarations obligatoires par le cadre : certains cadres exigent que les développeurs spécifient explicitement l'état à accéder lors de l'appel de la fonction.
Le parallélisme optimiste traite d'abord les transactions de manière optimiste, et lorsque des conflits se produisent, il réexécutera les transactions affectées dans l'ordre. Afin de minimiser les cas de conflit, l'essence du design du parallélisme optimiste est de prédire et d'hypothéquer rapidement l'état par des données historiques, une analyse statique, etc. C'est-à-dire que le système, sans vérification complète, suppose que certaines opérations ou mises à jour d'état sont valides, essayant d'éviter d'attendre tous les processus de vérification, améliorant ainsi la performance et le débit.
Bien que le parallélisme optimiste puisse éviter les conflits autant que possible par des hypothèses et des préjugés rapides sur l'état, il existe encore des défis inévitables, en particulier lorsqu'il s'agit d'exécutions de contrats ou de transactions inter-chaînes. Si des conflits se produisent fréquemment, les réexécutions peuvent considérablement ralentir les performances du système et augmenter la consommation des ressources de calcul.
Le parallélisme déterministe évite les conflits potentiels du parallélisme optimiste en effectuant une vérification de dépendance d'état avant la transaction, mais il nécessite que les dépendances d'état soient déclarées avec précision avant la soumission de la transaction, ce qui impose des exigences plus élevées aux développeurs, augmentant ainsi la complexité de mise en œuvre.
Dilemmes de parallélisme EVM
La façon de traiter les conflits d'état varie entre déterministe et optimiste, et lors de la mise en œuvre du parallélisme, il faut également considérer l'architecture de la base de données de la chaîne. Les conflits d'état dans le parallélisme sont particulièrement difficiles dans l'EVM sous l'architecture des arbres de Merkle. Un arbre de Merkle est une structure de hachage hiérarchique, et après chaque modification de données d'état par une transaction, la valeur de hachage de la racine de l'arbre de Merkle doit également être mise à jour. Ce processus de mise à jour est récursif, calculant couche par couche de la feuille jusqu'à la racine. Puisque le hachage est irréversible, on ne peut calculer la couche supérieure qu'une fois que les changements de données de la couche inférieure sont terminés, ce qui rend très difficile la mise à jour parallèle.
Si deux transactions s'exécutent en parallèle et accèdent au même état (comme le solde du compte), cela entraînera un conflit de nœud dans l'arbre de Merkle. Résoudre ce type de conflit nécessite généralement des mécanismes de gestion des transactions supplémentaires pour garantir qu'une valeur de hachage racine cohérente soit obtenue dans plusieurs branches. Cela n'est pas facile à réaliser pour l'EVM, car il doit faire des compromis entre la parallélisation et la cohérence de l'état.
Solutions de parallélisme non EVM
Solana
Contrairement à l'arbre d'état global d'Ethereum, Solana utilise un modèle de compte. Chaque compte est un espace de stockage indépendant, enregistré dans le livre, évitant ainsi les problèmes de conflit de chemin.
Solana est un parallélisme déterministe. Dans Solana, chaque transaction doit déclarer clairement les comptes qu'elle va accéder et les autorisations nécessaires (lecture seule ou lecture/écriture) lors de la soumission. Cette conception permet aux nœuds de blockchain d'analyser à l'avance les ressources nécessaires pour chaque transaction avant son exécution. Comme toutes les dépendances de compte sont déclarées avant le début de l'exécution, les nœuds peuvent déterminer quelles transactions accéderont aux mêmes comptes et lesquelles peuvent être exécutées en toute sécurité en parallèle, permettant ainsi une planification intelligente et évitant les conflits, établissant ainsi la base de la planification parallèle.
Puisque chaque transaction a déjà déclaré les comptes et les autorisations nécessaires avant son exécution, Solana peut vérifier s'il existe des dépendances entre les transactions (modèle Sealevel). Si aucune des transactions ne partage des comptes en lecture/écriture, le système peut les affecter à différents processeurs pour une exécution parallèle.
Aptos
La conception d'exécution parallèle d'Aptos diffère considérablement de celle d'Ethereum, avec des innovations clés dans son architecture et ses mécanismes, principalement en ce qui concerne le modèle de compte et le stockage d'état.
Ethereum doit fréquemment mettre à jour l'arbre d'état global (MPT) lors de l'exécution des transactions. Tous les états des comptes et des contrats sont stockés dans un arbre d'état partagé, chaque transaction nécessitant l'accès et la mise à jour d'une partie de cet arbre d'état. En revanche, Aptos divise les comptes en unités d'état indépendantes, chaque objet étant une paire clé-valeur indépendante, les objets peuvent exister indépendamment sans interférence, et ne se lient que par des relations de référence explicites. Il n'y a pas de chemin d'arbre commun entre les objets, ce qui évite la concurrence pour les verrous, permettant un traitement entièrement parallèle.
La structure de données sous-jacente d'Aptos est l'Arbre de Merkle Jellyfish. L'état de chaque objet est finalement stocké dans le JMT, en tant que paire clé-valeur indépendante. Contrairement au MPT d'Ethereum, l'Arbre de Merkle Jellyfish prend la forme d'un arbre binaire complet, ce qui simplifie les chemins de stockage et de requête des nœuds, réduisant considérablement le temps de vérification. De plus, la position de chaque compte dans l'arbre est fixe, et les nœuds dans l'arbre sont stockés de manière indépendante, permettant des mises à jour et des recherches de plusieurs comptes de manière parallèle.
Aptos utilise le parallélisme optimiste, n'exigeant pas la fourniture préalable de toutes les dépendances des comptes déclarés. Pour cela, Aptos utilise Block-STM, qui utilise l'ordre des transactions prédéfini pour estimer les dépendances, réduisant ainsi le nombre d'interruptions.
EVM parallèle
Comparé au parallélisme non EVM, le parallélisme EVM fait face à des défis techniques plus importants en matière de traitement des dépendances d'état, de détection des conflits, de gestion du Gas et de mécanismes de retour en arrière. Pour mieux comprendre cela, nous pouvons nous référer à certains projets EVM parallèles (comme Sui, Monad, Canto) et à la façon dont ils abordent ces problèmes.
Sui
Comme Aptos, Sui utilise également un modèle d'objet pour gérer l'état, utilisant chaque objet (comme un compte, un état de contrat intelligent) comme une ressource indépendante, ces objets étant distingués par un identifiant unique. Lorsque les transactions impliquent différents objets, ces transactions peuvent être traitées en parallèle, car elles opèrent sur des états différents, sans conflit direct.
Bien que Sui utilise un modèle d'objet pour gérer l'état, afin de rester compatible avec l'EVM, l'architecture de Sui utilise une couche d'adaptation ou un mécanisme abstrait supplémentaire pour faire le lien entre le modèle d'objet et le modèle de compte de l'EVM.
Dans Sui, la planification des transactions utilise une stratégie de parallélisme optimiste, supposant qu'il n'y a pas de conflit entre les transactions. Si un conflit se produit, le système utilise un mécanisme de retour en arrière pour restaurer l'état.
Sui utilise des modèles d'objet et une technologie d'isolement d'état, ce qui peut efficacement éviter les problèmes de dépendance d'état. Chaque objet en tant que ressource indépendante permet d'exécuter différentes transactions en parallèle, améliorant ainsi le débit et l'efficacité. Cependant, le compromis de cette méthode est la complexité du modèle d'objet et le coût des mécanismes de retour en arrière. Si des conflits se produisent entre les transactions, il sera nécessaire de revenir sur une partie de l'état, ce qui augmentera la charge du système et pourrait affecter l'efficacité du traitement parallèle. Comparé aux systèmes de parallélisme non EVM (comme Solana), Sui nécessite plus de ressources de calcul et de stockage pour maintenir une parallélisation efficace.
Monad
Comme Sui, Monad utilise également le parallélisme optimiste. Cependant, le parallélisme optimiste de Monad prédit tout de même certaines transactions ayant des dépendances avant l'exécution réelle, principalement via l'analyse statique du code de Monad. La prédiction nécessite d'accéder à l'état, et la façon dont l'état est stocké dans la base de données Ethereum rend l'accès à l'état très difficile, alors pour rendre le processus de lecture d'état parallèle plus efficace, Monad a également restructuré la base de données.
L'arbre d'état Monad est partitionné, chaque partition maintenant son propre sous-arbre d'état. Lors de la mise à jour, il suffit de modifier le fragment concerné sans reconstruire l'ensemble de l'arbre d'état. Une table d'index d'état permet de localiser rapidement l'état dans la partition, réduisant l'interaction entre les partitions.
Exigences matérielles des nœuds TPS de la blockchain Machine virtuelle Caractéristiques Solana 65 000+ 12 cœurs CPU, 256 Go de RAM, nœuds validateurs 500 Go SSD, nœuds d'archivage 1 To SSD, de préférence 500 Go supplémentaires pour le système d'exploitation Solana VM Prise en charge de la haute concurrence, utilisant la preuve d'historique (PoH), débit très élevé, mécanisme de consensus léger Aptos 160 000+ 32 cœurs CPU, 64 Go de RAM+, 3,0 To de stockage SSD Move VM Basé sur le langage Move, prend en charge l'exécution parallèle, optimise le débit élevé et la faible latence Sui 120 000+ 8 cœurs CPU, 128 Go de RAM, 4 To de stockage NVMe SSD Sui VM Exécution parallèle, modèle basé sur les ressources, prend en charge la faible latence et le débit élevé Monad 10000+ 16 cœurs CPU, 32 Go de RAM, 2 To de stockage NVMe SSD EVM (couche de compatibilité) Haute performance parallèle, optimisation du débit grâce à une exécution asynchrone et un design de machine virtuelle EVM plus léger Ethereum (après la fusion) 30-100+ 4 cœurs CPU, 32 Go de RAM, 4 To de stockage SSD EVM Plateforme de contrat intelligent traditionnelle, passant à la preuve d'enjeu après la fusion, tout en prenant encore en charge une parallélisation limitée
Résumé
Le cœur du parallélisme est d'améliorer l'efficacité d'exécution de la couche d'exécution par l'exécution multi-chemins. Pour réaliser l'exécution multi-chemins, la chaîne doit mettre en œuvre une série de mécanismes tels que la détection de conflits et le retour en arrière pour s'assurer qu'ils s'exécutent en parallèle sans affecter la cohérence de l'état final, et apporter certaines améliorations à la base de données.
Bien sûr, l'amélioration de l'efficacité de la couche d'exécution ne se limite pas à une seule méthode de parallélisme. L'optimisation des étapes d'exécution peut également être réalisée en réduisant les opérations de lecture et d'écriture nécessaires à une transaction dans la base de données. L'ensemble des améliorations de la vitesse de la chaîne implique un champ d'application plus large, y compris l'amélioration de l'efficacité de la couche de consensus.
Chaque technologie a des conditions de limitation spécifiques. Le parallélisme n'est qu'une des façons d'améliorer l'efficacité, et la décision d'utiliser cette technologie doit également prendre en compte son amitié pour les développeurs, la possibilité d'être réalisée sans sacrifier la décentralisation, etc. L'empilement technologique n'est pas nécessairement mieux, du moins en ce qui concerne Ethereum, le parallélisme n'est pas si attractif que cela. Si l'on part uniquement de l'angle de l'efficacité, l'ajout de paralélisme n'est pas la solution optimale pour Ethereum, que ce soit en termes de simplicité ou en tenant compte de la feuille de route actuelle centrée sur les Rollups.