Rejoignez-Nous sur

Bitcoin Testnet Block Storms

Block cumulative interval

News

Bitcoin Testnet Block Storms

Effets d'entraînement d'un ajustement de règle de consensus

De temps en temps, je vois quelqu'un publier publiquement une question du type "WTF se passe avec testnet en ce moment?" J'observe l'activité farfelue de testnet depuis que j'ai commencé à travailler à plein temps sur l'infrastructure Bitcoin en 2015.

Dans certains cas, les gens remarquent que les API testnet et les explorateurs de blocs sont bloqués avec leur dernier bloc trouvé il y a quelques heures ou peuvent signaler un nombre inhabituellement élevé de blocs trouvés avec un taux d'orphelins très élevé. La cause première est presque toujours la même: une activité réseau anormale due à l'un des attributs uniques de testnet.

Contexte: Reciblage des difficultés minières

Les mineurs de Bitcoin créent des blocs en résolvant (via la force brute) le preuve de travail pour leur bloc proposé. La difficulté pour l'ensemble du réseau de mineurs à résoudre un bloc est régulièrement ajustée afin de cibler un intervalle de bloc en moyenne de 10 minutes, mais chaque intervalle de bloc n'est pas exactement de 10 minutes. Il suit un processus statistique appelé processus de poisson, où des événements aléatoires se produisent avec la même probabilité dans chaque intervalle de temps. Le résultat est qu'environ 10% du temps (une fois toutes les deux heures), vous devrez attendre plus de 20 minutes pour le bloc suivant, tandis qu'environ 0,3% du temps (une fois tous les quelques jours), vous devrez attendre plus d'un heure pour un bloc. Ce n'est pas idéal pour les développeurs qui ont besoin que leurs transactions soient confirmées en temps opportun lors des tests!

Block cumulative interval

Pour rendre les tests un peu plus prévisibles, nous devons extraire les blocs de manière plus cohérente. Nous savons déjà que le pouvoir de hachage sur le testnet sera moins prévisible car il n'y a aucune incitation économique à extraire sur testnet – les pièces TBTC n'ont aucune valeur monétaire. En tant que tels, les mineurs vont et viennent au fur et à mesure que les gens testent de nouveaux matériels et logiciels d'exploitation minière.

En raison de l'imprévisibilité de la puissance de hachage et des temps de blocage, il existe une règle spéciale qui permet à un bloc d'être miné contre la difficulté minimale de 1 (et donc pratiquement instantanément sur un GPU ou un ASIC) s'il n'y a pas eu de bloc pendant 20 minutes. Cette règle est invoquée assez régulièrement sur testnet. En fait, j'ai écrit ce script pour déterminer à quelle fréquence. Il s'avère que près de 200 000 blocs (près de 12% de tous les blocs) sur testnet ont été extraits avec une difficulté de 1 après que la fenêtre de 20 minutes s'est écoulée depuis le bloc précédent.

Il convient de noter qu'en raison d'une certaine marge de manœuvre autorisée autour des horodatages de bloc, il est possible pour un mineur adversaire de définir son horodatage 20 minutes dans le futur et d'extraire un bloc à une difficulté de 1, mais il ne pourrait le faire qu'au maximum 6 fois avant d'appuyer sur la règle "2 heures dans le futur". J'ai discuté en profondeur de la sécurité d'horodatage des blocs dans ce post.

La règle unique de Testnet

Au moment de la rédaction, la logique de calcul de la difficulté (preuve de travail requise) pour le prochain bloc valide peut être trouvée ici dans pow.cpp. Nous voyons que testnet a un drapeau spécial, fPowAllowMinDifficultyBlocks, définie sur true, qui modifie la logique qui est exécutée lors du calcul de la difficulté du bloc suivant.

Screenshot from 2020 04 03 18 21 00

Si nous remontons les modifications apportées à ce bloc de code, nous voyons qu'il a été initialement écrit par Gavin Andresen fin 2011:

Modifications du calcul de la difficulté Testnet, pour entrer en vigueur le 15 février 2012 par gavinandresen · Pull Request # 686 · bitcoin / bitcoin

