# Ausführung, Familien und Shards

> Ein Hart, eine 38-Bit-Uhr, jeder Speicherzugriff als Abfrage mit Zeitstempel, 23 Schaltkreisfamilien und der Shard als Einheit des Beweisens.

## Die Maschine

Der Emulator führt RV32IMAC auf einem Hart über einem `ProgramImage` aus, ohne Interrupts und ohne Privilegstufen. Ein Lauf ist eine reine Funktion des Images und seiner Eingabe, ohne Uhr, Zufall oder Threads; zwei Läufe schneiden also identische Shards. Von einer gehosteten RV32IMAC-Umgebung weicht er in drei Punkten ab: `sc.w` gelingt immer, ein nicht ausgerichteter Halbwort- oder Wortzugriff ist fatal, statt aufgeteilt zu werden, und der Befehlsstrom ist das beim Laden dekodierte Image.

Jede andere Art, wie ein Lauf vor `EXIT` enden kann, etwa ein Zugriff außerhalb der gemappten Bereiche, `ebreak` oder ein Sprung zu einem Halbwort ohne Befehl, ist ein fataler Fehler ohne Trace. Ein solcher Lauf hat keinen Beweis. Ein Exit-Status ungleich null ist kein Fehler: Es handelt sich um eine Ausführung wie jede andere, und sie ist beweisbar.

## Die Uhr und die Abfrage

Zyklus `c` belegt die vier Zeitstempel `4c + Δ`, einen pro **Slot** `Δ ∈ {0, 1, 2, 3}`. Jeder Befehl ist ein Zyklus, und sonst ist nichts ein Zyklus: Ein Delegationsaufruf läuft im Zyklus mit, der ihn angefordert hat. Zyklen werden ab 1 gezählt, weil Zeitstempel 0 der anfängliche Schreibzugriff jeder Adresse ist. Die Uhr hat 38 Bit; eine Ausführung läuft also höchstens `2^36 − 1` Zyklen.

Jeder Speicherzugriff ist eine **Abfrage**: ein Lesezugriff auf einen Wert, der zuletzt zu einem früheren Zeitstempel geschrieben wurde, und ein Schreibzugriff zum aktuellen Zeitstempel. Eine Abfrage, die nur liest, schreibt zurück, was sie gelesen hat. Slot 0 jedes Zyklus ist die pc-Abfrage, die `pc` liest und `next_pc` schreibt. Danach folgen die Register- und Speicherabfragen des Befehls an festen Slots:

| Klasse | Δ = 1 | Δ = 2 | Δ = 3 |
| --- | --- | --- | --- |
| Register-Immediate, `jalr` | `rs1` | | `rd` |
| Verzweigungen | `rs1` | `rs2` | |
| Register-Register, M | `rs1` | `rs2` | `rd` |
| Loads | `rs1` | das Wort, gelesen | `rd` |
| Stores | `rs1` | `rs2` | das Wort, mit eingesetzten gespeicherten Bytes |
| Atomics | `rs1` | `rs2` | das Wort und `rd` |
| `ecall` | `a7` | `a0` | `a0` und die Spiegelabfrage einer Delegation |

Adressen liegen in **Adressräumen**: die 32 Register, der RAM in Wörtern mit 4-Byte-Ausrichtung, der pc, ein Ankerraum pro Delegationstyp und die Körperzellen des Rekursionsformats. `x0` ist im Trace ein gewöhnliches Register und in der Maschine eine Konstante: Jede Abfrage an diesem Register liest und schreibt 0.

## Dreiundzwanzig Familien

Eine **Familie** ist ein Schaltkreis zusammen mit den Zeilen, die er beweist. Es gibt vier Arten:

| Art | Familien | Eine Zeile ist |
| --- | --- | --- |
| Ausführung | 0–6: `ADD_SUB_LUI_AUIPC`, `JUMP_BRANCH_SLT`, `SHIFT_BITWISE`, `MUL_DIV`, `MEM_WORD`, `MEM_SUBWORD`, `ATOMICS` | ein ausgeführter Befehl |
| Fenster | 7 `INIT_TEARDOWN`, 8 `ZERO_WINDOWS`, 12 `PUBLIC_INPUT`, 13 `PUBLIC_OUTPUT`, 14 `ADVICE_WINDOWS` | ein Speicherwort, initialisiert und abgeschlossen |
| Delegation | 9 `KECCAK_F`, 10 `POSEIDON2`, 11 `FR_ARITH`, 15 `MOD_MUL`, 16 `SHA256_COMP`, 17 `EC_ADD` | ein Aufruf über einem Frame aus RAM |
| Rekursion | 18 `FIELD_WINDOWS`, 19 `FR_OP`, 20 `P2_FIELD`, 21 `FIELD_IO`, 22 `FQ_OP` | eine Körperzelle oder eine Koprozessor-Operation |

