Autor: Tia, Techub News

Blockchain hat aufgrund ihres dezentralisierten Designs Effizienz geopfert, daher ist die Verbesserung der Ausführungsgeschwindigkeit eines der dringendsten Probleme. Die „Ausführungsebene“ der Blockchain ist der entscheidende Teil, der jede Transaktion verarbeitet und sie in die Kette einfügt. Um die Verarbeitungsfähigkeit zu beschleunigen, wird die Verbesserung der Ausführungsebene zu einer der Kernstrategien, wobei die parallele Ausführung einen wichtigen Durchbruch in diesem Bereich darstellt.

Traditionelle Blockchains verarbeiten Transaktionen normalerweise sequenziell, was die Transaktionsgeschwindigkeit erheblich einschränkt, insbesondere in stark frequentierten Netzwerken, wo es zu Staus kommen kann. Durch parallele Ausführung können mehrere Transaktionen gleichzeitig bearbeitet werden, was die Ausführungseffizienz erheblich steigert und den Druck auf der Kette verringert.

Um besser zu verstehen, was Parallelität ist, beginnen wir mit der Ausführung und verwenden Ethereum im PBS-Modus nach dem Merge als Beispiel, um zu erklären, was Ausführung ist, während wir demonstrieren, wo die Ausführung im gesamten Lebenszyklus einer Transaktion steht.

Die spezifischen Schritte der Transaktionsausführung

  1. Transaktionen gelangen in den Speicherpool und werden gefiltert und sortiert: Dies ist die Vorverarbeitungsphase, nachdem die Transaktionen eingereicht wurden und umfasst die Interaktion zwischen Mempool, Sucher und Builder, um die Transaktionen zu filtern und zu sortieren.

  2. Builder erstellt Blöcke (führt jedoch keine Ausführung durch): Der Builder ordnet profitable Transaktionen in einen Block, um das Packen und Sortieren der Transaktionen abzuschließen.

  3. Proposer überprüft und reicht den Block ein: Nach Abschluss des Blockaufbaus sendet der Builder den Blockvorschlag an den Proposer. Der Proposer validiert die Struktur des Blocks und die Inhalte der Transaktionen und reicht dann offiziell den Block im Netzwerk ein, um die Ausführung zu starten.

  4. Transaktionen ausführen: Nach der Einreichung des Blocks führen die Knoten die Transaktionen im Block nacheinander aus. Dies ist die entscheidende Phase der Statusaktualisierung, jede Transaktion löst einen Smart-Contract-Aufruf, eine Änderung des Kontostands oder eine Statusänderung aus.

  5. Zeugenbeweis: Die Validatoren bezeugen die Ausführungsergebnisse und den Statusstamm des Blocks und bestätigen diese als endgültige Bestätigung. Dies stellt die Authentizität und Gültigkeit des Blocks in der Ausführungsebene sicher und verhindert Inkonsistenzen.

  6. Statussynchronisation: Jeder Knoten synchronisiert die Ausführungsergebnisse des Blocks (wie Kontostände, Aktualisierungen des Vertragsstatus usw.) mit seinem lokalen Status. Nach der Ausführung jeder Transaktion berechnet und speichert der Knoten einen neuen Statusstamm, um ihn im nächsten Block als Ausgangszustand zu verwenden.

Natürlich ist dies nur die Statussynchronisation von Transaktionen auf Blockebene. Um den neuesten Status auf der Kette zu halten, synchronisieren Knoten normalerweise Daten blockweise und validieren kontinuierlich Blöcke und Status. Um jedoch die Endgültigkeit unter dem POS-Mechanismus zu erreichen, muss der Aggregator die Signaturen der Zeugen in jedem Slot zu einer vollständigen Signatur aggregieren und an den Vorschlagenden des nächsten Slots übergeben. Die Validatoren müssen nach einem Epoch basierend auf der Anzahl der Stimmen den Status aller Blöcke innerhalb dieses Epochs bestätigen, um einen temporären Konsensstatuscheckpoint zu bilden. Sobald zwei aufeinanderfolgende Epochs die Unterstützung der Mehrheit der Validatoren erhalten, erreichen die Blöcke und Transaktionen die Endgültigkeit.

