de
Zurück zur Liste

Wie eine einzelne Transaktion das Ethereum-Netzwerk in Verwirrung stürzte

source-logo  bitcoinblog.de 13 November 2020 14:30, UTC

Gestern gab es einen Konsens-Fehler in Ethereum: Das Netzwerk war sich nicht länger einig, welche Blöcke gültig sind. Das stiftete viel Verwirrung, verursachte aber keine Verluste. Man könnte sagen: Der Worst Case ist eingetreten – war aber doch recht harmlos.

Für die Ethereum-Szene war gestern ein aufregender Tag. Sie erlebte einen jener Momente, in denen der Worst Case eintritt: Es beginnt mit Verwirrung, weil etwas passiert, das nicht passieren darf. Dann legt sich der Nebel, man sieht, was wirklich los ist, und viele klugen Köpfe müssen hellwach sein, um den Schaden aus der Welt zu bringen.

Als einer der ersten fiel dem Blockexplorer Blockchair auf, das etwas nicht stimmte. Er twitterte:

We're experiencing an issue with our #Ethereum explorer and working on a fix. It seems like there is a chain split, and some nodes (including ours and some miners') are stuck on a minority chain. pic.twitter.com/q7qo3DjHS4

— Blockchair (@Blockchair) November 11, 2020

Zu deutsch: Wir haben ein Problem mit Ethereum. Es sieht aus, als sei es zu einem Chainsplit gekommen, und einige Knoten sind auf der Minderheitenchain stecken geblieben.

Ein Chainsplit, also eine Spaltung der Kette, ist ziemlich genau das, was einer Blockchain nicht passieren sollte. Sie verliert den Konsens über die Historie; die einen Nodes denken, das sei passiert, und die anderen, jenes. Dabei gibt es die Blockchain genau darum: um zu verhindern, dass sich Nodes in einem dezentralen Netzwerk uneinig über die Vergangenheit sind.

Das klingt also nach einem ziemlich üblen, extrem ernsten Problem.

Nikita Zhavoronkov, der Blockchair betreibt, erklärt kurz darauf den Error:

Here’s the error we (and some others I know of) get:

########## BAD BLOCK #########
<…>
Error: invalid merkle root (remote: 57cc91ee8b91b956592a27b14386abc2aba723b5f4f9e5d3181ace6b5d3cd433 local: 1f9ee59bfa683a25c7a15b626995a3ad7c58c571b40df96eea31e5c5eed9732d)

— Nikita Zhavoronkov (@nikzh) November 11, 2020

Der Node von Blockchair hat einen Block abgelehnt, weil der „Merkle-Root“, zu deutsch, die Wurzel des Hashbaums, nicht valide ist. Diese Wurzel ist quasi ein Destillat des Blocks, den die Miner an die Blockchain anhängen. Sie erlaubt es allen Knoten, zu prüfen, ob der Block gültig ist. Wenn die Prüfung scheitert, lehnen sie den Block ab. Das ist eine vollkommen richtige Reaktion.

Nicht richtig ist es aber, wenn die einen Knoten, so wie der von Blockchair, einen Block ablehnen, die anderen ihn aber akzeptieren.

Der Bug zieht weite Kreise durchs ganze Ökosystem

Péter Szilágy, einer der führenden Leitentwickler von Ethereum, empfiehlt Nikita, die Software des Nodes, Geth, zu aktualisieren. Nikita meint zwar zuerst, dass der Backup-Node von Blockchair dieselbe Version benutzt, wie der andere, ohne das Problem zu haben. Er vermutet daher ein globales Problem, auch da Infura und andere Knoten down sind. Nachdem er Geth aktualisiert hat, funktioniert Blockchair allerdings wieder.

Tatsächlich tauchten kurz danach Berichte auf, dass Börsen, die Infura benutzen, Auszahlungen von Ether und ERC-Token ausgesetzt haben. Infura ist eine Art Infrastrukturanbieter bei Ethereum: Ein Netzwerk von Knoten, die eine API bereitstellen, über die andere in Echtzeit zuverlässige Informationen von der Ethereum-Blockchain bekommen.

