NEU: Helius übernimmt Light Protocol
Asynchrone Programmausführung: Beginn einer neuen Solana-APE-oche
Blog/Forschung

Asynchrone Programmausführung: Beginn einer neuen Solana-APE-oche

ForscherLostin auf X
29 Min. Lesezeit

Einführung

Inmitten der hitzigen Debatten und ankündigungsreichen Keynotes der diesjährigen, geschäftigen Breakpoint-Konferenz nahm sich Solana-Mitgründer Anatoly Yakovenko Zeit für einen einzigen improvisierten und nicht aufgezeichneten technischen Workshop. Mit Flipchart und Markern ausgerüstet, erläuterte er die Feinheiten eines Themas, das er leidenschaftlich als nächste Entwicklungsstufe von Solana vorantreibt und das im Mittelpunkt dieses Artikels steht: die asynchrone Ausführung.

Als Einstieg in die ambitionierte Vision der asynchronen Ausführung – im Folgenden kurz AE – beginnen wir mit einer allgemeinen Erklärung ihrer Kernkonzepte und Ziele. Anschließend betrachten wir die bestehenden Ausführungs- und Konsensmechanismen von Solana, um eine Grundlage für die vergleichende Analyse künftig vorgeschlagener Architekturen zu schaffen. Danach befassen wir uns mit den verschiedenen Vorschlägen rund um AE. Den Anfang machen Bankless Leaders, die einen notwendigen Zwischenschritt für diesen Wandel bilden. Außerdem untersuchen wir die ersten Designvorschläge aus dem Jahr 2022 und gehen chronologisch zu neueren Vorschlägen für eine „Endgame-Architektur“ über. Diese gehen über AE hinaus und umfassen Designimplementierungen für mehrere gleichzeitig aktive Blockproduzenten.

AE im Überblick

Es ist schon irgendwie seltsam, darüber nachzudenken. Alles, was er [ein Validator] tut, ist, Blöcke zu erstellen und abzustimmen. Er muss keinen dieser Blöcke jemals ausführen. Während er Blöcke erstellt, weiß er nicht, welche Art von Blöcken er erstellt … Entscheidend ist nur, sich auf die Reihenfolge zu einigen. Die Werte sind ihm egal.

Anatoly Yakovenko
Anatoly Yakovenko
Solana-Mitgründer

Im Kontext des Solana-Kernprotokolls bezeichnet AE den architektonischen Ansatz, Ausführung und Konsens voneinander zu trennen, damit beide unabhängig arbeiten können. Dazu erzielt das Netzwerk einen Konsens über die Reihenfolge der Transaktionen, ohne sie tatsächlich auszuführen. Sobald die Reihenfolge feststeht, kann jeder die Transaktionen ausführen und so die Wahrheit offenlegen.

Bei diesem Ansatz würden Leader Blöcke erstellen, ohne die Nicht-Abstimmungstransaktionen auszuführen, und sie über Turbine im Netzwerk verbreiten. Validatoren könnten ebenfalls über die Blöcke abstimmen, ohne Nicht-Abstimmungstransaktionen auszuführen. Der Konsens beschränkt sich ausschließlich auf die Reihenfolge und Verfügbarkeit der Transaktionen. Das reduziert den Zeitaufwand und die erforderlichen Schritte erheblich. Um eine Zusammenfassung von Jon Charbonneau von DBA sinngemäß wiederzugeben: Die Reihenfolge bestimmt die Wahrheit, die Ausführung legt sie offen.

Dieser Ansatz unterscheidet sich stark von der aktuellen Konsensfindung. Derzeit führen Leader Transaktionen aus, bevor sie sie in Blöcke packen, und alle Validatoren spielen die Transaktionen eines Blocks erneut ab, bevor sie darüber abstimmen.

AE ist aus folgenden Gründen möglich:

  1. Die Fork-Auswahl hängt nicht von der Programmausführung ab
  2. Bei einer deterministischen Zustandsübergangsfunktion kann nur ein korrekter Zustand berechnet werden. Letztlich berechnen alle denselben Endzustand
  3. Ungültige Transaktionen können verworfen werden. Die Kosten durch Spam mit fehlgeschlagenen Transaktionen sind für das Netzwerk relativ gering. Sie bestehen aus der für die Verbreitung der Transaktionen nötigen Turbine-Bandbreite und dem zusätzlichen Speicherplatz für die Transaktionen im Ledger
  4. Maschinen, die den vollständigen Zustand in Echtzeit und mit geringer Latenz berechnen müssen, etwa Systeme dedizierter RPC-Dienstanbieter, können gezielt für diesen Zweck ausgestattet werden

AE bietet zahlreiche potenzielle Vorteile.

Yakovenko geht sogar so weit zu sagen: „Die asynchrone Ausführung ist einer der seltenen Fälle, in denen es praktisch keine Kompromisse gibt.“

  1. Kürzere Blockzeiten (200 Millisekunden)
  2. Zuverlässigere Blockzeiten
  3. Geringere Anforderungen an Validatoren
  4. Bessere Benutzererfahrung (schnellere Finalität)
  5. Höhere Zensurresistenz
  6. Kleineres Zeitfenster zum Umsortieren von Transaktionen
  7. Übertragung ungenutzter Kapazität zwischen Blöcken
  8. Ein Weg zu mehreren gleichzeitig aktiven Blockproduzenten (dazu später mehr)

Im Verlauf dieses Artikels untersuchen wir genau, wie AE diese Vorteile ermöglicht.

AE lässt sich auch so verstehen: Das Abstimmungsprogramm kann unabhängig von allen anderen Programmen arbeiten. Das Abstimmungsprogramm und das stets erforderliche Systemprogramm sind die einzigen Programme, die innerhalb einer Epoche für den Konsens notwendig sind.

Die Diskussionen über AE auf Solana laufen bereits seit mehreren Jahren. Anatoly Yakovenkos erster formeller Vorschlag, ursprünglich APEX (Asynchronous Program Execution) genannt, stammt aus dem April 2022. Konkrete Details zur praktischen Implementierung von AE auf Solana verteilen sich auf mehrere SIMDs und Artikel. Dieser Artikel behandelt sie weitgehend in chronologischer Reihenfolge. Yakovenko ist zweifellos der sichtbarste öffentliche Befürworter von AE in der Solana-Community und lässt kaum eine Gelegenheit aus, das Thema in Interviews und Podcasts anzusprechen.