Jeder Zyklus geht an die eine Ausführungsfamilie, deren dekodierte Tabelle seinen pc beansprucht. Familien wechseln sich zeitlich ab: `ADD_SUB_LUI_AUIPC` kann die Zyklen 1 und 3 besitzen und `JUMP_BRANCH_SLT` den Zyklus 2. Nichts verlangt, dass sie zusammenhängend sind, weil das Speicherargument jede Zeile über ihren pc-Schreibzugriff ordnet.

Die Fensterfamilien gibt es, weil das Speicherargument verlangt, dass jede Adresse, die eine Ausführung berührt, genau einen Anfangswert und einen Endwert hat. `INIT_TEARDOWN` deckt RAM-Fenster 0 ab und belegt es zu Beginn mit dem Image des Programms; `ZERO_WINDOWS` deckt jedes andere Fenster gewöhnlichen RAMs ab, das der Lauf berührt hat, und belegt es zu Beginn mit null; das öffentliche Paar deckt die Fenster für Eingabe und Journal ab; `ADVICE_WINDOWS` deckt den Bereich der Hilfsdaten (Advice) ab und belegt ihn zu Beginn mit den Bytes des Provers.

## Shards

Die Zeilen einer Familie werden in der Reihenfolge ihres Auftretens in **Shards** der Höhe dieser Familie geschnitten. Der letzte wird mit Nullzeilen aufgefüllt, die die Schaltkreise per Konstruktion akzeptieren. Ein Shard kostet seine volle Höhe, unabhängig von seiner Belegung; die Familien, die ein Programm berührt, und die Höhen, die es wählt, bestimmen also die Untergrenze jedes Beweises.

| Familie | Standardhöhe | Warum |
| --- | --- | --- |
| Befehlsfamilien | `2^22`, `2^20` für `MUL_DIV` und `ATOMICS` | die Untergrenze ihrer Range-Checks für Zeitstempel ist `2^20` |
| RAM-Fenster | `2^22` | eine gemeinsame Fensterhöhe, mindestens `2^16` |
| Öffentliche Eingabe, Journal | `2^12` | fest: Die Höhe bestimmt die Lage der Fenster |
| `KECCAK_F`, `SHA256_COMP` | `2^18` | viermal so viele Aufrufe wie bei ihrer Untergrenze `2^16`, bei einem um 2 % größeren Beweis |
| `MOD_MUL`, `EC_ADD` | `2^16` | ihre Untergrenze |
| `POSEIDON2`, `FR_ARITH` | `2^8` | keine Tabelle, also keine Untergrenze |

Ein Shard wird für sich bewiesen, durch den Schaltkreis seiner Familie, mit Ausnahme des Speicherarguments: Der Schaltkreis jedes Shards gibt das Produkt seiner Lesetupel und das Produkt seiner Schreibtupel aus, und der Verifier gleicht diese Produkte einmal über alle Shards der Aussage ab. Das ist das Einzige, was Shards verbindet. Es gibt keine Verkettung des pc von Shard zu Shard und keinen gemeinsamen Rand zwischen Nachbarn.

Die Größen der Shard-Beweise bei den Standardhöhen reichen von etwa 12,5 KB für ein öffentliches Fenster bis zu 665 KB für einen `POSEIDON2`-Shard; der Beweis einer Befehlsfamilie liegt bei 64 bis 77 KB. Die Tabelle steht unter [Performance](https://apogee.gweb3networks.com/docs/architecture/performance).

Die Spezifikation: [Ausführungs-Trace](https://apogee.gweb3networks.com/docs/auditors/spec/execution-trace), [Schaltkreise und Registry](https://apogee.gweb3networks.com/docs/auditors/spec/circuits).