Autoriser l'extraction de blocs de difficulté minimale si 20 minutes se sont écoulées sans extraire un bloc de difficulté normale.
Les règles normales s'appliquent cependant tous les blocs de 2016, il peut donc y avoir un bloc très lent à confirmer …

528860

Nous constatons que plusieurs contributeurs ont donné leur avis sur ce changement et mentionné des problèmes qui devaient être corrigés. Notamment, Matt Corallo a remis en question le placement particulier de cette nouvelle logique:

Pourquoi à l'intérieur du contrôle d'intervalle? Si nous sommes à l'aube d'un intervalle, pourquoi ne devrions-nous pas autoriser les blocs min-diff?

Bien qu'il semble que Matt était sur quelque chose, il semble qu'aucun des 5 développeurs qui ont participé à cette demande de pull n'a remarqué un cas de bord substantiel créé par ce code. C'est tout à fait compréhensible parce que j'ai dû lire la logique plusieurs fois moi-même tout en connaissant déjà l'effet secondaire avant qu'il ne soit clair comment cela se passait.

Interactions imprévues

Tout comme le réseau bitcoin normal, testnet recalcule également la difficulté d'extraction tous les blocs de 2016. cependant, la logique de calcul de la nouvelle difficulté a été écrite avec l'hypothèse que les blocs précédents ont tous été validés par rapport au même calcul de cible de difficulté et donc il est sûr de continuer cette série de calculs de difficulté. Il s'agit d'une logique implicite similaire à la façon dont la limite de 21 millions de BTC de Bitcoin est assurée – un nœud ne résume jamais réellement toutes les valeurs UTXO mais suppose plutôt que chaque bloc précédent a été validé pour ne pas créer plus que la subvention autorisée, donc la somme doit implicitement être inférieur à la limite totale.