Terminologie

Es ist hilfreich, kurz zwei zentrale Begriffe zu definieren, die in unserer Diskussion über AE eine wichtige Rolle spielen: Bankless Leaders und Multiple Concurrent Block Producers (MCBP). Zusammengefasst:

  • Bankless Leader: ein Leader, der Blöcke erstellen kann, ohne Transaktionen auszuführen
  • Asynchronous Execution (AE): vollständige Trennung von Konsens und Ausführung
  • Multiple Concurrent Block Producers (MCBP): wie der Name sagt, mehrere Blöcke, die gleichzeitig innerhalb desselben Slots produziert werden‍

Bankless Leaders sind ein notwendiger Schritt, um vollständige AE zu ermöglichen. Ebenso ist eine erfolgreiche Implementierung von AE eine Voraussetzung für die spätere Einführung von Multiple Concurrent Block Producers (MCBP), auch Multiple Concurrent Leaders (MCL) genannt. Diskussionen über AE werden häufig gemeinsam mit MCBP geführt. Yakovenko betrachtet beide als entscheidende Bestandteile der „Endgame-Architektur“ von Solana.

Solana ist nicht die einzige Blockchain, die diese architektonischen Verbesserungen untersucht. Monad plant, AE zu implementieren, indem Konsens und Ausführung in separate Threads aufgeteilt werden. Auch die Ethereum-Forschungsgemeinschaft untersucht seit einiger Zeit die mögliche Einführung mehrerer gleichzeitig aktiver Proposer.

Yakovenkos Vorschläge werden in der Community weiterhin diskutiert, da ihre Umsetzung erhebliche Änderungen am Kernprotokoll von Solana erfordern würde. Nicht alle halten AE für den besten Weg. Es ist keineswegs übertrieben zu sagen, dass die vollständige Implementierung von Yakovenkos vorgeschlagener Endgame-Architektur die Funktionsweise von Solana grundlegend verändern und die Gesamtkomplexität des Protokolls erhöhen würde.

Bevor wir AE genauer untersuchen, frischen wir unser Wissen darüber auf, wie Ausführung und Konsens auf Solana derzeit funktionieren. Dabei achten wir besonders auf Aspekte, die später in diesem Artikel aufgegriffen werden. Außerdem analysieren wir Daten zu Abstimmungs- und Nicht-Abstimmungstransaktionen, um zusätzliche Erkenntnisse für die spätere Diskussion zu gewinnen. Wenn du mit diesen Funktionen bereits vertraut bist und sie sicher verstehst, kannst du den nächsten Abschnitt überspringen.

Synchrone Ausführung (Solana heute)

Ausführung

Solana erstellt Blöcke fortlaufend. Dabei werden sie während eines zugewiesenen Zeitfensters von 400 Millisekunden dynamisch zusammengestellt und gestreamt. Leader erhalten vor dem Wechsel vier aufeinanderfolgende Slots (1,6 Sekunden). Damit das Netzwerk einen Block akzeptiert, muss der Leader jede Transaktion im Block prüfen und ausführen. Darüber hinaus prüfen und führen alle anderen aktiven, am Konsens beteiligten Validatoren jede Transaktion im Block erneut aus.

Ein Leader empfängt Transaktionspakete über Gulfstream via QUIC. Sie gelangen in die Transaction Processing Unit (TPU), die Kernlogik des Leaders für die Blockproduktion. Die TPU empfängt Pakete über drei offene Ports:

  • tpu: verarbeitet reguläre Transaktionen wie Token-Übertragungen, NFT-Mints und Programmanweisungen
  • tpu_vote: verarbeitet ausschließlich Abstimmungstransaktionen
  • tpu_forwards: Kann der aktuelle Leader nicht alle Transaktionen verarbeiten, leitet er unverarbeitete Pakete über diesen Port an den nächsten Leader weiter‍

Bevor eine Sortierung oder Ausführung beginnen kann, werden alle Transaktionspakete streng validiert und auf Plausibilität geprüft. Dazu gehören die Signaturprüfung, die Kontrolle der korrekten Anzahl an Signaturen und das Entfernen doppelter Transaktionen. Abstimmungs- und Nicht-Abstimmungstransaktionen verwenden dabei separate Verfahren zur Signaturprüfung.

Die Blöcke entstehen in der Banking Stage. Eine Bank entspricht dem Zustand bei einem bestimmten Block. Transaktionen werden parallel verarbeitet und in Ledger-Einträge gepackt – Batches aus 64 konfliktfreien Transaktionen. Jede Transaktion enthält eine vollständige Liste der Konten, aus denen sie liest und in die sie schreibt. Dadurch können Validatoren für jeden Eintrag einfach nur konfliktfreie Transaktionen zur Ausführung auswählen. Transaktionen stehen in Konflikt, wenn sie in dasselbe Konto schreiben (zwei Schreibvorgänge) oder dasselbe Konto lesen und beschreiben (Lesen + Schreiben). Konfligierende Transaktionen kommen in unterschiedliche Einträge und werden nacheinander ausgeführt. Konfliktfreie Transaktionen werden parallel ausgeführt.

Sechs Threads verarbeiten Transaktionen parallel. Vier sind für Nicht-Abstimmungstransaktionen vorgesehen, zwei ausschließlich für Abstimmungstransaktionen. Konsensstimmen werden in der Banking Stage als privilegierte Transaktionen behandelt. Sie kosten einheitlich 0,000005 SOL, verbrauchen 2.100 Compute Units (CUs) und werden vom Vote Program ausgeführt. 

Nachdem Transaktionen in Einträge gruppiert wurden, führt die Solana Virtual Machine (SVM) sie aus. Die für die Transaktion erforderlichen Konten werden gesperrt. Prüfungen bestätigen, dass die Transaktion aktuell ist und noch nicht verarbeitet wurde. Anschließend werden die Konten geladen und die Transaktionslogik ausgeführt, wodurch sich die Kontozustände ändern. Ein Hash des Eintrags wird zur Aufzeichnung an den Proof-of-History-Dienst (PoH) gesendet. Bei erfolgreicher Ausführung werden alle Änderungen in die Bank übernommen und die Sperren der Konten aufgehoben.

