Mit diesem Blog -Beitrag ist es beabsichtigt, eine schwerwiegende Bedrohung gegen die Ethereum -Plattform offiziell offenzulegen, was eine klare und gegenwärtige Gefahr war, bis die Berliner Hardforks.
Zustand
Beginnen wir mit einem Hintergrund zu Ethereum und Staat.
Der Ethereum-Staat besteht aus einem Patricia-Merkle-Trie, einem Präfixbaum. Dieser Beitrag wird nicht zu viel detailliert eingehen, genügt zu sagen, dass die Zweige in diesem Baum dichter werden, wenn der Staat wächst. Jedes hinzugefügte Konto ist ein weiteres Blatt. Zwischen der Wurzel des Baumes und dem Blatt selbst gibt es eine Reihe von “mittleren” Knoten.
Um ein bestimmtes Konto oder “Blatt” in diesem riesigen Baum nachzuschlagen, müssen irgendwo in der Größenordnung von 6-9 Hashes über Zwischenknoten von der Wurzel gelöst werden, um schließlich den letzten Hash zu lösen, der zu den Daten führt, nach denen wir gesucht haben.
In klarer Hinsicht: Immer wenn eine Trie-Suche durchgeführt wird, um ein Konto zu finden, werden 8-9-Resolve-Operationen durchgeführt. Jede Auflösungsoperation ist eine Datenbank -Lookup, und jede Datenbank -Lookup kann eine beliebige Anzahl von tatsächlichen Festplattenoperationen sein. Die Anzahl der Festplattenoperationen ist schwer abzuschätzen, aber da die Trie -Tasten kryptografische Hashes (Kollisionsbeständigkeit) sind, sind die Schlüssel “zufällig”, was den genauen schlechtesten Fall für eine Datenbank treffen.
Als Ethereum gewachsen ist, war es notwendig, die Gaspreise für Operationen zu erhöhen, die auf den Trie zugreifen. Dies wurde in durchgeführt Mandarine Pfeife am Block 2.463.000 Im Oktober 2016, darunter auch EIP 150. EIP 150 hob bestimmte Gaskosts aggressiv an und führte nach den sogenannten “Shanghai -Angriffen” eine ganze Reihe von Veränderungen vor, um vor DOS -Angriffen zu schützen.
Eine weitere solche Erhöhung wurde in der durchgeführt Istanbul Upgrade bei Block 9.069.000 im Dezember 2019. In diesem Upgrade, EIP 1884 wurde aktiviert.
EIP-1884 führte die folgende Änderung vor:
- Schlampen ging von 200 Zu 800 Gas,
- GLEICHGEWICHT ging von 400 Zu 700 Gas (und ein billigerer Selbstbalance) wurde hinzugefügt,
- ExtcodeHash ging von 400 Zu 700 Gas,
Das Problem (en)
Im März 2019 machte Martin Swende einige Messungen der EVM -Opcode -Leistung. Diese Untersuchung führte später zur Schaffung von EIP-1884. Ein paar Monate vor EIP-1884 Live, die Zeitung Zerbrochenes Messgerät wurde veröffentlicht (September 2019).
Zwei Ethereum -Sicherheitsforscher – Hubert Ritzdorf und Matthias Egli – haben sich mit einem der Autoren hinter dem Papier zusammengetan; Daniel Perez und “Waffen” einen Exploit, den sie der Ethereum Bug Bounty unterzogen haben. Dies war am 4. Oktober 2019.
Wir empfehlen Ihnen, die zu lesen Vorlage Vollständig ist es ein gut geschriebener Bericht.
Auf einem Kanal, der sich für die Sicherheit des Klienten widmet, wurden Entwickler von Geth, Parity und Aleth am selben Tag über die Einreichung informiert.
Die Essenz des Exploits ist es, zufällige Trie -Lookups auszulösen. Eine sehr einfache Variante wäre:
jumpdest ; jump label, start of loop gas ; get a 'random' value on the stack extcodesize ; trigger trie lookup pop ; ignore the extcodesize result push1 0x00 ; jump label dest jump ; jump back to start
In ihrem Bericht führten die Forscher diese Nutzlast gegen Knoten durch, die mit dem Mainnet synchronisierten ETH_CALLund dies waren ihre Zahlen, wenn sie mit ausgeführt werden 10 m Gas:
- 10 m Gasnutzung verwenden ExtcodeHash (bei 400 Gas)
- 10 m Gasnutzung verwenden Extcodieren (bei 700 Gas)
Wie deutlich offensichtlich, wirkten sich die Veränderungen in EIP 1884 definitiv auf die Verringerung der Auswirkungen des Angriffs aus, aber es war bei weitem nicht ausreichend.
Dies war kurz vor Devcon in Osaka. Während der DevCon wurde die Kenntnis des Problems unter den Mainnet -Client -Entwicklern geteilt. Wir trafen uns auch mit Hubert und Mathias sowie Greg Markou (von Chainsafe – die an usw. arbeiteten). ETC -Entwickler hatten auch den Bericht erhalten.
Als 2019 zu Ende ging, wussten wir, dass wir größere Probleme hatten, als wir zuvor erwartet hatten, wo böswillige Transaktionen in der Minute zu Blockzeiten führen konnten. Um die Probleme weiterzugeben: Die Dev-Community freute sich bereits über EIP-1884, die Hade bestimmte Vertragsströme machte, und Benutzer und Bergleute waren für erhöhte Blockgasgrenzen schmerzlich jucken.
Darüber hinaus nur zwei Monate später, im Dezember 2019, Parity Ethereum angekündigt Ihre Abreise von der Szene und Openethereum übernahm die Wartung der Codebasis.
Es wurde ein neuer Kundenkoordinierungskanal erstellt, bei dem Geth, Nethermind, Openethereum- und Entu -Entwickler weiterhin koordinierten.
Die Lösung (en)
Wir stellten fest, dass wir einen zweigleisigen Ansatz durchführen müssten, um diese Probleme zu lösen. Ein Ansatz wäre, am Ethereum -Protokoll zu arbeiten und dieses Problem irgendwie auf der Protokollschicht zu lösen. bevorzugt, ohne Verträge zu brechen, und bevorzugt, ohne das „gute“ Verhalten zu bestrafen, aber dennoch zu verhindern, Angriffe zu verhindern.
Der zweite Ansatz wäre über Software -Engineering, indem die Datenmodelle und Strukturen innerhalb der Clients geändert werden.
Protokollarbeit
Die erste Iteration des Umgangs mit diesen Arten von Angriffen ist Hier. Im Februar 2020 wurde es offiziell als gestartet als EIP 2583. Die Idee dahinter ist, jedes Mal, wenn ein Trie -Lookup einen Fehlschlag verursacht, einfach eine Strafe hinzuzufügen.
Peter fand jedoch eine Arbeit für diese Idee – den Angriff “geschützter Relais” – bei dem eine Obergrenze (ca. ~ 800) darauf stellt, wie groß eine solche Strafe effektiv sein kann.
Das Problem mit Strafen für Fehler ist, dass die Suche zuerst erfolgen muss, um festzustellen, dass eine Strafe angewendet werden muss. Wenn jedoch nicht genügend Gas für die Strafe übrig ist, wurde ein unbezahlter Verbrauch durchgeführt. Obwohl dies zu einem Wurf führt, können diese Zustandslesungen in verschachtelte Anrufe eingewickelt werden. Erlaubt dem Außenberechtigten, den Angriff weiter zu wiederholen, ohne die (vollständige) Strafe zu zahlen.
Aus diesem Grund wurde der EIP aufgegeben, während wir nach einer besseren Alternative suchten.
- Alexey Akhunov erkundete die Idee von Öl – eine sekundäre “Gasquelle” GasDa es für die Ausführungsschicht unsichtbar wäre und Transaktions-Global-Rückkehrungen verursachen könnte.
- Martin schrieb einen ähnlichen Vorschlag über Karmaim Mai 2020.
Vitalik Buterin war während dieser verschiedenen Systeme iteriert und schlug vor, nur die Gaskosten zu erhöhen und Zugriffslisten aufrechtzuerhalten. Im August 2020 begannen Martin und Vitalik zu iterierten, was werden sollte EIP-2929 und sein Begleiter-EIP, EIP-2930.
EIP-2929 hat viele der früheren Probleme effektiv gelöst.
- Im Gegensatz zu EIP-1884, die bedingungslos die Kosten erhöhte, erhöhte es stattdessen nur die Kosten für Dinge, die noch nicht zugegriffen wurden. Dies führt zu einem bloßen Erhöhung der Unterprozent in Nettokosten.
- Zusammen mit EIP-2930 wird auch keine Vertragsströme gebrochen,
- Und es kann weiter mit erhöhten Gaskostern eingestellt werden (ohne Dinge zu brechen).
Am 15. April 2021 gingen beide mit dem live live Berlin Upgrade.
Entwicklungsarbeit
Peters Versuch, diese Angelegenheit zu lösen, war Dynamische Zustands -Schnappschüsseim Oktober 2019.
Ein Schnappschuss ist eine sekundäre Datenstruktur zum Speichern des Ethereum -Zustands in einem flachen Format, das während des Live -Betriebs eines Geth -Knotens vollständig online erstellt werden kann. Der Vorteil des Snapshots besteht darin, dass es als Beschleunigungsstruktur für staatliche Zugriffe fungiert:
- Anstatt zu tun O (log n) Festplatten liest sich (X LevelDB -Overhead), um auf einen Konto- / Speicherslot zuzugreifen, kann der Snapshot direkt bereitstellen. O (1) Zugangszeit (X Leveldb -Overhead).
- Der Snapshot unterstützt Konto- und Speicher -Iteration unter O (1) Komplexität pro Eintrag, mit der Remote -Knoten auf sequentielle Zustandsdaten signifikant billiger abgerufen werden als zuvor.
- Das Vorhandensein des Snapshots ermöglicht auch exotischere Anwendungsfälle wie die Offline-Bekämpfung des Staatstries oder die Migration auf andere Datenformate.
Der Nachteil des Snapshots ist, dass die RAW -Konto- und Speicherdaten im Wesentlichen dupliziert werden. Im Fall von Mainnet bedeutet dies ein Extra 25 GB des SSD -Raums verwendet.
Die dynamische Snapshot -Idee war bereits Mitte 2019 begonnen, um hauptsächlich ein Enabler für zu sein Schnappnahme Synchronisation. Zu dieser Zeit gab es eine Reihe von “großen Projekten”, an denen das Geth -Team arbeitete.
- Offline -Staat -Schnitt
- Dynamische Schnappschüsse + Snap Sync
- Les State Distribution über Sharded State
Es wurde jedoch beschlossen, Snapshots vollständig zu priorisieren und die anderen Projekte vorerst zu verschieben. Diese legten die Grundarbeit für das, was später geworden war Snap/1 Synchronisation Algorithmus. Es wurde im März 2020 zusammengeführt.
Mit der in die Wildnis freigesetzten “Dynamic Snapshot” -Funktion hatten wir ein bisschen Raum. Falls das Ethereum -Netzwerk mit einem Angriff getroffen werden würde, wäre es schmerzhaft, ja, aber es wäre zumindest möglich, Benutzer darüber zu informieren, dass es den Schnappschuss aktiviert. Die gesamte Snapshot -Generation würde viel Zeit in Anspruch nehmen, und es gab noch keine Möglichkeit, die Schnappschüsse zu synchronisieren, aber das Netzwerk konnte zumindest weiter funktionieren.
Die Fäden zusammenbinden
Im März-April 2021 die Snap/1 Das Protokoll wurde in Geth eingeführt, sodass es mit dem neuen Snapshot-basierten Algorithmus synchronisiert wurde. Obwohl es immer noch nicht der Standard-Synchronisierungsmodus ist, ist dies ein (wichtiger) Schritt, um die Schnappschüsse nicht nur als Angriffsschutz zu machen, sondern auch als wesentliche Verbesserung für Benutzer.
Auf der Protokollseite die Berlin Das Upgrade ereignete sich April 2021.
Einige Benchmarks, die in unserer AWS -Überwachungsumgebung hergestellt wurden, finden Sie unten:
- Präberlin, keine Schnappschüsse, 25m Gas: 14,3s
- Präberlin, mit Schnappschüssen, 25m Gas: 1,5s
- Postberlin, keine Schnappschüsse, 25m Gas: ~ 3.1s
- Postberlin, mit Schnappschüssen, 25m Gas: ~ 0,3s
Die (rauen) Zahlen geben das an Berlin reduzierte die Effizienz des Angriffs durch 5xund Schnappschuss reduziert es durch 10xinsgesamt zu a 50x Auswirkungsreduzierung.
Wir schätzen, dass derzeit auf dem Mainnet (15m Gas) Blöcke erstellt werden können, die dauern würden 2,5-3s auf a ausführen Geth Knoten ohne Schnappschüsse. Diese Zahl verschlechtert sich weiter (für Nicht-Snapshot-Knoten), wenn der Zustand wächst.
Wenn Rückerstattungen verwendet werden, um den effektiven Gasverbrauch innerhalb eines Blocks zu erhöhen, kann dies durch den Faktor von (max) weiter verschärft werden. 2x . Mit EIP 1559Die Blockgasgrenze hat eine höhere Elastizität und erlaubt eine weitere 2x (Die Elastizität_Multiplier) in vorübergehenden Ausbrüchen.
Was die Machbarkeit der Ausführung dieses Angriffs betrifft; Die Kosten für einen Angreifer, einen vollen Block zu kaufen15 m Gas bei 100gwei Ist 1.5 Äther).
Warum jetzt offenlegen?
Diese Bedrohung ist seit langem ein “offenes Geheimnis” – sie wurde mindestens einmal öffentlich bekannt gegeben und wurde in ACD -Anrufen mehrmals ohne ausdrückliche Details verwiesen.
Da das Berliner Upgrade jetzt hinter uns liegt und dass Geth -Knoten standardmäßig Schnappschüsse verwenden, schätzen wir, dass die Bedrohung niedrig genug ist, dass Transparenz übertrumpft, und es ist an der Zeit, die Arbeiten hinter den Kulissen vollständig zu veröffentlichen.
Es ist wichtig, dass der Community die Möglichkeit hat, die Argumentation hinter Änderungen zu verstehen, die sich negativ auf die Benutzererfahrung auswirken, z. B. die Erhöhung der Gaskosten und die Begrenzung der Rückerstattungen.
Dieser Beitrag wurde von Martin Holst Swende und Peter Szilagyi 2021-04-23 geschrieben. Es wurde mit anderen in Ethereum ansässigen Projekten unter 2021-04-26 geteilt und wurde 2021-05-18 öffentlich bekannt gegeben.