Ainsi, sur testnet lorsque le bloc avant le reciblage (bloc # 2015, # 4031, etc.) est un bloc de difficulté 1 en raison de la règle spéciale de difficulté minimale, la logique de reciblage pour le bloc suivant s'exécutera en supposant que la difficulté pour l'ensemble des blocs 2015 précédents a été de 1! Et comme un reciblage est limité pour ne jamais augmenter la "difficulté actuelle" de plus de 4X, la nouvelle difficulté sera recalculée pour être 1, 2, 3 ou 4.

Screenshot from 2020 04 04 08 53 21
Ici, nous pouvons voir que l'ajustement de la difficulté est basé sur la difficulté du bloc précédent.

Au moment de l'écriture, testnet a 1 694 700 blocs, ce qui signifie qu'il y a eu 840 retargets de difficulté. On peut voir ça 99 de ces difficultés retargets ont entraîné la réinitialisation "permanente" de la difficulté à 1. C'est exactement le nombre de retargets que nous attendons car c'est également 12% de tous les retargets, ce qui correspond au taux auquel la règle spéciale de difficulté testnet est déclenchée. Donc, alors que théoriquement, un mineur de testnet contradictoire aurait pu facilement attendre que la hauteur du bloc atteigne 1 bloc avant un recalcul de difficulté, puis a miné un bloc de difficulté 1 avec un horodatage de 20 minutes à l'avenir afin de déclencher une réinitialisation de la difficulté, il ne le fait pas semblent que cela s'est produit.

Screenshot from 2020 04 03 18 47 11
https://testnet.smartbit.com.au/charts/difficulty?from=2019-10-3&to=2020-4-3

Nous pouvons voir que cela crée des fluctuations de volatilité extrêmes dans la difficulté sur testnet, ce qui la fait se déplacer jusqu'à 7 ordres de grandeur dans les deux sens.

Explorateurs de rupture de bloc et autres services

Pourquoi la difficulté de réinitialisation provoque-t-elle de tels conflits avec les services exécutés sur testnet? C'est parce qu'une fois que la difficulté est remise à 1, même un ASIC bon marché comme un S5 peut miner plusieurs blocs par seconde. Comme vous pouvez l'imaginer, si vous avez alors des dizaines de mineurs testnet crachant des blocs sur le réseau, il y aura pas mal de conflits.

Lorsqu'un nœud Bitcoin reçoit un nouvel ensemble de blocs en conflit qui ont plus de preuves de travail que ce qu'il considère être la meilleure chaîne actuelle, il doit effectuer une réorganisation de la chaîne de blocs. Cela implique de faire reculer séquentiellement la chaîne actuelle de blocs et de transactions, puis d'appliquer la nouvelle chaîne – c'est un processus très intensif qui se produit très rarement sur le réseau principal et presque jamais avec plus d'un bloc à la fois. De nombreux nœuds ou services naïvement écrits effectueront simplement cette opération en mémoire comme une amélioration des performances, mais lorsqu'ils sont servis avec une réorganisation qui contient des centaines ou des milliers de blocs, la machine peut manquer de mémoire et provoquer le crash du nœud ou du service, le gelant ainsi au dernier bloc traité avec succès. Il est également possible que le service n'ait pas de verrou autour de cette opération et s'il est en train d'effectuer une réorganisation alors qu'une autre réorganisation se produit, le service gèlera / bloquera / corrompra les données.

Screenshot from 2020 04 02 11 29 51
https://testnet.smartbit.com.au/charts/blocks?from=2015-4-2&to=2020-4-2

Nous pouvons voir que, pendant une journée normale, environ 144 blocs sont frappés, si une difficulté réinitialisée à la difficulté minimale se produit, elle entraîne l'extraction de plus de 10 000 blocs! C'est un bloc toutes les 8 secondes!

Résoudre le problème

Bien qu'il soit trivial de patcher la logique afin qu'elle ne déclenche pas de difficulté permanente, la réinitialisation à la difficulté minimale est un code critique consensuel. Un tel changement nécessiterait un hard fork du réseau., Bien qu'il s'agisse de testnet, il n'est donc pas aussi important que Mainnet. Il serait toujours difficile pour de nombreuses entreprises et développeurs de coordonner une mise à jour.

Cependant, ce serait un effort inutile car un testnet amélioré est en cours de développement depuis un certain temps. Karl-Johan Alm travaille sur BIP 325 pour ajouter des fonctionnalités permettant aux développeurs d'exécuter des réseaux de test "signet" qui n'utilisent pas du tout le minage, mais utilisent plutôt une fédération de signataires de blocs. Vous pouvez en savoir plus sur Signet sur Magazine Bitcoin.

Plats à emporter

Il est difficile de voir les cas marginaux, en particulier autour d'une logique implicite plutôt qu'explicite. Une telle logique ajoute à la difficulté de revoir la sécurité du code car le réviseur doit garder à l'esprit toutes les hypothèses formulées par d'autres parties de la base de code lors de la révision du code modifié.

Il est également difficile de prédire l'avenir et d'écrire ainsi du code à l'épreuve du temps. Au moment où ce changement de code a été effectué, la difficulté du réseau principal Bitcoin n'était que de 1 million et les ASIC n'avaient même pas été inventés. Au moment de la rédaction du présent document, la difficulté du réseau principal est de plus de 15 000 milliards et même la difficulté de testnet dépasse souvent 13 millions. Les fluctuations de difficulté insensées n'ont probablement même pas traversé l'esprit des développeurs à ce moment.

Heureusement, ce bogue particulier n'affecte que testnet, qui n'a aucune valeur monétaire, mais il cause des "dommages" dans le sens où les développeurs comme moi doivent alors passer du temps à réparer l'infrastructure. Cela montre à quel point les développeurs de protocoles doivent être prudents et conservateurs lorsqu'ils modifient un code critique consensuel. Il s'agit d'un code essentiel à la mission qui peut avoir des ramifications de grande envergure et il devrait être abordé à partir d'un état d'esprit semblable à l'ingénierie aérospatiale en raison des conséquences potentiellement catastrophiques, même d'un défaut "mineur".

challenger
Le résultat d'un joint torique défectueux





Traduction de l’article de Jameson Lopp : Article Original

BlockBlog

Le Meilleur de l'Actualité Blockchain Francophone & Internationale | News, Guides, Avis & Tutoriels pour s'informer et démarrer facilement avec Bitcoin, les Crypto-Monnaies et le Blockchain. En Savoir Plus sur L'Équipe BlockBlog

Commenter cet Article

Commenter cet Article

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Plus dans News

Top
commodo efficitur. sed sem, venenatis ipsum