Das Protokoll schreibt keine Reihenfolge für gültige Transaktionen innerhalb eines Blocks vor. Der endgültige Zustand der Chain ergibt sich aus allen bestätigten Transaktionen. Dieser Zustand lässt sich jederzeit deterministisch aus der Blockchain-Historie rekonstruieren, etwa indem das Ledger ab Genesis oder einem Snapshot erneut abgespielt wird.

Jede Bank hat einen zugehörigen BankHash, einen SHA256-Hash der folgenden Elemente:

  • Übergeordneter BankHash – der BankHash des unmittelbar übergeordneten Blocks
  • Konto-DeltaHash – eine 16-stellige Merkle-Tree-Root aller Konten, deren Zustand sich im aktuellen Block geändert hat
  • Anzahl der Signaturen – die Gesamtzahl der Transaktionssignaturen im aktuellen Block
  • Letzter Blockhash
Code
hashv(&[
	parent_bankhash,
	accounts_delta_hash,
	num_sigs,
	blockhash,
])

Der BankHash ist die kryptografische Zusicherung, über die Validatoren für jeden Slot abstimmen.

Konsens

Validatoren benötigen drei Konten, um den Abstimmungsprozess zu ermöglichen:

Identitätskonto

Dieses Systemkonto signiert und bezahlt die Gebühren aller Abstimmungstransaktionen. Es handelt sich um ein Hot-Keypair, das direkt auf der Serverhardware gespeichert ist. Wie der Name andeutet, dient der öffentliche Schlüssel dieses Kontos als Netzwerkidentität des Validators. Das Identitätskonto ist erforderlich, um ein Abstimmungskonto zu erstellen.

Abstimmungskonto

An dieses Konto delegieren Delegierende ihre SOL. Die Adresse dient zum Nachschlagen des Kontos, nicht zum Signieren von Transaktionen.

Auszahlungskonto

Über dieses Konto werden Mittel vom Abstimmungskonto abgehoben. Es kann das Identitätskonto ändern. Der private Schlüssel dieses Kontos wird normalerweise in einer sicheren Multi-Signature- oder Cold Wallet gespeichert und muss sich von den Keypairs der Validatoridentität und Abstimmungsberechtigung unterscheiden.

Jede vom Validator signierte Stimme (Beispiel) enthält den öffentlichen Schlüssel des Validators und einen Hash, der den Block identifiziert, für den er stimmt. Wenn Validatoren korrekte und erfolgreiche Stimmen abgeben, erhalten sie Credits.

Das Netzwerk wartet nicht darauf, dass alle Validatoren einem neu erstellten Block zustimmen, bevor es den nächsten produziert. Deshalb können zwei verschiedene Blöcke mit demselben übergeordneten Block verknüpft sein und Forks bilden. Validatoren müssen über diese Forks abstimmen und mit Tower BFT, einer Variante der ursprünglichen Practical Byzantine Fault Tolerance (pBFT), entscheiden, welche sie übernehmen. 

Wenn konkurrierende Forks existieren, finalisiert das Netzwerk eine davon, während Validatoren die Blöcke verworfener Forks aufgeben. Für jeden Slot ist ein Leader vorgegeben, und nur der Block dieses Leaders wird akzeptiert. Für einen einzelnen Slot kann es also nicht zwei vorgeschlagene Blöcke geben. Die Anzahl möglicher Forks ist daher auf eine „vorhanden/nicht vorhanden“-Skip-Liste begrenzt, die an den Grenzen der Leader-Rotations-Slots entstehen kann. 

Sobald sich ein Validator für eine Fork entschieden hat, bleibt er bis zum Ablauf einer Sperrfrist an diese gebunden. Er muss seine Wahl also für einen Mindestzeitraum beibehalten. Dieser Mechanismus schafft einen Anreiz für Validatoren, sorgfältig für die Fork zu stimmen, die ihrer Einschätzung nach die besten Chancen auf Aufnahme hat – also die „schwerste“ Fork.

Ein Block gilt als optimistisch bestätigt, sobald eine Zweidrittel-Supermehrheit für ihn stimmt. Er gilt als finalisiert, sobald 31 Blöcke auf ihm aufgebaut wurden. In der Geschichte von Solana gab es noch nie einen Fall, in dem ein optimistisch bestätigter Block nicht finalisiert wurde.

Wenn eine Fork finalisiert wird, erhält der Block durch die Kontoaktualisierungen der Bank eine Root, und seine Vorgänger werden auf die Festplatte geschrieben. Zusätzlich werden alle Kontoaktualisierungen früherer Banks entfernt, die keine Vorgänger der finalisierten Bank sind.

Abstimmungs- und Nicht-Abstimmungstransaktionen

Wie wir gesehen haben, sind auf Solana die Transaktionsausführung und die Konsensfindung über Tower BFT eng miteinander verflochten. Abstimmungs- und Nicht-Abstimmungstransaktionen durchlaufen denselben Weg: Sie werden in Einträge gebündelt, von der SVM ausgeführt, im Proof-of-History-Stream (PoH) mit einem Zeitstempel versehen und über Turbine im Netzwerk verbreitet. Dieser einheitliche Prozess sorgt dafür, dass Validatoren den Konsenszustand konsistent wahrnehmen. Würden Stimmen ausschließlich über den Gossip-Dienst verbreitet, könnten Unterschiede zwischen Validatoren entstehen. Dadurch könnten Validatoren unterschiedlich einschätzen, welche Fork wahrscheinlich korrekt ist. Die fortlaufende Blockerstellung erfordert fortlaufende Abstimmungen, insbesondere während vorherige Blöcke bestätigt werden.

Ein Nebeneffekt dieser Bündelung ist die Kontroverse um Solanas TPS-Kennzahlen (Transaktionen pro Sekunde). In ihrer Rohform umfassen sie sowohl Abstimmungs- als auch Nicht-Abstimmungstransaktionen. Bei den meisten vergleichbaren Netzwerken der Branche ist das nicht der Fall. Deshalb hat sich „echte TPS“ als genauere Kennzahl für die Transaktionskapazität etabliert, bei der Abstimmungstransaktionen ausgeschlossen werden.

Bei der Betrachtung der jüngsten Solana-Aktivität sehen wir, dass Abstimmungstransaktionen die Nicht-Abstimmungstransaktionen überwiegen. Ihr Durchschnitt liegt bei knapp 1.000 pro Block.