Böse Zungen behaupten, Ethereum laufe zentralisiert auf den Servern von Infura, was nicht ganz unberechtigt ist, wenn man sich anschaut, wen Infura zu seinen Kunden zählt: UniSwap, Compound, Maker, um nur ein paar zu nennen; zudem verbindet sich die beliebte Wallet MetaMask standardmäßig mit Infura. Der Fehler gestern zeigte nun, WIE abhängig Ethereum von Infura ist. Nicht nur Wallets und dApps benutzen die API, sondern auch einige Börsen, etwa Binance, Bithumb, Upbit and Crypto.com – alles kleine kleinen, unbedeutenden Handelsplätz, sondern große Plattformen, die an manchen Tagen Milliarden von Dollar an Volumen umsetzen.

Infura bestätigte, ein Problem zu haben, und vermeldete auf der Status-Seite den ersten „Major Outage“, also den ersten großen Ausfall, überhaupt.

Aber was war passiert? Ein Hack? Ein Bug? Weshalb waren die Knoten von Infura auf der falschen Blockchain gelandet?

Der komplexe Grund, weshalb der Konsens-Fehler seit rund einem Jahr geschlummert hat

Die Erkärung ist ziemlich komplizierter. Leider. Péter Szilágy erklärt in einem Post-Mortem-Post, was genau geschehen ist: Schon die im November 2019 veröffentlichte Version von Geth, 1.9.7, hat einen Konsens-Bug eingeführt, indem sie EIP-211 unter bestimmten, sehr speziellen Bedingungen verletzte.

Jeder Konsens-Bug kann einen Split der Blockchain verursachen; dieser aber scheint eher esoterisch gewesen zu sein, da er weder zum Chainsplit führte noch jemandem zeitnah auffiel. Erst ein Dreivierteljahr später, im Juli 2020, entdeckte ein Entwickler den Fehler. Der wurde daraufhin mit Geth 1.9.17 heimlich behoben.

Die Ethereum-Entwickler hatten also schon im Juli 2020 das eingeführt, was man gemeinhin eine „Hardfork“ nennt: Eine Änderung der Regeln mit einer neuen Version, so dass diese unter Umständen nicht mehr mit der alten Version kompatibel ist. Anders als viele meinen, führt eine Hardfork aber nicht sofort zum Split, sondern erst dann, wenn das entsprechende Ereignis eintritt – welches im Fall des EIP-211-Bugs so esoterisch ist, dass ich nicht mal im Ansatz verstehe, worum es überhaupt geht (wer will, möge sich selbst über EUP-211 informieren).

Wie auch immer: Geth 1.9.17, veröffentlich im Juli, war in einem bestimmten Aspekt nicht länger kompatibel mit den vorhergegangenen Versionen von Geth. Péter Szilágy drückt es so aus: Die Geth-Entwickler haben versehentlich einen Bug eingeführt und ihn nun behoben. Wenn man einen Bug keine „Konsens-Änderung“ nenne, sei auch der Fix keine.

Allerdings haben nicht alle Knoten das Update zu 1.9.17 mitgemacht. Etwa Blockchair. Oder auch Infura, wie der API-Anbieter erklärt: Man habe Geth 1.9.9 und 1.9.13 für einige „interne Systeme“ benutzt.

Gestern Morgen nun geschah es: Eine Transaktion hat das Konsens-Problem getriggert. Die Transaktion hat das vermutlich absichtlich gemacht, wurde also nur geschrieben, um den Fehler auszunutzen. Zumindest legt Szilágys Post das nahe, auch wenn man nicht weiß, wer dies weshalb getan hat.

Die Folge war, dass ein Knoten von Blockchair einen Block ablehnte, da dieser nach den Konsensregeln von Geth < 1.9.17 ungültig war. Auch die Knoten der „internen Systeme“ von Infura hörten auf, die Blöcke zu synchronisieren. Die Cloud-Architektur von Infura ist so komplex, dass das gesamte System zwar an sich live blieb, aber die API, von der so viele Plattformen abhängen, herunterfuhr.

Wenige Stunden später hatte Infura die Knoten aktualisiert und die Blockchain wieder synchronisiert. Auch Blockchair war wieder auf dem neuesten Stand. Die Börsen und Plattformen, die Infura benutzten, nahmen wieder Kontakt zur Ethereum-Blockchain auf.

Alles wurde schnell und professionell geregelt. Doch was bleibt von dem Bug?

Wenn alle alles richtig machen kann man nichts besser machen

Aus nichts lernt man so gut wie aus Fehlern und Unglücksfällen. Das trifft auch auf diesen Bug zu.