Betrachtet man den gesamten Lebenszyklus einer Transaktion, erfolgt die Ausführung, nachdem der Proposer die Struktur und die Inhalte der vom Builder gesendeten Blöcke validiert hat. Der tatsächliche Ausführungsprozess erfordert die schrittweise Bearbeitung der Transaktionen und die Aktualisierung des entsprechenden Kontos oder Vertragsstatus. Nachdem alle Transaktionen ausgeführt wurden, berechnet der Proposer einen neuen Statusstamm (Merkle-Root), der die Ausführungsergebnisse aller Transaktionen im aktuellen Block und den endgültigen globalen Status zusammenfasst. Einfach ausgedrückt umfasst der gesamte Blockausführungsprozess eine Reihe von Berechnungen, die erforderlich sind, um Ethereum vom vorherigen Status in den nächsten Status zu verwandeln, von der Ausführung jeder Transaktion bis zur Berechnung der Merkle-Root.

Sequenzielle Ausführung

Im Gegensatz zur Parallelität steht die sequenzielle Ausführung, die derzeit die gängigste Ausführungsweise in Blockchain ist. Normalerweise werden Transaktionen nacheinander ausgeführt. Nach Abschluss der Ausführung einer Transaktion aktualisiert Ethereum den Kontostatus und die zugehörigen Informationen (z. B. Salden, Vertragsdaten) im Statusbaum des Kontos, und es wird ein neuer Hash des Kontostatus erzeugt. Nachdem alle Kontostatusbäume aktualisiert wurden, wird der Hash des Wurzelknotens des Statusbaums, bekannt als Merkle-Root, gebildet. Nach Abschluss der Berechnung von Merkle-Root, Transaktions-Merkle-Root und Beleg-Merkle-Root wird der Blockkopf gehasht, um den Blockhash dieses Blocks zu erzeugen.

In diesem Zusammenhang ist die Reihenfolge der Transaktionsausführung von entscheidender Bedeutung. Da der Merkle-Baum ein binärer Baum von Hashwerten ist, wird der Merkle-Root-Wert, der in unterschiedlicher Reihenfolge gebildet wird, unterschiedlich sein.

Parallele Ausführung

In einer parallelen Ausführungsumgebung versuchen Knoten, die Transaktionen im Block parallel zu verarbeiten. Es werden nicht nacheinander Transaktionen ausgeführt, sondern die Transaktionen werden verschiedenen „Ausführungspfaden“ zugewiesen, sodass sie gleichzeitig ausgeführt werden können. Durch parallele Ausführung kann das System die Transaktionen im Block effizienter bearbeiten und die Durchsatzrate erhöhen.

Nachdem alle Transaktionen abgeschlossen sind, fasst der Knoten die Ausführungsergebnisse (d. h. die Statusaktualisierungen, die durch die Transaktionen beeinflusst wurden) zusammen und bildet einen neuen Blockstatus. Dieser Status wird der Blockchain hinzugefügt und repräsentiert den neuesten globalen Status auf der Kette.

Zustandskonflikte

Da Parallelität Transaktionen auf verschiedenen Pfaden gleichzeitig verarbeitet, ist ein großes Problem der Parallelität der Statuskonflikt. Es kann Situationen geben, in denen mehrere Transaktionen gleichzeitig auf denselben Teil von Daten (Status) auf der Blockchain zugreifen oder diese schreiben. Wenn dies nicht richtig gehandhabt wird, kann es zu unbestimmten Ausführungsergebnissen führen. Aufgrund unterschiedlicher Aktualisierungsreihenfolgen des Status können auch die endgültigen Berechnungsergebnisse unterschiedlich sein. Zum Beispiel:

Angenommen, es gibt zwei Transaktionen, Transaktion A und Transaktion B, die beide versuchen, den Saldo des gleichen Kontos zu aktualisieren:

  • Transaktion A: Erhöhung des Kontostands um 10.

  • Transaktion B: Erhöhung des Kontostands um 20.

Der anfängliche Kontostand beträgt 100.