Abstimmungstransaktionen machen nur einen kleinen Teil der gesamten Compute Units pro Block aus. Der Durchschnitt liegt bei etwas mehr als 2 Millionen CUs pro Block und konstant zwischen 2,1 und 2,3 Millionen CUs. Das entspricht nur 4,5 % des Compute-Limits von 48 Millionen CUs für Solana-Blöcke.

Der Zeit- und Rechenaufwand von Abstimmungstransaktionen ist im Vergleich zu Nicht-Abstimmungstransaktionen sehr zuverlässig. Das ist ein entscheidender Punkt, auf den wir später zurückkommen. Die CUs von Nicht-Abstimmungstransaktionen schwanken und führen dadurch zu einer ineffizienten Hardwareauslastung. ‍

Eine präzise Ausführungsdauer in der Runtime zu garantieren, ist schwierig, da es sich eher um einen Näherungswert handelt. Im Durchschnitt sollen Blöcke unter 400 Millisekunden bleiben, gelegentlich treten jedoch Spitzen auf. Diese Spitzen können als Fehler betrachtet werden. Sie werden kontinuierlich gesucht und behoben, wodurch sich das System laufend verbessert.

Eine Epoche umfasst 432.000 Slots. Würde jeder exakt 400 Millisekunden dauern, ergäbe das eine Epochenlänge von genau 48 Stunden. Historische Daten zeigen jedoch, dass Epochen dieses Ziel selten oder nie erreichen. Im vergangenen Jahr dauerten Epochen üblicherweise zwischen 2,1 und 2,3 Tagen.

Bei synchroner Ausführung müssen alle gestakten, am Konsens beteiligten Validatoren für die ungünstigste Ausführungsdauer eines beliebigen Blocks überdimensioniert sein. Entsprechend hoch sind die Hardwareanforderungen für Solana-Validatoren.

Damit ist unser Überblick über die aktuelle Funktionsweise von Konsens und Ausführung auf Solana abgeschlossen. Der Schwerpunkt lag auf den Teilen, die für spätere Diskussionen relevant sind. Für umfassendere Erklärungen empfehlen wir unsere früheren Helius-Blogbeiträge zu Konsens, PoH, Turbine und dazu, wie Solana funktioniert. In den folgenden Abschnitten untersuchen wir künftige Änderungen am Protokolldesign von Solana.

APEX, 2022

Yakovenkos erster formeller Vorschlag für AE stammt aus dem April 2022 und trägt den Titel APEX (Asynchronous Program EXecution). Dieser relativ kurze Vorschlag beschreibt praktische Details zur Trennung von Konsens und Ausführung. Er führt das Konzept ein, den Zustand in zwei isolierte Domänen aufzuteilen: die standardmäßige „Domain 0“ und die „Domain 1“ des Vote Program. Dadurch wird das Vote Program vom Rest der Bank getrennt.‍

Alle Konten gehören zu genau einer Domäne. Transaktionen können nicht auf Konten aus mehreren Domänen zugreifen oder in sie schreiben. Jede Transaktion, die dies versucht, schlägt sofort fehl und wird ignoriert. Das System Program existiert in beiden Domänen. Das Vote Program ist das einzige weitere Programm in Domain 1.

Eine spezielle Systemanweisung (SystemInstruction::MoveDomains) bietet einen Mechanismus, mit dem Konten einmal pro Epoche zwischen Domänen wechseln können. Das ermöglicht die Übertragung von SOL an Abstimmungskonten und von ihnen weg.

Der Vorschlag führt außerdem das Konzept eines ForkHash als Gegenstück zum BankHash ein. Bei der Berechnung des ForkHash werden nur die Anweisungen des Vote Program aus Domain 1 ausgewertet. Der BankHash wertet dagegen alle Anweisungen aus Domain 0 aus, die nicht zum Vote Program gehören. Abstimmungsanweisungen verweisen auf den ForkHash. Die Berechnung des BankHash erfolgt außerhalb der Root, über die Konsensvalidatoren abstimmen. Zuvor mussten zur Auswahl einer Fork und zur Abstimmung darüber alle Transaktionen in der Bank vollständig ausgewertet und ausgeführt werden. Nun werden bei der Fork-Auswahl nur noch Transaktionen ausgewertet, die das Vote Program betreffen.

Dieses frühe Design lässt viele Fragen offen, etabliert aber das grundlegende Konzept isolierter Domänen, auf das wir später zurückkommen.

Bankless Leaders

Ein Bankless Leader ist ein Leader, der Blöcke erstellen kann, ohne Nicht-Abstimmungstransaktionen auszuführen. Das ist eine entscheidende Voraussetzung für die Implementierung von AE. In einem Blogbeitrag mit dem Titel Der Weg zu Bankless baut Anza-Ingenieur Andrew Fitzgerald auf einem früheren Vorschlag für Bankless Leaders von Tao Zhu, ebenfalls bei Anza, auf (SIMD-005, Dezember 2022, geschlossen). Fitzgerald beschreibt mehrere notwendige Änderungen für die Einführung von Bankless Leaders auf Solana. Insbesondere identifiziert er drei zentrale Kategorien protokollbedingter Einschränkungen, die die Implementierung von AE begrenzen: Block-, Eintrags- und Transaktionseinschränkungen.

Wird derzeit eine dieser Einschränkungen verletzt, ist der gesamte Block ungültig. Durch die Aufhebung dieser Beschränkungen würde das Solana-Protokoll einen Weg für AE eröffnen und zugleich die Flexibilität bei Blockproduktion und -validierung erhöhen. Im Folgenden findest du eine Zusammenfassung der verschiedenen Einschränkungen:‍

Blockeinschränkungen

Diese Einschränkungen gelten für den gesamten Block: 

  • Blöcke müssen 64 Ticks enthalten
  • Der letzte Blockeintrag muss ein Tick sein
  • Transaktionen in allen Blockeinträgen müssen innerhalb der Blocklimits liegen

Eintragseinschränkungen

Die wichtigste Einschränkung dieser Kategorie besteht darin, dass Einträge keine konfliktierenden Transaktionen enthalten dürfen. Fitzgerald reichte im November vergangenen Jahres SIMD 0083: Eintragseinschränkungen lockern ein, das sich speziell mit diesem Problem befasst. Das SIMD wurde angenommen.

Einschränkungen auf Transaktionsebene

Dies ist die größte Kategorie. Sie lässt sich in drei Unterkategorien aufteilen:

Statische Einschränkungen