Zunächst einmal finden die Beteiligten, dass sie alles richtig gemacht haben, was eine geradezu verzweifelte und resignierende Unterwerfung unter die komplexe Wirklichkeit ist. Péter Szilágy erklärt ausführlich und reflektiert, weshalb man den Bug heimlich gefixt habe, weshalb das Vorgehen (lange) funktioniert habe, und dass die Entwickler anderer Kryptowährungen es ebenso handhaben. In einem dezentralen Netzwerk brauchen Updates Zeit. Daher gibt es keine Alternative zu einem heimlichen Fix eines schlimmen Bugs.

Auch Infura hat gute Gründe, alte Versionen von Geth parallel laufen zu lassen: Um zu verhindern, dass neu eingeführte Änderungen oder Bugs – kleine Bugs – die Infura-Cloud stören, sind die Entwickler mittlerweile sehr vorsichtig und gründlich mit Upgrades. Neue Versionen werden ausführlich getestet und an die hauseigene, auf Cloud-Performance getrimmte Version angepasst. Natürlich führt man Konsens-ändernde Updates zeitiger ein, doch das Team von Geth habe Infura nicht informiert, dass Version 1.9.17 ein solches Update enthalte – was auch richtig so sei: „Wir haben zwar einen guten Draht zum Geth-Team, haben aber niemals erwartet, irgendeine besondere Behandlung oder Zugang zu Insiderinformationen zu genießen. Keine Börse, kein Miner, kein API-Provider sollte anders behandelt werden als ein einzelner Betreiber eines Knotens.“

Es wurde also alles richtig gemacht – und zwar von allen. Der Vorfall hat weder einen Schuldigen noch einen Fehler. Es gibt so gut wie nichts, was man tun kann, um ihn in Zukunft zu verhindern. Man kann nur (noch) wacher und aufmerksamer sein.

Weniger zentralisiert als gefürchtet

Es bleibt aber mehr als Resignation. Viel mehr. Im Grunde gibt der Bug auch einen Anlass zu unerhörtem Optimismus.

Denn erstens ist der Worst Case geschehen – ein Hacker konnte absichtlich die Ethereum-Chain spalten – und es ging – überhaupt nichts zu Bruch. Keine Tasse, kein Teller ist zersprungen, kein Bruchstück eines Ethers oder eines Tokens ging verloren. Einige Börsen und einige Plattformen haben für einige Stunden den Kontakt zur Blockchain verloren, Metamask hat partiell nicht richtig funktioniert. Das war’s. Es ist nicht so, dass man das jeden Tag haben will – aber auch nicht so, dass die Welt oder auch nur ein Acker untergeht.

Zweitens ist die Sache mit der Zentralisierung wohl doch nicht so schlimm wie gedacht. Geth, die führende Implementierung von Ethereum, hat einen Bug eingeführt. Wenn man sagt, der Code sei das Protokoll, wie es bei Bitcoin zum Teil gesagt wird, wo es nur eine einzige Implementierung gibt, würde das bedeuten, dass die Entwickler keinen Bug verbrochen, sondern das Konsens-Protokoll verändert haben. So wäre es in einem zentralisierten System. Doch es war für die Geth-Entwickler keine Sekunde lang eine Frage, dass sie ihre Software an den Konsens der anderen Knoten anzupassen haben. Das, was „Konsens“ ist, entscheidet weiterhin nicht ein Team von Entwicklern, egal wie wichtig ihre Software ist.

Auch eine übermächtige Cloud-Infrastruktur wie Infura bestimmt nicht den Konsens. Ein Teil von Infura hat aufgehört, dieselbe Sicht auf die Vergangenheit zu haben wie der Rest des Netzwerks. Doch an keiner Stelle war es überhaupt eine Frage, wer sich irrt und wer nicht. Es war jederzeit glasklar, dass Infura etwas falsch verstanden hat und die anderen Recht haben.

Selbst wenn die Personen hinter Geth und Infura die Absicht hätten, den Konsens zu ändern – es wäre gar nicht möglich. Das Ethereum-System hat zu viele Checks und Balances, zu viele Parteien, die mitsprechen können: Die Miner, die die Blöcke an die Blockchains anhängen, die Entwickler der verschiedenen Implementierungen, die Betreiber von Blockexplorer, die vielen Börsen, die Ethereum listen, die Ethereum Foundation und noch viele mehr.

Es ist schwierig, könnte man sagen, etwas dezentral zu machen. Aber es ist ebenso schwierig, wenn nicht unmöglich, ein System wieder zu zentralisieren, sobald es einmal wirklich dezentral war.

bitcoinblog.de