Wenn wir seriell ausführen, ist das Ergebnis der Ausführungsreihenfolge bestimmt:

1. Führen Sie zuerst Transaktion A und dann Transaktion B aus:

  • Der Kontostand erhöht sich zunächst um 10 und beträgt 110.

  • Erhöht sich dann um 20 und beträgt schließlich 130.

2. Führen Sie zuerst Transaktion B und dann Transaktion A aus:

  • Der Kontostand erhöht sich zunächst um 20 und beträgt 120.

  • Erhöhe um 10, was schließlich zu 130 führt.

In diesen beiden Reihenfolgen ist das Endguthaben jeweils 130, da das System die Konsistenz der Ausführungsreihenfolge der Transaktionen sicherstellt.

Aber in einer parallelen Ausführungsumgebung könnten die Transaktionen A und B gleichzeitig den Anfangssaldo von 100 lesen und ihre jeweiligen Berechnungen durchführen:

  1. Transaktion A liest einen Saldo von 100 und aktualisiert den Saldo nach der Berechnung auf 110.

  2. Transaktion B liest ebenfalls einen Saldo von 100 und aktualisiert den Saldo nach der Berechnung auf 120.

In diesem Fall führt die gleichzeitige Ausführung der Transaktionen dazu, dass das endgültige Guthaben nur auf 120 aktualisiert wird, anstatt auf 130, da die Operationen von Transaktion A und Transaktion B die Ergebnisse des jeweils anderen "überschreiben" und einen Zustandskonflikt erzeugen.

Solche Statuskonflikte werden oft als „Datenüberschreibung“ bezeichnet, was bedeutet, dass, wenn Transaktionen gleichzeitig versuchen, dieselben Daten zu ändern, sie möglicherweise die Berechnungsergebnisse des jeweils anderen überschreiben, was zu einem falschen Endstatus führen kann. Ein weiteres Problem, das durch Statuskonflikte verursacht werden kann, ist die Unfähigkeit, die Ausführungsreihenfolge zu garantieren. Da mehrere Transaktionen in unterschiedlichen Zeitrahmen ihre Operationen abschließen, kann dies zu unterschiedlichen Ausführungsreihenfolgen führen. Unterschiedliche Reihenfolgen können unterschiedliche Berechnungsergebnisse liefern, was die Ergebnisse unbestimmt macht.

Um diese Unsicherheit zu vermeiden, führen Blockchain-parallele Ausführungssysteme in der Regel einige Konflikterkennungs- und Rückrollmechanismen ein oder analysieren die Abhängigkeiten der Transaktionen im Voraus, um sicherzustellen, dass sie parallel ausgeführt werden, ohne die Konsistenz des Endstatus zu beeinträchtigen.

Optimistisch parallel vs. deterministisch parallel

Es gibt zwei Ansätze, um mögliche Probleme mit Statuskonflikten zu behandeln: deterministische Parallelität und optimistische Parallelität. Diese beiden Modelle haben unterschiedliche Kompromisse in Bezug auf Effizienz und Designkomplexität.

Deterministische Parallelität erfordert, dass der Statuszugriff im Voraus deklariert wird; Validatoren oder Sequencer überprüfen die deklarierten Statuszugriffe beim Sortieren von Transaktionen. Wenn mehrere Transaktionen versuchen, denselben Status zu schreiben, werden diese Transaktionen als Konflikte markiert, um eine gleichzeitige Ausführung zu vermeiden. Verschiedene Blockchains implementieren die Vorabdeklaration des Statuszugriffs unterschiedlich, aber im Allgemeinen umfasst dies verschiedene Methoden:

  • Durch Vertragsvorgaben: Entwickler geben direkt den Umfang des Zugriffs auf den Status in Smart Contracts an. Zum Beispiel erfordert die Übertragung von ERC-20-Token den Zugriff auf die Saldenfelder des Senders und des Empfängers.

  • Durch die Deklaration strukturierter Daten in Transaktionen: Spezielle Felder in der Transaktion hinzufügen, um den Statuszugriff zu kennzeichnen.

  • Durch Compiler-Analyse: Compiler für Hochsprachen können den Vertragscode statisch analysieren und automatisch eine Sammlung von Statuszugriffen generieren.

  • Durch Frameworks erzwungene Deklaration: Bestimmte Frameworks verlangen von Entwicklern, dass sie bei Funktionsaufrufen explizit den benötigten Status angeben.