Einschränkungen, die sich ohne Kenntnis eines zusätzlichen Zustands prüfen lassen. Dazu gehören die Signaturprüfung, die Transaktionsgröße, die Anzahl der in der Lese-/Schreibadressliste aufgeführten Konten und die Einhaltung des Transaktionsdatenformats – eine Transaktion muss sich also deserialisieren lassen‍

Diese Unterkategorie der Einschränkungen auf Transaktionsebene muss nicht geändert werden.

Bankzustandsabhängige Einschränkungen

Dazu gehören Prüfungen der Eindeutigkeit einer Transaktionssignatur, um sicherzustellen, dass sie nicht bereits in einem kürzlich erstellten Block enthalten war, sowie Altersprüfungen – Transaktionen müssen also einen aktuellen Blockhash enthalten

Diese Unterkategorie erfordert Kenntnisse über den jüngsten Zustand der Bank.

Kontozustandsabhängige Transaktionseinschränkungen

Die restriktivste Unterkategorie. Sie umfasst die Auflösung von Address Lookup Tables (ALT), Nonce-Prüfungen, Prüfungen des Gebührenzahlers und Prüfungen der Ausführbarkeit

Diese Unterkategorie erfordert Kenntnisse über vorherige Transaktionen.

Fitzgerald schlug mit SIMD 0082: Transaktionseinschränkungen lockern, das derzeit offen ist, formell Änderungen an dieser Einschränkungskategorie vor.

Wie Fitzgerald anmerkt, darf die Blockprüfung für AE nicht vom Kontozustand abhängen. Wenn die Prüfung eines Blocks die Ergebnisse vorheriger Transaktionen benötigt, kann der Block nicht asynchron ausgeführt werden. Daher müssen Abhängigkeiten vom Kontozustand bei der Blockprüfung beseitigt werden. Außerdem sind viele dieser Einschränkungen unnötig restriktiv.

Eine Transaktion, bei der der Unterzeichner nicht genügend Lamports für die Gebühren besitzt, sollte beispielsweise weder im aktuellen Protokoll noch nach den vorgeschlagenen Änderungen ausgeführt werden. Mit den vorgeschlagenen Änderungen würde eine solche Transaktion jedoch nicht dazu führen, dass der restliche Block als ungültig gilt.

Insgesamt bietet Fitzgeralds Arbeit ein praktisches Konzept dafür, wie sich die Banking Stage ändern ließe, um AE den Weg zu ebnen. Sie beschreibt viele Schritte, die den Konsens verändern und nötig sind, um AE Wirklichkeit werden zu lassen.

APExB 2023: AE trifft auf MCBP

Die asynchrone Programmausführung wird den gesamten Solana-Zustand in ein Rollup verwandeln.

Anatoly Yakovenko
Anatoly Yakovenko
Mitgründer von Solana

Im März 2023, fast ein Jahr nach dem ursprünglichen APEX-Entwurf, stellte Yakovenko einen umfassenderen und detaillierteren Vorschlag mit dem Titel Asynchronous Program Execution and Broadcast (APExB) SIMD 0023 vor. Dieser Vorschlag geht über die Implementierung von AE hinaus und präsentiert eine breitere Vision, die Multiple Concurrent Block Producers (MCBP) integriert.

Der Vorschlag führt das Konzept der „Builder“ ein, die vom Leader getrennte Entitäten sind. Builder sind gestakte Nodes, die UserBlocks erstellen, die ausschließlich aus Transaktionen ohne Votes bestehen. Diese UserBlocks werden über den Turbine-Baum verbreitet und haben eigene „UserBlockSlots“. Standardmäßig gibt es zwei UserBlockSlots pro regulärem Slot.

Builder haben einen eigenen Zeitplan, der unabhängig vom Leader-Zeitplan ist. Mehrere Builder können gleichzeitig für die Erstellung von UserBlocks eingeplant werden. Compute Units werden gleichmäßig zwischen Buildern und UserBlock-Slots aufgeteilt. Ein Block mit zwei Buildern, zwei UserBlock-Slots und einem Limit von 48 Millionen CU hat beispielsweise ein CU-Limit von 12 Millionen (48/4) pro UserBlock-Slot.

Leader erstellen wie gewohnt gemäß dem Leader-Zeitplan Blöcke mit Consensus-Votes, während Builder gleichzeitig UserBlocks mit Benutzertransaktionen erzeugen und übertragen. UserBlocks geben ihre Slot-Nummer an und werden vom Builder signiert, damit der Leader keinen Teil des Blocks manipulieren oder ausschließen kann. Sobald der Leader über Turbine einen UserBlock empfängt, erzeugt er anhand eines Hashs des UserBlock einen UserBlockEntry und fügt diesen UserBlockEntry dem Proof of History (PoH) hinzu.

Validatoren können nicht über Blöcke abstimmen, deren zugehörige UserBlocks sie noch nicht empfangen haben. Andernfalls lässt sich nicht garantieren, dass alle die Daten ausführen können, da sie zurückgehalten werden könnten. Sie können jedoch über Leader-Blöcke abstimmen, indem sie zunächst nur die Votes ausführen und erst danach die Transaktionen im UserBlock. Validatoren führen UserBlocks nur auf dem schwersten Fork aus und müssen beim Abstimmen lediglich ihren neuesten BankHash übermitteln, der zu einem älteren übergeordneten Slot gehören kann. Validatoren stimmen über VoteHashes ab. Diese erfüllen denselben Zweck wie ForkHashes im APEX-Vorschlag von 2022 – im Wesentlichen ein BankHash nur für Vote-Transaktionen.

Builder-Zeitplan

Wenn es pro Netzwerkblock zehn UserBlock-Builder gibt, werden jedem 10 % der Turbine-Shreds und 10 % der verfügbaren Rechenleistung zugewiesen. Builder werden über zwei Verfahren eingeplant: zufällig und persistent.

An jeder Epochengrenze werden zufällige Builder anhand eines nach Stake gewichteten Auswahlverfahrens zugewiesen. Persistente UserBlock-Slots werden über eine holländische Auktion vergeben. Den Zuschlag erhalten die Höchstbietenden, die bereit sind, am meisten SOL zu verbrennen.

Prioritätsreihenfolge von Transaktionen 

