
Historique complet des pannes de Solana : causes, correctifs et enseignements
Sommaire
- Introduction
- Vivacité et sûreté
- Redémarrages du réseau
- Signalement des bugs
- Pannes recensées
- Bug de Turbine : décembre 2020
- L’IDO de Grape Protocol : septembre 2021
- Un second bug : dépassement d’entier
- Forte congestion : janvier 2022
- Spam de Candy Machine : avril/mai 2022
- Taxe de Candy Machine sur les bots
- Bug des nonces durables : juin 2022
- Bug de bloc dupliqué : septembre 2022
- Un bloc volumineux submerge Turbine : février 2023
- Boucle de recompilation infinie : février 2024
- Correctif coordonné d’une vulnérabilité : août 2024
- Processus de mise à jour corrective
- Conclusion
- Ressources complémentaires
Bip, bip, bip. Bip, bip, bip.
Le sommeil de Steven est brutalement interrompu par la sonnerie stridente de son téléphone, qui l’arrache soudainement à ses rêves. Dans l’obscurité, l’écran brille intensément tandis que l’appareil vibre frénétiquement sur sa table de chevet. Bip, bip, bip. Il gémit, se frotte les yeux encore ensommeillés et saisit l’appareil. En plissant les yeux pour lire le message, il sent son cœur se serrer : le nœud est hors service. Sans hésiter, il bondit du lit à moitié habillé et tente maladroitement de déverrouiller son téléphone tandis que d’autres messages affluent. Il comprend alors : tout le cluster est hors service.
À cet instant précis, partout dans le monde, dans différentes villes et différents fuseaux horaires, des centaines d’opérateurs de nœuds fixent leur téléphone avec la même prise de conscience : le moment qu’ils redoutaient est arrivé — une panne.
Introduction
Comme tous les systèmes distribués, Solana doit composer avec le fait qu’un seul défaut d’implémentation ou cas limite obscur peut entraîner une défaillance de l’ensemble du réseau. Bien que perturbatrices, les pannes sont inévitables dans la maintenance d’une infrastructure distribuée complexe, qu’il s’agisse de blockchains décentralisées, de plateformes d’échange centralisées ou même de grands fournisseurs de services cloud comme Amazon ou Microsoft.
La question n’est pas de savoir si des défaillances se produiront, mais quand elles se produiront — et comment le réseau évoluera pour s’y adapter et mieux résister aux incidents futurs. Malgré des tests rigoureux en simulation, un testnet incitatif et un programme actif de primes aux bugs, aucun système, aussi bien conçu soit-il, ne peut anticiper tous les modes de défaillance possibles. Les enseignements les plus précieux viennent de l’exploitation en conditions réelles.
Au cours des cinq dernières années, Solana a connu sept pannes distinctes, dont cinq causées par des bugs de client et deux par l’incapacité du réseau à gérer des torrents de transactions indésirables. Les premières versions de Solana ne disposaient pas de mécanismes essentiels de gestion de la congestion, comme les frais de priorité et les marchés de frais locaux, qui se sont ensuite révélés indispensables pour réduire la pression sur le réseau. L’absence de tels mécanismes a entraîné de longues périodes de performances dégradées et de congestion tout au long de l’année 2022, le réseau encourageant de fait le spam.
Cet article analyse en détail chaque panne de Solana, en examinant ses causes profondes, les événements déclencheurs et les mesures prises pour la résoudre. Nous aborderons également les principaux aspects du redémarrage du réseau, du signalement des bugs ainsi que les concepts fondamentaux de défaillance de vivacité et de sûreté. Bien qu’il soit préférable de lire ces sections dans l’ordre, chacune est conçue pour être autonome, afin que les lecteurs puissent accéder directement aux sujets ou aux pannes qui les intéressent le plus.
Vivacité et sûreté
Selon le théorème CAP, également appelé théorème de Brewer, un système distribué ne peut garantir que deux des trois propriétés suivantes :
- Cohérence - Chaque lecture voit toutes les écritures précédentes.
- Disponibilité - Chaque requête reçoit une réponse.
- Tolérance au partitionnement - Le système continue de fonctionner malgré les partitions réseau.
Pour les blockchains, la tolérance au partitionnement est essentielle : les perturbations du réseau sont inévitables. Il faut donc choisir entre AP (disponibilité + tolérance au partitionnement) et CP (cohérence + tolérance au partitionnement). Comme la plupart des chaînes PoS à finalité rapide, Solana privilégie la cohérence à la disponibilité, ce qui en fait un système CP. Elle s’arrête en cas de défaillance critique plutôt que de servir des données obsolètes ou d’autoriser des écritures non sûres. Si cela signifie que le logiciel des nœuds peut entrer dans un état irrécupérable nécessitant une intervention manuelle, cela garantit également la sécurité des fonds des utilisateurs.
Défaillance de vivacité : survient lorsque la blockchain cesse de progresser, empêchant la confirmation des transactions et la production de blocs en raison de l’indisponibilité de validateurs, de partitions réseau ou d’un blocage du consensus. Dans le contexte du théorème CAP, cela correspond à une perte de disponibilité.
Défaillance de sûreté : survient lorsque l’état finalisé de la blockchain est modifié ou bifurqué de manière incorrecte. Cela peut créer des historiques contradictoires ou une double dépense, souvent en raison de bugs de consensus ou d’attaques malveillantes. Dans le contexte du théorème CAP, cela correspond à une perte de cohérence.
Solana privilégie la sûreté à la vivacité. Le réseau s’arrête donc en cas de pression extrême ou de défaillance du consensus plutôt que de risquer une corruption de l’état. Bien que les pannes soient perturbatrices et puissent affecter les applications, les utilisateurs et les validateurs, elles restent préférables aux conséquences catastrophiques d’un registre incohérent ou corrompu.
Redémarrages du réseau
Le redémarrage du réseau Solana consiste à identifier le dernier slot de bloc confirmé de manière optimiste, puis à redémarrer les nœuds à partir d’un snapshot local fiable de l’état de ce slot. Comme le slot de redémarrage n’est pas déterminé on-chain, les opérateurs de validateurs doivent parvenir à un consensus off-chain sur un point de retour sûr. Cette coordination se déroule publiquement dans le canal #mb-validators du Discord Solana Tech, où les opérateurs professionnels de validateurs communiquent en temps réel. La plupart disposent de systèmes d’alerte automatisés qui les préviennent dès que la production de blocs s’arrête, ce qui garantit une réaction rapide.
Une fois qu’un consensus est atteint sur le bon slot de redémarrage, les opérateurs utilisent l’outil de registre pour générer un nouveau snapshot local, redémarrer leurs validateurs et attendre qu’au moins 80 % du stake total soit de nouveau en ligne. Ce n’est qu’à ce moment-là que le réseau reprend la production et la validation des blocs. Vérifier qu’au maximum 20 % du stake est hors ligne lors du redémarrage du cluster garantit une marge de sécurité suffisante pour rester opérationnel si des nœuds bifurquent ou repassent hors ligne immédiatement après le redémarrage.
Signalement des bugs
Les programmes de primes aux bugs récompensent les chercheurs en sécurité qui identifient et signalent des vulnérabilités logicielles. Ils constituent une ligne de défense essentielle, car ils incitent de manière proactive à détecter les bugs avant qu’ils ne puissent être exploités. Les chercheurs en sécurité et les développeurs qui identifient des vulnérabilités potentielles dans le client Agave sont invités à les signaler par les canaux de sécurité appropriés. Des consignes de divulgation détaillées sont disponibles dans le dépôt GitHub d’Agave.
Des récompenses sont offertes pour les signalements valides de vulnérabilités critiques, avec des montants déterminés selon leur gravité :
- Perte de fonds : jusqu’à 25 000 SOL
- Violations du consensus ou de la sûreté : jusqu’à 12 500 SOL
- Défaillance de vivacité ou perte de disponibilité : jusqu’à 5 000 SOL
En outre, le client FireDancer dispose d’un programme distinct de primes aux bugs, hébergé sur Immunefi, qui offre une récompense maximale de 500 000 USDC pour les découvertes critiques.
Pannes recensées
Les sections suivantes proposent une analyse détaillée et chronologique des pannes et des périodes de performances dégradées de Solana depuis le lancement de Mainnet Beta le 16 mars 2020. Cette étude met en lumière les principaux incidents, leurs causes profondes et les améliorations ultérieures du réseau. Elle montre comment Solana a évolué au fil du temps pour renforcer sa stabilité et sa résilience.
Bug de Turbine : décembre 2020
Durée d’indisponibilité : environ six heures
Problème fondamental : bug de propagation des blocs
Correctifs :
- Suivre les blocs par hash plutôt que par numéro de slot
- Corriger les endroits de Turbine où les défaillances peuvent être détectées plus tôt
- Propager la première défaillance détectée à tous les validateurs via gossip
Cette panne a été causée par un problème déjà connu de réparation des blocs et de traitement du code, déclenché par un bug non identifié dans Turbine, le mécanisme de propagation des blocs de Solana. La défaillance s’est produite lorsqu’un validateur a transmis deux blocs différents pour le même slot et les a propagés vers deux partitions distinctes (A et B), tandis qu’une troisième partition détectait indépendamment l’incohérence.
Comme chaque partition ne détenait qu’une part minoritaire du stake, aucune ne pouvait obtenir le consensus d’une supermajorité pour faire progresser la chaîne. Le problème provenait de la manière dont les structures de données internes de Solana suivent les blocs et leur état calculé. Le système utilisait le numéro de slot de la Proof of History (PoH), un identifiant u64, pour référencer l’état et le bloc de ce slot. Une fois le réseau divisé en partitions, les nœuds ont interprété à tort les blocs A et B comme étant identiques, empêchant leur réparation et leur synchronisation correctes.
Chaque partition supposait que l’autre détenait le même bloc, ce qui a entraîné un conflit fondamental :
- Les nœuds détenant le bloc A rejetaient les forks dérivés du bloc B
- Les nœuds détenant le bloc B rejetaient les forks dérivés du bloc A
Comme les transitions d’état différaient entre les partitions, les validateurs ne pouvaient ni réparer ni réconcilier les forks, empêchant ainsi la finalité.
Le correctif a consisté à permettre aux services de suivre les blocs par hash plutôt que par numéro de slot. Si plusieurs blocs d’un même slot créent des partitions, celles-ci sont traitées de la même façon que les partitions dont les blocs occupent des slots différents. Les nœuds peuvent alors réparer tous les forks possibles et le consensus peut résoudre les partitions.
Bien que le bug ait été la cause initiale de la panne, l’essentiel de l’indisponibilité provenait de l’attente du retour en ligne d’un poids de stake suffisant, car Solana exige une participation d’au moins 80 % du stake pour reprendre la production de blocs.
L’IDO de Grape Protocol : septembre 2021
Durée d’indisponibilité : dix-sept heures
Problème fondamental : saturation de la mémoire causée par des transactions de bots
Correctifs :
- Ignorer les verrous d’écriture sur les programmes
- Limiter le débit de transfert des transactions
- Rendre configurable le comportement de nouvelle tentative des RPC
- Prioriser les transactions de vote dans la TPU
Le 14 septembre 2021, Solana a subi un blocage majeur du réseau après le lancement par Grape Protocol de son offre initiale de DEX (IDO) on-chain sur la plateforme de financement participatif Raydium AcceleRaytor. Dans les 12 minutes suivant le début de l’IDO, le réseau a été submergé par un torrent sans précédent de transactions générées par des bots et a cessé de produire des slots enracinés. Ces bots ont effectivement mené une attaque distribuée par déni de service (DDoS), poussant la charge transactionnelle au-delà des capacités du réseau.
Au plus fort de la congestion :
- Certains validateurs recevaient plus de 300 000 transactions par seconde.
- Les données brutes des transactions dépassaient 1 Gbit/s, avec 120 000 paquets par seconde.
- Le trafic dépassait parfois les limites physiques des interfaces réseau, provoquant la perte de paquets au niveau du port du commutateur avant même qu’ils n’atteignent les validateurs.
L’un des bots structurait ses transactions de façon à verrouiller en écriture 18 comptes essentiels, notamment le programme global de tokens SPL et le programme désormais abandonné Serum DEX. Cela bloquait toutes les transactions interagissant avec ces comptes et réduisait fortement la capacité de traitement parallèle de Solana. Au lieu d’exécuter les transactions indépendamment, le réseau a rencontré un goulot d’étranglement et les a traitées séquentiellement, aggravant ainsi la congestion.
Un correctif ignorant les verrous d’écriture sur les programmes avait déjà été développé et sa publication était planifiée. Le redémarrage du réseau a ensuite permis d’activer cette mise à niveau, supprimant définitivement ce vecteur d’attaque.
Pendant l’IDO, les validateurs ont reçu un torrent de transactions générées par des bots, puis ont transféré les transactions excédentaires au leader suivant, amplifiant la congestion. Le redémarrage du réseau a introduit des limites de débit sur le transfert des transactions pour empêcher de futures tempêtes de transactions de submerger les leaders.
Les nœuds RPC de Solana réessaient automatiquement les transactions ayant échoué, une fonctionnalité conçue pour améliorer la fiabilité. Cependant, sous une congestion extrême, ce mécanisme de nouvelle tentative a amplifié le flot de transactions en maintenant les anciennes transactions en circulation au lieu de permettre au réseau de récupérer. Solana 1.8 a introduit un comportement configurable pour les nouvelles tentatives RPC, permettant aux applications de les optimiser avec des délais d’expiration plus courts et des stratégies de backoff exponentiel.
Sous une forte congestion, les leaders Solana n’ont pas réussi à inclure les transactions de vote, pourtant essentielles au maintien du consensus. L’absence de votes confirmés a donc bloqué le consensus et interrompu la production de nouveaux blocs racines. Les versions ultérieures du client Solana ont introduit un mécanisme de priorisation des transactions de vote, empêchant qu’elles soient noyées par les transactions ordinaires lors d’incidents futurs.
Un second bug : dépassement d’entier
Un second problème est apparu lors du redémarrage du réseau. Les validateurs ont signalé des fluctuations extrêmes du montant de stake actif. Ce problème provenait d’un bug qui multipliait incorrectement le pourcentage de stake par 100, dépassant ainsi la valeur maximale possible. Le mécanisme d’inflation avait créé tant de nouveaux tokens SOL qu’il avait provoqué le dépassement de capacité d’un entier non signé de 64 bits. Ce bug a été rapidement identifié et corrigé avant un second redémarrage.
Forte congestion : janvier 2022
Durée d’indisponibilité : aucune
Cause profonde : nombre excessif de transactions dupliquées Correctif partiel :
- Versions 1.8.12 et 1.8.14 de Solana
- Optimisation de la déduplication SigVerify
- Amélioration des performances du cache d’exécution
Entre le 6 et le 12 janvier 2022, le mainnet de Solana a subi une congestion sévère, entraînant des performances dégradées et des pannes partielles. La perturbation était due à des bots qui envoyaient un nombre excessif de transactions dupliquées, réduisant considérablement la capacité du réseau. Le traitement des blocs prenait plus de temps que prévu, ce qui amenait le leader suivant à créer un fork et réduisait encore le débit. Au plus fort de l’incident, le taux de réussite des transactions a chuté de jusqu’à 70 %. Le client peinait à gérer des transactions toujours plus complexes et gourmandes en calcul, révélant ses limites face à la demande.
Une instabilité supplémentaire s’est produite du 21 au 23 janvier, tandis que la congestion persistait. Le 22 janvier, l’endpoint RPC public (https://api.mainnet-beta.solana.com) est devenu indisponible en raison d’une utilisation abusive, des appels RPC groupés indésirables ayant submergé le système.
Pour résoudre ces problèmes, la version 1.8.12 de Solana ciblait spécifiquement l’épuisement du cache des programmes, tandis que la version 1.8.14 apportait des améliorations au cache Sysvar, au rejet SigVerify et à la déduplication SigVerify.
Spam de Candy Machine : avril/mai 2022
Durée d’indisponibilité : huit heures
Problème fondamental : spam de transactions provenant de comptes de bots
Correctifs :
- Taxe sur les bots dans le programme Candy Machine
- Amélioration de la gestion de la mémoire dans Solana v1.10
Le 30 avril 2022, Solana a connu une hausse sans précédent du nombre de requêtes de transaction. Certains nœuds ont signalé jusqu’à six millions de requêtes par seconde, générant plus de 100 Gbit/s de trafic par nœud. Cette hausse était due à des bots qui tentaient d’obtenir des NFT nouvellement créés via le programme Metaplex Candy Machine. Ce mécanisme de création fonctionnait selon le principe du premier arrivé, premier servi, ce qui incitait fortement à inonder le réseau de transactions pour remporter le mint.
Lorsque le volume de transactions a explosé, les validateurs ont épuisé leur mémoire et sont tombés en panne, ce qui a fini par bloquer le consensus. Le débit insuffisant des votes a empêché la finalisation des blocs précédents et donc la suppression des forks abandonnés. Les validateurs ont alors été submergés par le nombre considérable de forks à évaluer, dépassant leurs capacités même après les redémarrages et nécessitant une intervention manuelle pour restaurer le réseau.
Bien que cette panne présente des similitudes avec l’incident de septembre 2021, Solana a fait preuve d’une meilleure résilience. Malgré un volume de requêtes de transaction supérieur de 10 000 % à celui de la panne précédente, le réseau est resté opérationnel bien plus longtemps, ce qui reflète les améliorations apportées par la communauté des validateurs en réponse aux précédents défis de mise à l’échelle.
Le redémarrage du réseau a pris moins d’une heure et demie après l’accord sur le snapshot canonique. Solana v1.10 comprenait des améliorations de l’utilisation de la mémoire afin de prolonger la durée pendant laquelle les nœuds peuvent supporter un consensus ralenti ou bloqué.
Des problèmes fondamentaux restaient toutefois non résolus. Le leader continuait de traiter les transactions concurrentes pour les mêmes données de compte selon le principe du premier arrivé, premier servi, sans prévention efficace du spam, et les utilisateurs ne pouvaient pas indiquer le niveau d’urgence de leurs transactions. Trois mécanismes à long terme ont été proposés comme solutions pratiques.
Adoption de QUIC : auparavant, Solana s’appuyait sur le protocole réseau UDP (User Datagram Protocol) pour envoyer les transactions via Gulf Stream des nœuds RPC au leader actuel. Rapide et efficace, UDP est toutefois sans connexion et ne propose ni contrôle de flux ni accusés de réception. Il n’existe donc aucun moyen pertinent de décourager ou de limiter les comportements abusifs. Pour contrôler le trafic réseau, le protocole d’ingestion des transactions du validateur, c’est-à-dire l’étape Fetch de la TPU, a été réimplémenté avec QUIC.
QUIC tente d’offrir le meilleur de TCP et d’UDP. Il facilite une communication rapide et asynchrone similaire à UDP, tout en offrant les sessions sécurisées et les stratégies avancées de contrôle de flux de TCP. Il permet ainsi de limiter les différentes sources de trafic pour que le réseau se concentre sur le traitement des transactions légitimes. QUIC prend également en charge des flux distincts : si une transaction est abandonnée, elle ne bloque pas les autres. QUIC a finalement été intégré au client Solana Labs avec la version 1.13.4.
Qualité de service pondérée par le stake (SWQoS) : un nouveau système donnant la priorité au trafic réseau selon le stake détenu par les validateurs a été introduit afin que ceux disposant d’un stake plus élevé puissent envoyer des transactions plus efficacement. Avec ce mécanisme, un validateur détenant 3 % du stake total peut envoyer jusqu’à 3 % de l’ensemble des paquets au leader. SWQoS sert de mécanisme de résistance aux attaques Sybil, ce qui complique la tâche des acteurs malveillants cherchant à inonder le réseau de transactions de faible qualité. Cette approche remplace l’ancien modèle du premier arrivé, premier servi, qui acceptait les transactions sans distinction et sans tenir compte de leur source.
Introduction des frais de priorité : une fois ingérées, les transactions restent en concurrence pour accéder aux données de comptes partagées. Auparavant, cette concurrence était résolue selon le simple principe du premier arrivé, premier servi, sans que les utilisateurs puissent signaler l’urgence de leurs transactions. Comme tout le monde peut soumettre des transactions, une pondération par le stake ne convient pas pour établir les priorités à ce stade. Pour résoudre ce problème, une nouvelle instruction a été ajoutée au programme Compute Budget. Elle permet aux utilisateurs de spécifier des frais supplémentaires prélevés lors de l’exécution et de l’inclusion dans un bloc. Le rapport entre ces frais et les unités de calcul détermine la priorité d’exécution d’une transaction, ce qui garantit un ordonnancement plus dynamique et guidé par le marché.
Taxe de Candy Machine sur les bots
Metaplex a rapidement introduit une taxe codée en dur de 0,01 SOL sur les transactions de mint interagissant avec le programme Candy Machine afin de lutter contre le spam généré par les bots. Ce mécanisme antispam imposait des frais minimes pour décourager les activités malveillantes sans pénaliser les utilisateurs légitimes ayant commis des erreurs accidentelles. La taxe s’appliquait dans plusieurs scénarios précis, notamment :
- Tentative de mint alors que la Candy Machine n’était pas active
- Tentative de mint alors qu’il ne restait aucun élément
- Transactions dans lesquelles le mint ou la définition de la collection n’était pas l’instruction finale
- Utilisation d’un ID de collection incorrect
- Instructions Set Collection incompatibles
- Incompatibilité entre le signataire-payeur des instructions de définition de la collection et de mint
- Transactions suspectes impliquant des programmes interdits
- Tentative de mint depuis une Candy Machine protégée par une AllowList sans détenir le token d’allowlist requis
Cette mesure économique dissuasive s’est révélée très efficace. Les fonds des snipers de mint ont été rapidement épuisés et le spam a cessé. Au cours des premiers jours, les opérateurs de bots ont perdu collectivement plus de 426 SOL.
Bug des nonces durables : juin 2022
Durée d’indisponibilité : quatre heures et demie
Problème fondamental : bug de nonce durable entraînant une défaillance du consensus
Correctifs :
- Désactivation temporaire des transactions à nonce durable
- Mise à jour Solana 1.10.23
Un bug d’exécution permettait de traiter deux fois certaines transactions à nonce durable — une fois comme transaction ordinaire et une autre comme transaction à nonce — si elles utilisaient un blockhash récent au lieu d’un nonce durable dans le champ recent_blockhash. Cela entraînait un comportement non déterministe parmi les validateurs : certains nœuds rejetaient la seconde exécution tandis que d’autres l’acceptaient. Surtout, comme plus d’un tiers des validateurs acceptaient le bloc, la majorité requise des deux tiers ne pouvait pas atteindre le consensus.
Contrairement aux transactions standard, les transactions à nonce durable n’expirent pas et nécessitent un mécanisme spécifique pour éviter une double exécution. Elles sont traitées en série à l’aide d’une valeur de nonce on-chain associée à chaque compte, qui est renouvelée à chaque traitement d’une transaction à nonce durable. Une fois renouvelée, la même transaction à nonce ne devrait plus être valide.
Pour atténuer le problème, les transactions à nonce durable ont été temporairement désactivées. Un correctif a ensuite été implémenté dans Solana 1.10.23, empêchant la double exécution en séparant les domaines des nonces et des blockhash. La mise à jour garantissait que, lors de l’avancement des comptes de nonce, le blockhash était haché avec une chaîne fixe, rendant un blockhash invalide comme valeur de nonce. Ainsi, une transaction exécutée une fois comme transaction ordinaire ne peut pas être réexécutée comme transaction durable, et inversement. De plus, un nouveau type DurableNonce a remplacé les anciennes valeurs de blockhash dans l’état du compte de nonce, renforçant la sûreté des types et empêchant des problèmes similaires à l’avenir.
Consultez notre précédent article du blog Helius pour en savoir plus sur les nonces durables et leurs usages.
Bug de bloc dupliqué : septembre 2022
Durée d’indisponibilité : huit heures et demie
Problème fondamental : un bug dans les règles de sélection des forks a entraîné une défaillance du consensus
Correctif :
- Correctif du client
Cette panne a été déclenchée par un validateur qui a produit par erreur des blocs dupliqués à la même hauteur de bloc. Cela s’est produit parce que le nœud principal du validateur et son nœud de secours sont devenus actifs simultanément, utilisant la même identité de nœud tout en proposant des blocs différents. Cette situation a persisté pendant au moins 24 heures avant la panne, période durant laquelle le réseau a correctement géré les slots de leader dupliqués du validateur.
Le cluster a fini par s’arrêter lorsque le réseau a rencontré un fork irrécupérable en raison d’un bug dans la logique de sélection des forks. Ce bug empêchait les producteurs de blocs de construire sur le bloc précédent, ce qui a provoqué une défaillance du consensus.
Les forks sont courants sur Solana et les validateurs les résolvent généralement en s’alignant sur celui qui détient la majorité des votes, c’est-à-dire le fork le plus lourd. Lorsqu’un validateur choisit le mauvais fork, il doit basculer vers le fork le plus lourd pour rester synchronisé avec le réseau. Dans ce cas, cependant, les validateurs ne pouvaient pas revenir à la banque la plus lourde si son slot correspondait à leur dernier slot voté. Ce défaut les a bloqués, empêchant le consensus de progresser et provoquant finalement l’arrêt du réseau.
Dans l’exemple ci-dessus, le validateur défectueux C produit des blocs dupliqués pour ses slots de leader 5 à 8. Lorsque le validateur G prend la relève comme leader suivant, il n’observe qu’un seul des doublons et prolonge son fork en conséquence. Cependant, le leader suivant, le validateur D, détecte les deux blocs dupliqués du validateur C et décide de les écarter, construisant plutôt son fork à partir du slot 4.
À mesure que le réseau progresse, le fork construit par le validateur G reçoit les votes de la majorité du stake et s’établit comme chaîne canonique. Constatant que son fork perd du terrain, le validateur D tente de basculer vers celui du validateur G. La transition échoue toutefois en raison d’un bug dans la logique de sélection des forks. Le problème vient du fait que l’ancêtre commun des deux forks — un bloc dupliqué au slot 5 — n’a pas été traité correctement, empêchant le validateur D de reconnaître le fork majoritaire. Le validateur D reste donc bloqué sur son propre fork, incapable de rejoindre la chaîne principale.
Le problème a été résolu après examen par l’équipe principale. Un correctif a été fusionné dans la branche master et rétroporté vers toutes les branches de publication.
Un bloc volumineux submerge Turbine : février 2023
Durée d’indisponibilité : près de 19 heures
Problème fondamental : défaillance de la logique de déduplication dans les services de transfert des shreds
Correctifs :
- Plusieurs améliorations de la logique de déduplication et du filtrage de Turbine
- Ajout d’un correctif au client forçant les producteurs de blocs à abandonner s’ils génèrent des blocs volumineux
Le service personnalisé de transfert des shreds d’un validateur a mal fonctionné et transmis un bloc exceptionnellement volumineux, composé de près de 150 000 shreds, soit plusieurs ordres de grandeur de plus qu’un bloc standard, pendant son slot de leader. Cela a submergé les filtres de déduplication des validateurs et provoqué un retransfert continu des données. Le problème s’est amplifié à mesure que de nouveaux blocs étaient produits, jusqu’à saturer le protocole.
La hausse du trafic réseau anormal a submergé Turbine, obligeant les données de blocs à être transmises via le protocole de secours Block Repair, nettement plus lent. Bien que Turbine soit conçu pour résister aux blocs volumineux en les filtrant, les services de transfert des shreds interviennent en amont de cette logique de filtrage, ce qui réduit son efficacité. Pendant la période de performances dégradées, les leaders de blocs sont automatiquement passés en mode vote uniquement, un mécanisme de sécurité dans lequel ils excluent les transactions économiques autres que les votes.
La cause profonde du problème était une défaillance de la logique de déduplication des services de transfert des shreds, qui n’empêchait pas leur retransmission redondante. De plus, le filtre de déduplication du pipeline de retransmission n’avait pas été conçu à l’origine pour empêcher les boucles dans l’arbre Turbine, ce qui a aggravé le problème.
Le réseau a été redémarré manuellement après un retour à la dernière version stable connue du logiciel des validateurs. Pour atténuer ces problèmes, Solana v1.13.7 et v1.14.17 ont amélioré la logique de déduplication, renforçant sa capacité à empêcher la saturation des filtres et garantissant des performances réseau plus robustes.
Boucle de recompilation infinie : février 2024
Durée d’indisponibilité : près de cinq heures
Problème fondamental : bug provoquant une boucle de recompilation infinie dans le cache JIT
Correctifs :
- Désactivation du chargeur historique dans la v1.17.20
Le validateur Agave compile juste-à-temps (JIT) tous les programmes avant d’exécuter les transactions qui les référencent. Pour optimiser les performances, le résultat JIT des programmes fréquemment utilisés est mis en cache, ce qui réduit les recompilations inutiles. Dans Agave v1.16, le mécanisme de cache existant, LoadedPrograms, a été remplacé par une nouvelle implémentation appelée ExecutorsCache, qui apportait plusieurs gains d’efficacité.
LoadedPrograms fournissait une vue globale du cache des programmes tenant compte des forks, réduisant la duplication des données comptables et permettant aux threads d’exécution des transactions de charger de nouveaux programmes de manière coopérative afin d’éviter les conflits de compilation. Une fonctionnalité clé de ce système consistait à suivre le slot où un programme devenait actif, appelé hauteur de slot effective, afin de détecter les invalidations du cache lorsque les données on-chain du programme étaient mises à jour.
La hauteur de slot effective de la plupart des programmes était dérivée de leur slot de déploiement, stocké dans leur compte on-chain. Toutefois, les programmes déployés avec des chargeurs historiques ne conservaient pas ce slot de déploiement dans leurs comptes. Comme solution de contournement, LoadedPrograms attribuait à ces programmes une hauteur de slot effective de zéro.
Une exception se produisait lorsqu’une instruction de déploiement était détectée, ce qui signalait que le bytecode d’un programme avait été remplacé. Dans ce cas, LoadedPrograms insérait temporairement une entrée avec la bonne hauteur de slot effective. Cependant, comme aucune transaction ne référençait jamais cette entrée, elle était très susceptible d’être évincée. Lorsqu’elle l’était, le résultat JIT était supprimé et le programme marqué comme déchargé, mais la hauteur de slot effective était conservée.
Si une transaction référençait ensuite ce programme déchargé, LoadedPrograms le recompilait et réinsérait une entrée à sa hauteur de slot effective. En temps normal, le programme devenait alors disponible pour l’exécution à l’itération suivante. Cependant, pour les programmes utilisant des chargeurs historiques, le nouveau résultat JIT recevait la hauteur de slot sentinelle de zéro et se retrouvait placé derrière l’entrée déchargée précédente. LoadedPrograms ne reconnaissait donc jamais le programme comme chargé, déclenchant une boucle de recompilation continue à chaque itération.
Dans Agave v1.16, LoadedPrograms ne prenait pas en charge le chargement coopératif, ce qui permettait d’intégrer la transaction déclencheuse dans un bloc. Ce bloc était ensuite propagé sur tout le réseau, amenant chaque validateur à le rejouer et à entrer dans la même boucle de recompilation infinie. Comme plus de 95 % du stake du cluster exécutait Agave v1.17 pendant la panne, la plupart des validateurs se sont retrouvés bloqués sur ce bloc, interrompant le réseau.
Ce bug avait été identifié la semaine précédente au cours d’une enquête sur une panne d’un cluster Devnet, et le déploiement d’un correctif était planifié. La solution retenue consistait à rétroporter les modifications vers Agave v1.17 et à supprimer immédiatement un feature gate lors du redémarrage du réseau. Cela a désactivé le chargeur historique responsable du déclenchement du bug, empêchant qu’il ne se reproduise.
Correctif coordonné d’une vulnérabilité : août 2024
Durée d’indisponibilité : aucune
Problème fondamental : hypothèse incorrecte sur l’alignement des adresses ELF
Correctifs :
- Mise à jour corrective
Le 5 août, les ingénieurs principaux d’Anza ont été alertés d’une vulnérabilité du client Agave, signalée par un chercheur externe. Un attaquant aurait pu exploiter cette faille pour faire planter les validateurs leaders, entraînant l’arrêt de tout le réseau. En réponse, les ingénieurs d’Anza ont rapidement développé un correctif, qui a ensuite été audité par plusieurs sociétés de sécurité tierces.
Les programmes Solana sont compilés avec LLVM au format Executable and Linkable Format (ELF). La vulnérabilité provenait d’une hypothèse incorrecte sur l’alignement des adresses dans les fichiers ELF générés. Si l’assainissement ELF impose généralement plusieurs contrôles d’intégrité, il ne validait pas l’alignement de la section .text. Cette lacune aurait permis à un fichier ELF conçu de manière malveillante de définir une section .text mal alignée, amenant la machine virtuelle à accéder à une adresse invalide. Cela aurait provoqué une erreur de segmentation sur l’hôte et fait planter le validateur.
Un attaquant aurait pu exploiter cette vulnérabilité comme suit :
- Créer un programme Solana malveillant utilisant l’opcode CALL_REG.
- Manipuler le fichier ELF pour désaligner la section .text.
- Déployer et invoquer le programme sur le réseau afin de faire planter les validateurs.
Processus de mise à jour corrective
Toute publication publique d’un correctif aurait immédiatement révélé la vulnérabilité à tous. Un attaquant aurait alors pu disposer de suffisamment de temps pour procéder à une rétro-ingénierie de la vulnérabilité et interrompre le réseau avant qu’une part suffisante du stake n’ait effectué la mise à niveau. Une masse critique de validateurs devait adopter tout correctif aussi rapidement que possible pour éviter ce scénario.
Le 7 août, plusieurs membres de la Solana Foundation avaient contacté des validateurs par messages privés sur différentes plateformes de communication, les informant de l’arrivée d’un correctif critique et partageant un message haché confirmant la date et l’identifiant unique de l’incident. Plusieurs membres importants d’Anza, de Jito et de la Solana Foundation ont partagé ce hash sur X, GitHub et LinkedIn pour confirmer l’authenticité du message. Exemple de hash partagé :
Le lendemain, les membres principaux ont continué à contacter les validateurs en insistant sur l’urgence et la confidentialité. À l’heure prédéterminée, le 8 août à 14 h UTC, les opérateurs de validateurs ont reçu un autre message contenant des instructions pour télécharger, vérifier et appliquer le correctif. Celui-ci était hébergé dans le dépôt Github d’un ingénieur Anza connu, et non dans le dépôt Agave principal. Les instructions comprenaient la vérification des fichiers du correctif téléchargés à l’aide des sommes de contrôle fournies.
Le 8 août à 20 h UTC, une supermajorité du stake avait été corrigée, garantissant la sécurité du réseau. La vulnérabilité et le correctif correspondant ont ensuite été rendus publics, avec un appel invitant tous les validateurs restants à effectuer la mise à niveau.
La distribution discrète du correctif et la coordination en coulisses des validateurs ont suscité des inquiétudes quant à la décentralisation de Solana. Peu après l’incident, Dan Albert, directeur exécutif de la Solana Foundation, a répondu à ces critiques lors d’une interview dans les médias.
« Je pense qu’il est important de ne pas confondre centralisation et capacité à se coordonner. Il existe 1 500 nœuds producteurs de blocs dans le monde entier, exploités par presque autant de personnes… La possibilité de communiquer volontairement avec eux, ou avec certains d’entre eux, ne doit pas être confondue avec la centralisation. »
Je pense qu’il est important de ne pas confondre centralisation et capacité à se coordonner. Il existe 1 500 nœuds producteurs de blocs dans le monde entier, exploités par presque autant de personnes… La possibilité de communiquer volontairement avec eux, ou avec certains d’entre eux, ne doit pas être confondue avec la centralisation.

Conclusion
À l’heure où nous écrivons ces lignes, Solana n’a connu aucune panne depuis plus d’un an, atteignant ainsi un jalon essentiel pour retirer la mention « bêta » de mainnet-beta. La fréquence des pannes semble diminuer à mesure que le réseau gagne en maturité, et l’introduction de Firedancer devrait accroître la diversité des clients, réduisant le risque que des bugs inconnus ou des cas limites provoquent l’arrêt complet du cluster. Certains responsables de la communauté, dont Mert Mumtaz, fondateur de Helius, prédisent toutefois que les pannes continueront. L’avenir le dira.
Un grand merci à Zantetsu (Shinobi Systems) et à OxIchigo pour leur relecture des versions précédentes de ce travail.
Ressources complémentaires
Articles associés
Abonnez-vous à Helius
Suivez les dernières actualités du développement sur Solana et recevez une notification à chaque publication