Optimistische Parallelität bearbeitet Transaktionen optimistisch zuerst und führt die betroffenen Transaktionen in der Reihenfolge erneut aus, wenn Konflikte auftreten. Um Konflikte zu vermeiden, liegt der Schwerpunkt des Designs der optimistischen Parallelität darauf, den Status schnell durch historische Daten, statische Analysen usw. vorherzusagen. Das System nimmt an, dass bestimmte Operationen oder Statusaktualisierungen gültig sind, ohne alle Validierungsprozesse abzuwarten, um die Leistung und den Durchsatz zu steigern.

Obwohl optimistische Parallelität versucht, Konflikte durch schnelle Vorhersagen und Annahmen über den Status zu vermeiden, gibt es dennoch einige unvermeidbare Herausforderungen, insbesondere bei der Ausführung von Verträgen oder bei Cross-Chain-Transaktionen. Wenn Konflikte häufig auftreten, kann die erneute Ausführung die Systemleistung erheblich verlangsamen und den Verbrauch von Rechenressourcen erhöhen.

Deterministische Parallelität vermeidet Konflikte, die möglicherweise bei optimistischer Parallelität auftreten können, indem vor der Transaktion eine Überprüfung der Zustandsabhängigkeit durchgeführt wird. Da jedoch die Zustandsabhängigkeiten vor dem Einreichen der Transaktionen genau deklariert werden müssen, sind die Anforderungen an die Entwickler höher, was die Komplexität der Implementierung erhöht.

EVM-Parallelen Herausforderungen

Der Umgang mit Statuskonflikten unterscheidet sich nicht nur zwischen deterministischen und optimistischen Ansätzen, sondern erfordert auch Überlegungen zur Architektur der Blockchain-Datenbank. Die Probleme mit Statuskonflikten in der Parallelität sind besonders herausfordernd im Kontext der EVM unter Verwendung der Merkle-Baum-Architektur. Der Merkle-Baum ist eine hierarchische Hash-Struktur, und jedes Mal, wenn eine Transaktion Daten zu einem bestimmten Status ändert, muss auch der Wurzel-Hash des Merkle-Baums aktualisiert werden. Dieser Aktualisierungsprozess ist rekursiv und erfolgt schrittweise von den Blättern bis zur Wurzel. Da Hashes nicht umkehrbar sind, kann der übergeordnete Hash erst berechnet werden, wenn die Änderungen der untergeordneten Daten abgeschlossen sind. Diese Eigenschaften machen es schwierig, parallele Aktualisierungen durchzuführen.

Wenn zwei Transaktionen parallel ausgeführt werden und denselben Status (z. B. Kontostand) aufrufen, führt dies zu Konflikten bei den Knoten im Merkle-Baum. Die Lösung solcher Konflikte erfordert normalerweise zusätzliche Transaktionsverwaltungsmechanismen, um sicherzustellen, dass in mehreren Verzweigungen derselbe Wurzel-Hash-Wert konsistent bleibt. Dies ist für die EVM nicht leicht zu implementieren, da sie einen Kompromiss zwischen Parallelität und Statuskonsistenz eingehen muss.

Nicht-EVM-Parallele Lösungen

Solana

Im Gegensatz zum globalen Statusbaum von Ethereum verwendet Solana ein Kontenmodell. Jedes Konto ist ein unabhängiger Speicherraum, der im Ledger gespeichert ist, wodurch Probleme mit Pfadkonflikten vermieden werden.