Es wird angenommen, dass jeder UserBlock gleichzeitig während des UserBlockSlot erstellt wurde, in dem der Leader ihn codiert hat. Für jeden UserBlock innerhalb des UserBlockSlot werden die Transaktionen vor der Ausführung nach Priority Fee sortiert. Haben Transaktionen aus zwei verschiedenen Blöcken dieselbe Priorität, richtet sich ihre Reihenfolge danach, welcher UserBlock zuerst im PoH des Leaders erscheint. Das bedeutet: Priority Fees bestimmen die Ausführungspriorität. Doppelte oder ungültige Transaktionen in UserBlocks werden ohne Zustandsänderungen übersprungen. Wenn mehrere UserBlockEntries dieselbe Transaktion enthalten, wird die zweite übersprungen.

Oben: In Szenario 1 wird Transaktion B priorisiert, obwohl sie später im PoH-Stream eintrifft. In Szenario 2 wird Transaktion C priorisiert, da sie dieselbe Priority Fee wie Transaktion D hat, ihr Block im PoH-Stream aber früher erscheint.

Bei diesem Design schöpfen die Builder das gesamte MEV ab. Der Vorschlag lässt offen, wie Builder und Leader die Gebühren für Benutzertransaktionen aufteilen sollen.

Builder können auch BundleTransactions erstellen. Das sind Gruppen von Transaktionen innerhalb des UserBlock, die gemeinsam als ein geordneter Batch ausgeführt werden sollen. Diese Transaktionen können außerdem eine Priority Fee hinzufügen, damit das gesamte Bundle als Batch für die Ausführung priorisiert wird, ähnlich wie bei der aktuellen Implementierung von Jito-Bundles.

Epochengrenzen

Stake-Gewichte beeinflussen die Fork-Auswahl und werden an jeder Epochengrenze aktualisiert. Das hat wichtige Folgen für das Design. Validatoren müssen die Ausführung von Transaktionen ohne Votes aufgeholt haben, bevor sie jenseits dieser Epochengrenze weiter abstimmen können.

Yakovenko merkt jedoch an: „[N]odes können nicht so weit zurückfallen, weil die allgemeinen CU-Limits für die synchrone Ausführung festgelegt sind. Mit der Option zur asynchronen Ausführung lässt sich der Rückstand jedoch viel leichter aufholen. Die reine Verarbeitung des Ledgers ohne Einbeziehung des Netzwerks ist 20- bis 30-mal schneller.“

Überlegungen

Mehrere Builder machen die Ressourcenverwaltung komplexer. Clients können den nächstgelegenen Builder wählen, doch die Priority Fees können sich je nach UserBlock unterscheiden. Benutzer wissen beim Senden ihrer Transaktionen wahrscheinlich nicht, welcher Block ausgelastet sein könnte.

Zu den Vorteilen gehört die planbare Zuweisung. Anwendungen können auf den Anteil der Blockbandbreite bieten, den sie für ihren Betrieb benötigen, und dedizierte Sequencer erstellen, die eine spätere Abwicklung auf der Chain garantieren. Zufällige UserBlock-Builder sind unverzichtbar. Sie verhindern, dass persistente Block-Builder Transaktionen zensieren und dauerhaft von der Aufnahme ausschließen.

APE in Solana 2024

In einem im Juni dieses Jahres veröffentlichten X-Artikel mit dem Titel Asynchronous Program Execution (APE) führt Yakovenko das Konzept der Ausführungsdomänen weiter aus, das erstmals im APEX-Vorschlag von 2022 beschrieben wurde.

Die Ausführungsdomänen, ursprünglich Domain 0 und Domain 1, heißen jetzt Vote Execution Domain (VED) und User Execution Domain (UED). Ihr Zweck bleibt unverändert: Consensus-Voting und Transaktionsausführung vollständig voneinander zu isolieren.

Ausführungsdomänen sind als getrennte Gruppen von Programmen sowie den Schlüsseln und Werten definiert, mit denen sie interagieren. Sie werden unabhängig von anderen Gruppen ausgeführt:

  • Ausführungsdomänen können auf verschiedenen Threads und Kernen laufen und auf physisch getrennten Maschinen zu unterschiedlichen Zeiten abgeschlossen werden 
  • Ausführungsdomäne A kann keine Werte in Ausführungsdomäne B lesen oder schreiben 
  • Domänen können einen gemeinsamen Zustand nutzen, der während der Ausführung beider Domänen konsistent bleibt
  • Der Gebührenzahler bestimmt, in welcher Domäne eine Transaktion ausgeführt wird
  • Ein Protokoll muss den Zustand zwischen Domänen synchronisieren und die Übertragung von Schlüsseln und Werten ermöglichen

Komponenten der Vote Execution Domain (VED)

  • SystemProgram: wird für Übertragungen verwendet
  • VoteProgram: Das Kernprogramm für Abstimmungen. Dieses Programm ist statisch und muss sowohl in der UED als auch in der VED vorhanden sein
  • VoteProgram-Sysvars: Variablen für Abstimmungen
  • Vote Authority: Accounts, die zum Abstimmen berechtigt sind
  • Vote Fee Payer: Accounts, die Gebühren für Abstimmungen bezahlen
  • Fee Payer Funder: Ein aktualisierbarer Account, über den SOL in die VED übertragen werden kann

Accounts, die nicht zur VED gehören, gelten als Teil der UED.

Vote-Accounts müssen aktiviert werden. Nach ihrer Aktivierung werden sie in der nächsten Epoche in die VED aufgenommen. Nach der Deaktivierung werden sie in der nächsten Epoche aus der VED entfernt. Für die Übertragung von Mitteln in die VED und aus ihr heraus sind formale Prozesse festgelegt.

Accounts verfolgen nach einer ähnlichen Konvention wie bei Linux-Dateiberechtigungen, welcher Ausführungsdomäne sie zugeordnet sind (R für Lesen, W für Schreiben und X für Ausführen). Es gibt vier gültige Zuordnungen:

Nur Accounts des Vote Program und des System Program können zwischen VED und UED verschoben werden. Das System Program stellt eine Schnittstelle bereit, über die System-Accounts und Vote-Program-Accounts in die VED und aus ihr heraus verschoben werden können. Dieser Ansatz macht einen expliziten FeePayerFunding-Account überflüssig. Jeder System-Account kann zwischen VED und UED neu zugeordnet werden, um Mittel zwischen den Domänen zu übertragen.

