
Le co-fondateur de Solana explique l'architecture ultime de Solana
TechFlow SélectionTechFlow Sélection

Le co-fondateur de Solana explique l'architecture ultime de Solana
Toutes les transactions non votantes peuvent être calculées de manière asynchrone.
Rédaction : Anatoly Yakovenko, PDG de Solana (cofondateur et CEO)
Traduction : 1912212.eth, Foresight News
L'objectif de Solana est de synchroniser le plus rapidement possible une machine d'état globale unique, sans autorisation, tout en respectant les lois physiques. Je crois que l'architecture permettant d'atteindre cet objectif sera la suivante :
-
Un grand nombre de nœuds complets, dépassant 10 000 (N > 10 000)
Pour que le réseau fonctionne comme une machine d'état globale, il doit supporter un grand nombre de nœuds complets. Turbine a déjà démontré qu'une réplication rapide vers un réseau très étendu est évolutivement réalisable sur du matériel et des réseaux modernes.
-
Un grand nombre de leaders de génération de blocs, dépassant 10 000 (N > 10 000)
-
Des leaders concurrents produisent simultanément des blocs, avec un choix aléatoire entre 4 et 16.
Les leaders concurrents permettent au réseau d'avoir plusieurs emplacements à l'échelle mondiale pour ordonner les transactions utilisateur. Cela réduit la distance entre l'utilisateur et le réseau, et élimine la nécessité pour les nœuds complets de valider chaque transaction avant son ajout à la chaîne.
-
Temps de bloc : 120 millisecondes
Un temps de bloc court crée des points de finalité rapides, renforce la résistance à la censure, améliore l'expérience utilisateur, réduit la fenêtre de réordonnancement des transactions, et accélère globalement le réseau.
-
Un comité restreint de nœuds de consensus votants, composé de 200 à 400 nœuds, choisis aléatoirement parmi les leaders, et renouvelé tous les 4 à 8 heures par epoch.
Le consensus est essentiel pour choisir la fourche lors de partitions réseau. Un échantillon de 200 nœuds ou plus représentera statistiquement toutes les principales partitions du réseau et reflétera fidèlement leur distribution réelle. Ainsi, il n'est pas nécessaire que tous les nœuds complets votent : 200 suffisent. Restreindre le vote à un comité réduit la mémoire et la bande passante réseau requises pour supporter un temps de bloc de 120 ms. Réduire le temps de bloc augmente naturellement le nombre de votes envoyés par seconde, ce qui exerce une pression sur les ressources allouées au consensus.
Le véritable défi dans un bloc de 120 ms réside dans la relecture de toutes les transactions utilisateur. Étant donné que le réseau est sans autorisation, garantir un environnement d'exécution homogène capable d'exécuter en temps fiable un code utilisateur arbitraire est extrêmement difficile. Bien que cela soit possible, cela ne peut être réalisé qu'en limitant les ressources de calcul disponibles aux transactions utilisateur et en s'assurant que chaque nœud est surdimensionné pour le pire cas.
Cependant, pour les nœuds de consensus votants soutenant une fourche ou les leaders construisant dessus, il n'y a aucune raison d'exécuter l'état complet. Pour maintenir la synchronisation entre les nœuds de consensus et les leaders, l'état n'a besoin d'être calculé qu'une seule fois par période.
Exécution asynchrone
Motivation
L'exécution synchrone exige que tous les nœuds votants et producteurs de blocs soient fortement surdimensionnés pour chaque bloc afin de garantir le temps d'exécution dans le pire des cas. L'exécution asynchrone est l'une des rares optimisations presque sans compromis. Les nœuds de consensus peuvent effectuer moins de travail avant de voter. Ce travail peut être agrégé et traité par lots, rendant son exécution très efficace, sans pertes de cache. Il peut même être exécuté sur des machines totalement distinctes des nœuds de consensus ou des leaders. Les utilisateurs souhaitant une exécution synchrone peuvent allouer suffisamment de ressources matérielles pour exécuter chaque transition d'état en temps réel, sans attendre le reste du réseau.
Étant donné la diversité des applications et des développeurs principaux, il serait pertinent de planifier une modification majeure du protocole chaque année. S'il fallait en choisir une, mon choix serait l'exécution asynchrone.
Aperçu
Actuellement, les validateurs rejouent rapidement toutes les transactions de chaque bloc et ne votent qu'après avoir calculé l'état complet du bloc. Cette proposition vise à séparer la décision de vote sur la fourche du calcul de la transition d'état complète du bloc.
Les validateurs votants dans le quorum n'ont besoin que de choisir la fourche ; ils n'ont absolument pas besoin d'exécuter aucun état. Ils n'ont besoin de l'état qu'une fois par epoch, pour calculer le prochain quorum.
La procédure de vote est modifiée pour pouvoir être exécutée indépendamment. Les nœuds n'exécutent la procédure de vote qu'avant de voter. Comme les transactions de vote occupent peu d'espace, les exigences en mémoire devraient être relativement faibles. Étant donné que l'exécution du vote a un temps très prévisible, elle devrait présenter presque aucun jitter.
Toutes les transactions non-votantes peuvent être calculées de manière asynchrone. Cela permet de rejouer par lots toutes les transactions non-votantes, de précharger et de compiler à l'avance (JIT) tous les programmes, éliminant ainsi presque entièrement les pertes de cache. L'objectif à long terme est que seules les machines nécessitant un calcul d'état complet à faible latence en temps réel soient configurées pour cette tâche. On suppose que les utilisateurs paieront des frais supplémentaires pour le matériel nécessaire.
Une fois la sélection de fourche dissociée de l'exécution d'état, il devient plus facile de progresser :
-
Exécution asynchrone
-
Rotation d'un nombre fixe de membres du comité votant par epoch
-
Temps de bloc de 200 millisecondes
Puisque la relecture des transactions utilisateur ne bloque plus le choix de la fourche, la variabilité n'est plus un problème lors de la réduction du temps de bloc. Le seul facteur à considérer est que, à 200 ms, le taux de vote des validateurs double. Une modification assez directe de la façon dont le quorum calcule ses quotas permettra de fixer la taille du quorum à 200, 400, ou tout autre nombre approprié.
Il est également naturel de séparer complètement l'exécution du consensus. Le redémarrage ne nécessitera plus que de vérifier les comptes de vote des nœuds de consensus dans un quorum de taille fixe, ce qui sera beaucoup plus rapide.
En pratique, je crois que les temps de confirmation s'amélioreront, car la majorité du quorum votera aussi vite que possible, tandis que les nœuds fournissant aux utilisateurs les résultats de l'exécution d'état complet pourront exécuter les transactions en parallèle pendant que les votes se propagent. Ainsi, toute fluctuation de relecture que nous observons aujourd'hui devrait se produire simultanément à la propagation des votes.
Votes
-
Le compte de vote doit posséder une quantité suffisante de SOL pour couvrir 2 epochs de votes.
-
Les transactions de vote doivent être simples. Toute transaction de vote non simple échouera nécessairement. Les générateurs de blocs devraient abandonner les votes complexes.
-
Le retrait de SOL depuis un compte de vote est autorisé, tant que le solde ne descend pas en dessous du niveau requis pour 1 epoch de vote.
-
Pour vider complètement tous les lamports, l'instruction Vote CLOSE exige qu'une epoch complète se soit écoulée. Un compte marqué comme CLOSE à l'epoch 1 ne peut être fermé qu'à l'epoch 2. CLOSE permet de retirer tous les SOL et de supprimer le compte de vote. Une fois marqué comme CLOSE, un compte ne peut être que supprimé définitivement, jamais rouvert.
-
Le vote contient un VoteBankHash, plutôt qu'un BankHash classique.
Contrôle des leaders et quorum
Seuls les validateurs remplissant les conditions suivantes :
-
Montant mis en gage > X
-
Et SOL > coût de vote pour 2 epochs
-
Et non marqué comme CLOSE
peuvent entrer dans la planification des leaders et être pris en compte dans le quorum. Pour la version 2, on peut séparer LeaderSchedule du Quorum, leurs exigences respectives n'ayant pas besoin d'être identiques.
Calcul du VoteBankHash
Contrairement au BankHash qui prend en compte toutes les transactions, les validateurs calculent le VoteBankHash uniquement à partir des transactions de vote simples associées aux validateurs présents dans le LeaderScheduler. Toutes les autres transactions sont ignorées. Après avoir rejoué tous les votes, le VoteBankHash est calculé selon le même format que le BankHash actuel.
Le VoteBankHash devrait accumuler le VoteBankHash précédent, plutôt que le BankHash complet.
Calcul du BankHash
Pour tous les blocs confirmés de manière optimiste (configurable pour tous les blocs), les validateurs commencent à calculer le UserBankHash, qui inclut toutes les transitions d'état, sauf les transactions déjà prises en compte dans le VoteBankHash.
Le BankHash est ensuite dérivé de l'accumulation de (VoteBankHash, UserBankHash). Les 99,5 % premiers validateurs soumettent le BankHash comme partie intégrante de leur vote tous les 100 slots. Bien qu'il soit soumis tous les 100 slots, il est calculé à chaque slot. Il convient de noter qu'il pourrait être utile qu'une petite fraction de nœuds soumette continuellement le BankHash via gossip comme signal doux d'absence de non-déterminisme.
Si moins de 67 % des validateurs soumettent le calcul complet du BankHash, le leader devrait réduire de 50 % l'espace disponible dans le bloc pour les transactions utilisateur et les comptes modifiables. Cette mesure vise à protéger la chaîne contre les abus pouvant excessivement augmenter le temps de relecture.
Le BankHash devrait accumuler le BankHash précédent.
Leaders sans banque
Durant la création d'un bloc, le leader risque probablement de ne pas avoir accès à l'état nécessaire pour créer le bloc, et il n'est pas idéal d'exécuter toutes les transactions durant cette phase.
-
Le leader maintient un cache des soldes des comptes payeurs.
-
Si un compte payeur est utilisé comme source d'un transfert système, ou transmis comme compte modifiable avec le programme système à un autre programme, alors son solde est mis à zéro.
-
Les blocs sont regroupés par ordre de priorité locale basée sur les unités de calcul déclarées (CUs), jusqu'à remplissage complet du bloc.
-
Les frais sont déduits du cache des soldes des comptes payeurs.
-
Le cache des soldes des comptes payeurs est alimenté par le calcul du BankHash.
Le coût pour le réseau en cas d'échec dû aux spams de transactions est relativement faible, comprenant uniquement les octets stockés dans l'archive et la bande passante nécessaire à la diffusion des transactions dans les blocs.
Étant donné que les validateurs cherchent déjà à maximiser leurs revenus, ils ont une forte incitation à maintenir un cache précis des comptes payeurs. En outre, en l'absence de mécanisme de pénalité, à long terme, n'importe quel participant du réseau pourrait facilement fournir ce service de cache. En cas de panne du serveur, les opérateurs de leaders sans banque devraient pouvoir facilement basculer ou échantillonner à partir de multiples sources.
Cela signifie que, motivés par la recherche de revenus maximaux, les validateurs s'efforceront de maintenir un cache précis des comptes payeurs. Sans mécanisme de pénalité, ce cache pourrait à long terme être fourni par n'importe quel nœud du réseau. De plus, en cas de défaillance du serveur, les opérateurs de leaders sans banque devraient pouvoir facilement basculer ou échantillonner à partir de plusieurs sources.
Compromis
Le principal compromis réside dans le fait que les nœuds complets fournissant l'état utilisateur manquent d'une signature confirmée garantissant que leur état est parfaitement cohérent avec le reste du quorum. L'interprétation autoritative de l'état doit rester inchangée, même si chaque transaction est relue séquentiellement dans le registre. Aucune optimisation de performance ne devrait altérer le résultat. Ainsi, une fois la fourche finalisée, il ne reste qu'un seul état correct à calculer, à condition qu'il n'y ait pas d'erreur dans l'implémentation du runtime.
Les nœuds visant à fournir de manière fiable l'état devraient exécuter plusieurs machines et clients, et interrompre leurs opérations en cas de divergence dans l'exécution de l'état. C'est fondamentalement ce que les opérateurs devraient faire aujourd'hui, car se fier uniquement au reste du réseau introduit une hypothèse de majorité honnête.
Les utilisateurs peuvent également signer des transactions affirmant le BankHash ou déclenchant un arrêt. Ces transactions ne seront exécutées par le reste du réseau que si le BankHash exactement calculé correspond parfaitement au BankHash fourni par le fournisseur RPC à l'utilisateur.
Feuille de route à long terme : nœuds de consensus sans état
Un réseau doté d'un quorum de taille fixe n'a besoin que d'une très petite quantité d'état pour démarrer : le quorum lui-même, ses poids de mise en gage, et les soldes de tous les comptes de vote. C'est une mémoire très réduite et un fichier d'instantané minuscule pouvant être distribué rapidement et initialisé rapidement au redémarrage.
Si le quorum diverge des nœuds complets, ceux-ci — qui suivent simultanément le quorum et l'état — s'arrêteront. Cela signifie que si le quorum diverge de l'état, les bourses, canaux fiat, RPC, ponts, etc., cesseront de fonctionner. Cela ne nécessite qu'une proportion très faible de nœuds de consensus sans état défectueux.
Les leaders sans banque peuvent s'appuyer sur des échantillons provenant de plusieurs nœuds complets pour initialiser le cache des soldes des comptes payeurs. Même en cas de défaut, le résultat sera du spam dans les blocs, pas une défaillance du consensus. Les opérateurs devraient pouvoir surveiller la santé de leur leader et le pourcentage de spam injecté dans les blocs, et réagir rapidement aux pannes.
Bienvenue dans la communauté officielle TechFlow
Groupe Telegram :https://t.me/TechFlowDaily
Compte Twitter officiel :https://x.com/TechFlowPost
Compte Twitter anglais :https://x.com/BlockFlow_News