Solana ist deterministisch parallel. In Solana muss jede Transaktion beim Einreichen eindeutig die Konten und die erforderlichen Zugriffsrechte (nur lesen oder lesen und schreiben) deklarieren, auf die zugegriffen werden soll. Dieses Design ermöglicht es Blockchain-Knoten, die benötigten Ressourcen für jede Transaktion im Voraus zu analysieren, bevor die Transaktion ausgeführt wird. Da die Kontenabhängigkeiten vor Beginn der Ausführung jeder Transaktion klar deklariert sind, können die Knoten feststellen, welche Transaktionen auf dieselben Konten zugreifen und welche Transaktionen sicher parallel ausgeführt werden können, was eine intelligente Planung zur Vermeidung von Konflikten und die Grundlage für die parallele Planung ermöglicht.

Da jede Transaktion vor der Ausführung die benötigten Konten und Berechtigungen deklariert hat, kann Solana überprüfen, ob zwischen den Transaktionen Kontenabhängigkeiten bestehen (Sealevel-Modell). Wenn zwischen den Transaktionen keine gemeinsamen Lese- oder Schreibkonten existieren, kann das System sie auf verschiedene Prozessoren verteilen und parallel ausführen.

Aptos

Das Design der parallelen Ausführung von Aptos unterscheidet sich erheblich von Ethereum, da es einige entscheidende Innovationen in Architektur und Mechanismen aufweist, die hauptsächlich im Kontenmodell und in der Statusspeicherung zum Ausdruck kommen.

Ethereum muss bei der Ausführung von Transaktionen häufig den globalen Statusbaum (MPT) aktualisieren. Alle Konten- und Vertragszustände werden in einem gemeinsamen Statusbaum gespeichert, und jede Transaktion muss einen Teil dieses Statusbaums lesen und aktualisieren. Aptos teilt jedoch Konten in unabhängige Zustandseinheiten auf, wobei jedes Objekt ein unabhängiges Schlüssel-Wert-Paar ist, das unabhängig existieren kann, ohne sich gegenseitig zu beeinflussen, und nur bei explizitem Bezug zueinander verbunden wird. Zwischen Objekten gibt es keinen gemeinsamen Baumweg, was zu keinem Lock-Wettbewerb führt und eine vollständige Parallelität ermöglicht.

Aptos' zugrunde liegende Datenstruktur ist der Jellyfish Merkle Tree. Der Status jedes Objekts wird schließlich im JMT gespeichert, als unabhängiges Schlüssel-Wert-Paar. Im Gegensatz zum MPT von Ethereum hat der Jellyfish Merkle Tree eine vollständig binäre Baumstruktur, die den Speicher- und Abfragepfad der Knoten vereinfacht und die Verifizierungszeit erheblich verkürzt. Außerdem ist die Position jedes Kontos im Baum festgelegt, und die Knoten im Baum werden unabhängig gespeichert, was mehrere Aktualisierungen und Abfragen von Konten parallel ermöglicht.

Aptos ist optimistisch parallel, es erfordert nicht, dass alle deklarierten Kontenabhängigkeiten im Voraus bereitgestellt werden. Zu diesem Zweck verwendet Aptos Block-STM, das die vorgegebene Transaktionsreihenfolge nutzt, um Abhängigkeiten zu schätzen und somit die Anzahl der Abbrüche zu reduzieren.

Parallele EVM

Im Vergleich zur nicht-EVM-Parallelität stehen parallele EVMs vor größeren technischen Herausforderungen bei der Behandlung von Statusabhängigkeiten, Konflikterkennung, Gasverwaltung und Rückrollmechanismen. Um dies besser zu verstehen, können wir einige parallele EVM-Projekte (wie Sui, Monad, Canto) betrachten, die diese Probleme lösen.

Sui

Sui und Aptos verwenden ebenfalls ein Objektmodell zur Verarbeitung des Status und behandeln jedes Objekt (z. B. Konto, Status von Smart Contracts) als unabhängige Ressource, die durch eindeutige Identifikatoren unterschieden wird. Wenn Transaktionen unterschiedliche Objekte betreffen, können diese Transaktionen parallel verarbeitet werden, da sie auf unterschiedliche Zustände zugreifen und keine direkten Konflikte verursachen.

Obwohl Sui ein Objektmodell zur Verwaltung des Status verwendet, wird die Architektur von Sui durch eine zusätzliche Anpassungsschicht oder Abstraktionsmechanismen so gestaltet, dass sie das Objektmodell mit dem Kontenmodell der EVM verbindet.