Leader führen für die von ihnen erstellten Blöcke nur die VED-Domäne aus. Daher haben sie möglicherweise nur teilweise oder unvollständige Informationen über den Status der UED-Gebührenzahler. Nach dem Empfang eines Blocks führen Validatoren zuerst VED-Transaktionen aus. Anhand des resultierenden VED-Zustands wird der VED Hash berechnet, den Validatoren anschließend zum Abstimmen verwenden. 

Beim UED-Replay werden Transaktionen mit ungültigen Gebührenzahlern übersprungen. Aktualisierungen des UED-Zustands berechnen den Bankhash, der als UED Hash bezeichnet wird. Wenn mindestens ein Drittel der Validatoren abweichende UED Hashes übermittelt, müssen alle Nodes anhalten und die Betreiber warnen.

Aktivierung neuer Funktionen

Da der Consensus jetzt von der Ausführung entkoppelt ist, muss das VoteProgram mit Szenarien umgehen können, in denen VED-Votes Epochengrenzen überschreiten. Dadurch können neue Funktionen zu anderen Zeitpunkten aktiviert werden als bei Transaktionen, die in der UED mit dem VoteProgram interagieren.

Endgame-Architektur 2024

Angesichts der Vielfalt an Anwendungen und Core-Entwicklern lohnt es sich, pro Jahr eine einzige große Protokolländerung zu planen. Wenn wir uns für eine entscheiden müssen, würde ich für die asynchrone Ausführung stimmen.

Anatoly Yakovenko
Anatoly Yakovenko
Mitgründer von Solana

Anfang 2024 veröffentlichte Yakovenko Endgame Architecture, ein Dokument mit einer mutigen Vision für die Zukunft von Solana: ein Netzwerk mit 10.000 Nodes und Blockzeiten von 120 Millisekunden. Das Dokument bekräftigt und erweitert frühere Designvorschläge. Zugleich stellt es die Einführung von AE als Weg heraus, um diese ambitionierte Vision zu verwirklichen.

Leader ohne Bank

Zusammengefasst:

● Leader verwalten einen Cache mit den Guthaben der gebührenzahlenden Accounts

● Wenn ein Gebührenzahler als beschreibbarer Account und Quelle einer Systemübertragung verwendet oder zusammen mit dem System Program als beschreibbarer Account an ein anderes Programm übergeben wird, wird das gebührenzahlende Guthaben auf 0 gesetzt

● Blöcke werden anhand der deklarierten CUs gefüllt, bis der Block gemäß der lokalen Prioritätsreihenfolge für Gebühren voll ist. Dabei werden Transaktionsgebühren vom Cache des Gebührenzahlerguthabens abgezogen 

● Der Cache für Guthaben gebührenzahlender Accounts wird durch die BankHash-Berechnung aufgefüllt 

Leader können die Account-Guthaben der Gebührenzahler zunächst abfragen, indem sie mehrere vollständige Nodes oder RPCs konsultieren. Falls Nodes in seltenen Fällen falsche Daten liefern, führt das zu fehlgeschlagenen Transaktionen statt zu einem Consensus-Ausfall. Veraltete Gebührenzahlerguthaben könnten Spam innerhalb von Blöcken verursachen, ohne den Consensus zu beeinträchtigen. Die Kosten für Spam durch fehlgeschlagene Transaktionen sind relativ gering. Sie umfassen hauptsächlich die Turbine-Bandbreite zur Verbreitung der Transaktionen und den zusätzlichen Speicherplatz, den sie im Ledger belegen. Darüber hinaus arbeiten die Teams von Temporal und Firedancer aktiv an Tools, die Spam eindämmen, bevor er Blöcke erreicht. Dazu implementieren sie Mechanismen wie das Filtern ungültiger Transaktionen, Deduplizierung und das Verhindern von Transaktionen, die aufgrund von Konflikten bei Lese-/Schreibsperren zwangsläufig scheitern.

Dieses Problem lässt sich leicht erkennen und überwachen. Betreiber können die Leistung der Leader verfolgen und das Spamaufkommen in Blöcken bewerten. So können sie Probleme schnell beheben und bei Bedarf zu einer anderen Datenquelle wechseln. Da Validatoren ihre Einnahmen maximieren wollen, haben sie einen Anreiz, einen präzisen Cache der Guthaben gebührenzahlender Accounts zu führen.

Subkomitees mit fester Größe

Die Implementierung von AE in einem großen Netzwerk mit 10.000 Nodes erfordert rotierende Abstimmungskomitees mit fester Größe. Das stellt eine erhebliche Änderung des Consensus-Mechanismus dar. Diese Änderung stabilisiert die Ressourcenkosten des Consensus-Votings unabhängig von der Gesamtzahl der gestakten Nodes. Yakovenko schlägt ein rotierendes Komitee aus 200 oder 400 Nodes vor. So können Validatoren mit minimalen Zustandsanforderungen am Consensus-Voting teilnehmen – beschränkt auf Quorum, Stake-Gewichte und Guthaben der Vote-Accounts. Der Speicherbedarf ist gering. Die zugehörige Snapshot-Datei lässt sich einfach verteilen und bei einem Neustart erneut initialisieren.

Die eigentliche Ironie wird sein, dass ein Solana-Consensus-Validator nach der asynchronen Ausführung auf einem FPGA laufen könnte. Turbine + Tower für 10.000 Vote-Accounts würden problemlos auf einen FPGA passen. Vielleicht etwa 4 MB Zustand zur Nachverfolgung.

Anatoly Yakovenko
Anatoly Yakovenko
Mitgründer von Solana

Rotierende Subkomitees mit fester Größe in Byzantine-Fault-Tolerant-Protokollen (BFT) sind ein etabliertes Konzept, das vergleichbare Netzwerke wie Tron bereits produktiv einsetzen. Es basiert auf dem Committee-Sampling-Ansatz. Dabei übernimmt ein kleineres Komitee den Consensus und übermittelt die Ergebnisse an das gesamte Netzwerk der Replikate.

Ein erster Ansatz für Solana könnte Votes einfach eine feste Anzahl von CUs zuweisen. In jeder Epoche würden die nach Stake größten Validatoren ausgewählt, die in diese CUs passen, um die Fork-Auswahl zu verfolgen. Andere Validatoren würden weiterhin abstimmen und Belohnungen erhalten, ihre Votes würden für die Fork-Auswahl jedoch nicht berücksichtigt.

Vote-Accounts

● Vote-Accounts müssen genügend SOL enthalten, um die Votes für zwei Epochen abzudecken 

● Vote-Transaktionen müssen einfache Votes sein

● SOL darf vom Vote-Account abgehoben werden, wenn das Guthaben die Kosten der Votes für eine Epoche übersteigt

● Um alle Lamports zu entfernen, muss bei der Vote-Anweisung CLOSE eine vollständige Epoche vergehen. Vote-Accounts werden in Epoche eins für CLOSE markiert, können aber erst in Epoche 2 CLOSE werden

CLOSE ermöglicht es, alle SOL abzuheben und den Vote-Account zu löschen. Sobald ein Account für CLOSE markiert wurde, kann er nur noch gelöscht und nicht erneut geöffnet werden

● Votes enthalten einen VoteBankHash anstelle eines regulären BankHash 

BankHashes

Validatoren berechnen für einfache Vote-Transaktionen einen VoteBankHash. Dabei verwenden sie dasselbe Format wie beim aktuellen BankHash und ignorieren alle anderen Transaktionen. Diese VoteBankHashes beziehen den vorherigen VoteBankHash statt des vollständigen BankHash ein.

Bei Blöcken, die von einer Zweidrittel-Supermehrheit optimistisch bestätigt wurden, beginnen Validatoren außerdem mit der Berechnung des UserBankHash. Dieser umfasst alle Zustandsübergänge außer denen, die bereits im VoteBankHash berücksichtigt wurden.

Für jeden Slot wird ein BankHash berechnet, indem der VoteBankHash, der UserBankHash und der vorherige BankHash kombiniert werden. Die obersten 99,5 % der Validatoren übermitteln diesen BankHash in jedem 100. Slot als Teil ihres Votes. Zusätzlich können einige Nodes den BankHash über das Gossip-Netzwerk verbreiten, um zu signalisieren, dass kein Nichtdeterminismus erkannt wurde.

Wenn weniger als zwei Drittel der Validatoren den vollständigen BankHash übermitteln, können Leader den Blockspace für Benutzertransaktionen und beschreibbare Accounts um 50 % reduzieren. Das verhindert Exploits, die die Replay-Zeit übermäßig verlängern könnten.

Der Zustand muss nur einmal pro Epoche berechnet werden, um das nächste Quorum festzulegen und Consensus-Nodes und Leader synchron zu halten. Die Ausführung kann auf Maschinen getrennt von den Consensus-Nodes aggregiert und gebündelt werden. Benutzer, die synchrone Ausführung benötigen – darunter die meisten Anwendungen und RPCs –, können dedizierte Hardwareressourcen einsetzen, um jeden Zustandsübergang in Echtzeit zu verarbeiten, ohne auf das übrige Netzwerk zu warten.

Überlegungen

RPC-Anbieter, die Benutzern Zustandsdaten in Echtzeit bereitstellen, haben keine Signatur, mit der sie prüfen können, ob ihr lokal berechneter Zustand dem Zustand des übrigen Netzwerks entspricht. Sobald ein Fork finalisiert ist, konvergiert das Netzwerk jedoch auf einen einzigen korrekten kanonischen Zustand, der sich deterministisch berechnen lässt. Nodes, die präzise Zustandsdaten bereitstellen wollen, sollten mehrere Nodes betreiben, um das Risiko von Laufzeitfehlern oder Datenbeschädigungen zu minimieren. Sobald Abweichungen bei der Zustandsausführung erkannt werden, muss der Betrieb sofort gestoppt werden.

Außerdem können Benutzer Transaktionen übermitteln, die den BankHash bestätigen oder einen Abbruch auslösen. Das Netzwerk verarbeitet diese Transaktionen nur, wenn der berechnete BankHash mit dem Wert übereinstimmt, den der RPC-Anbieter dem Benutzer bereitgestellt hat.

Fazit

Yakovenko entwirft eine ambitionierte Zukunft für Solana: Blockzeiten von nur 120 Millisekunden und deutlich mehr Nodes, ermöglicht durch die Einführung von AE. Um diese Zukunft zu verwirklichen, müssen sich jedoch eigenständige Client-Teams und die breitere Solana-Entwickler-Community hinter dieser Vision versammeln und die erheblichen technischen Herausforderungen solcher Änderungen bewältigen. 

Bekannte Mitglieder der Community haben Bedenken zu vielen dieser vorgeschlagenen Änderungen geäußert. Richard Patel aus dem Firedancer-Team warnte, dass „die Implementierung asynchroner Ausführung für Blockproduzenten ziemlich komplex ist und erhebliche Risiken birgt.“

Obwohl Zano Sherwani von Jito Labs AE unterstützt, kritisierte er MCBP und erklärte: „Multiple Concurrent Proposers ist eine schreckliche Lösung auf der Suche nach einem Problem. Die zusätzliche Komplexität für das Protokoll steht in keinem Verhältnis zu dem, was damit gelöst werden soll – falls überhaupt etwas.“

Als Mert Mumtaz von Helius in einem kürzlich veröffentlichten Podcast zu mehreren Block-Buildern befragt wurde, antwortete er: „Ich bin nicht vollständig überzeugt.“

AE kann zweifellos erhebliche Leistungsvorteile bieten. Kürzere Blockzeiten führen zu schnelleren Bestätigungen und einer besseren Benutzererfahrung. Gleichzeitig erhöhen sie die Zensurresistenz und verkürzen das Zeitfenster für die Neuanordnung von Transaktionen.

Wir müssen jedoch auch die Nachteile sorgfältig abwägen. Dazu gehören eine potenziell höhere Protokollkomplexität und eine stärkere Abhängigkeit von RPC-Anbietern. In bestimmten Szenarien sind diese Anbieter möglicherweise die einzigen Teilnehmer mit einer aktuellen Echtzeitansicht des Chain-Zustands.

AE ist ein bedeutendes Upgrade für Solana. Mit diesem Artikel möchten wir die Solana-Entwickler-Community auf die spannenden Änderungen aufmerksam machen, die AE mit sich bringen wird, und eine fundiertere Diskussion über dieses wichtige Thema fördern.

Vielen Dank an 0xIchigo und Anatoly Yakovenko für die Durchsicht früherer Versionen dieses Beitrags.

Weitere Ressourcen

Helius abonnieren

Bleib bei der Solana-Entwicklung auf dem Laufenden und erhalte Updates, wenn wir neue Beiträge veröffentlichen

Vergrößertes Bild