In Sui verwendet die Planung von Transaktionen eine optimistisch parallele Strategie, die davon ausgeht, dass es keine Konflikte zwischen den Transaktionen gibt. Wenn Konflikte auftreten, verwendet das System Rückrollmechanismen, um den Status wiederherzustellen.

Sui verwendet ein Objektmodell und Techniken zur Statusisolierung, um effektiv Probleme mit Statusabhängigkeiten zu vermeiden. Jedes Objekt fungiert als unabhängige Ressource, verschiedene Transaktionen können parallel ausgeführt werden, was die Durchsatzrate und Effizienz erhöht. Der Nachteil dieser Methode ist jedoch die Komplexität des Objektmodells und die Kosten des Rückrollmechanismus. Wenn Konflikte zwischen Transaktionen auftreten, muss ein Teil des Status zurückgesetzt werden, was die Belastung des Systems erhöht und die Effizienz der parallelen Verarbeitung beeinträchtigen kann. Im Vergleich zu nicht-EVM-parallelen Systemen (wie Solana) benötigt Sui mehr Rechen- und Speicherressourcen, um eine effiziente Parallelität aufrechtzuerhalten.

Monad

Ähnlich wie Sui verwendet auch Monad optimistische Parallelität. Die optimistische Parallelität von Monad prognostiziert jedoch vor der tatsächlichen Transaktionsausführung einige Transaktionen mit Abhängigkeiten, wobei die Vorhersage hauptsächlich durch den statischen Code-Analysator von Monad erfolgt. Für die Vorhersage muss auf den Status zugegriffen werden, während die Art und Weise, wie Ethereum die Datenbank speichert, den Zugriff auf den Status sehr erschwert. Um die Effizienz der Parallelität im Statusleseprozess zu erhöhen, hat Monad zudem die Datenbank umgestaltet.

Der Statusbaum von Monad ist nach Partitionen unterteilt, wobei jede Partition ihren eigenen Statusunterbaum verwaltet. Bei Aktualisierungen müssen nur die relevanten Partitionen geändert werden, es ist nicht erforderlich, den gesamten Statusbaum neu zu erstellen. Der Statusindex ermöglicht eine schnelle Lokalisierung des Status innerhalb der Partition und reduziert die Interaktionen zwischen den Partitionen.

Zusammenfassung

Das Herzstück der Parallelität besteht darin, die Effizienz der Ausführungsebene durch Mehrpfadausführung zu steigern. Um Mehrpfadausführung zu erreichen, muss die Blockchain eine Reihe von Mechanismen wie Konflikterkennung und Rückrollmechanismen implementieren, um sicherzustellen, dass sie parallel ausgeführt wird, ohne die Konsistenz des Endstatus zu beeinträchtigen, und dass sie die Datenbank in gewissem Maße verbessert.

Natürlich ist die Steigerung der Effizienz der Ausführungsebene nicht nur auf Parallelität beschränkt, sondern die Optimierung der Ausführung kann auch durch die Reduzierung der Lese- und Schreiboperationen einer Transaktion auf der Datenbank erreicht werden. Die Verbesserung der Geschwindigkeit der gesamten Kette umfasst auch die Steigerung der Effizienz der Konsensschicht.

Hinter jeder Technologie stehen spezifische Einschränkungen. Parallelität ist nur eine Möglichkeit, die Effizienz zu steigern. Ob diese Technologie letztendlich genutzt wird, hängt auch davon ab, ob sie für Entwickler benutzerfreundlich ist und ob sie dezentralisiert umgesetzt werden kann, ohne dabei Abstriche zu machen. Eine Überlagerung von Technologien ist nicht immer besser. Zumindest für Ethereum ist Parallelität nicht so attraktiv, da die Integration von Parallelität aus der Sicht der Effizienzsteigerung nicht die beste Lösung für Ethereum darstellt, sowohl aus der Sicht der Einfachheit als auch im Hinblick auf den aktuellen Rollup-zentrierten Fahrplan von Ethereum.