@@ -44,48 +44,17 @@ There are 3 types of witness data involved in onchain execution:
...
@@ -44,48 +44,17 @@ There are 3 types of witness data involved in onchain execution:
### Packed State
### Packed State
The following state is packed together, and provided in every executed onchain instruction:
The Packed State is provided in every executed onchain instruction.
```solidity
See [Cannon VM Specs](../../specs/cannon-fault-proof-vm.md#state) for
struct State {
details on the state structure.
bytes32 memRoot;
bytes32 preimageKey;
uint32 preimageOffset;
uint32 pc;
uint32 nextPC;
uint32 lo;
uint32 hi;
uint32 heap;
uint8 exitCode;
bool exited;
uint64 step;
uint32[32] registers;
}
```
The packed state is small! The `State` data can be packed in such a small amount of EVM words,
The packed state is small! The `State` data can be packed in such a small amount of EVM words,
that it is more efficient to fully provide it, than to create a proof for each individual part involved in execution.
that it is more efficient to fully provide it, than to create a proof for each individual part involved in execution.
The memory is represented as a merkle-tree root, committing to a binary merkle tree of all memory data,
see [memory proofs](#memory-proofs).
The `State` covers all general purpose registers, as well as the `lo`, `hi` and `pc` values.
`nextPC` helps pre-schedule the program counter change, to emulate delay-slot behavior of MIPS
after branch and jump instructions.
The program stops changing the state when `exited` is set to true. The exit-code is remembered,
The program stops changing the state when `exited` is set to true. The exit-code is remembered,
to determine if the program is successful, or panicked/exited in some unexpected way.
to determine if the program is successful, or panicked/exited in some unexpected way.
This outcome can be used to determine truthiness of claims that are verified as part of the program execution.
This outcome can be used to determine truthiness of claims that are verified as part of the program execution.
The `heap` value is a special value, used to emulate a growing heap, to map new memory upon `mmap` calls by the program.
No memory reads/writes are actually illegal however, mmap-ing is purely to satisfy program runtimes that
need the memory-pointer result of the syscall to locate free memory.
The `preimageKey` and `preimageOffset` are backing the in-flight communication of [pre-image data](#pre-image-data).
The VM `stateHash` is computed as `keccak256(encoded_packed_state)`,
where `encoded_packed_state` is the concatenation of all state-values (all `uint` values are big-endian).
### Memory proofs
### Memory proofs
...
@@ -133,11 +102,7 @@ Pre-image data is accessed through syscalls exclusively.
...
@@ -133,11 +102,7 @@ Pre-image data is accessed through syscalls exclusively.
The OP-stack fault-proof [Pre-image Oracle specs](../../specs/fault-proof.md#pre-image-oracle)
The OP-stack fault-proof [Pre-image Oracle specs](../../specs/fault-proof.md#pre-image-oracle)
define the ABI for communicating pre-images.
define the ABI for communicating pre-images.
This ABI is implemented by the VM by intercepting the `read`/`write` syscalls to specific file descriptors:
This ABI is implemented by the VM by intercepting the `read`/`write` syscalls to specific file descriptors. See [Cannon VM Specs](../../specs/cannon-fault-proof-vm.md#io) for more details.
-`hint client read = 3`: used by the client to send hint data to the host. Optional, implemented as blocking.
-`hint client write = 4`: used by the client to wait for the host. Always instant, since the above is implemented as blocking.
-`preimage client read = 5`: used by the client to read pre-image data, starting from the latest pre-image reading offset.
-`preimage client write = 6`: used by the client to change the pre-image key. The key may change a little bit at a time. The last 32 written bytes count as key for retrieval when reading the pre-image. Changing the key also resets the read offset to 0.
The data is loaded into `PreimageOracle.sol` using the respective loading function based on the pre-image type.
The data is loaded into `PreimageOracle.sol` using the respective loading function based on the pre-image type.
And then retrieved during execution of the `read` syscall.
And then retrieved during execution of the `read` syscall.
@@ -66,7 +66,9 @@ location as the entire address space is unprotected.
...
@@ -66,7 +66,9 @@ location as the entire address space is unprotected.
### Heap
### Heap
FPVM state contains a `heap` that tracks the base address of the most recent memory allocation.
FPVM state contains a `heap` that tracks the base address of the most recent memory allocation.
Heap pages are bump allocated at the page boundary, per `mmap` syscall. The page size is 4096.
Heap pages are bump allocated at the page boundary, per `mmap` syscall.
mmap-ing is purely to satisfy program runtimes that need the memory-pointer
result of the syscall to locate free memory. The page size is 4096.
The FPVM has a fixed program break at `0x40000000`. However, the FPVM is permitted to extend the
The FPVM has a fixed program break at `0x40000000`. However, the FPVM is permitted to extend the
heap beyond this limit via mmap syscalls.
heap beyond this limit via mmap syscalls.
...
@@ -105,8 +107,9 @@ The following table list summarizes the supported syscalls and their behaviors.
...
@@ -105,8 +107,9 @@ The following table list summarizes the supported syscalls and their behaviors.
| 4004 | write | uint32 fd | char *buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned writes. See [I/O](#io) for more details. |
| 4004 | write | uint32 fd | char *buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned writes. See [I/O](#io) for more details. |
| 4055 | fcntl | uint32 fd | int32 cmd | | Similar behavior as Linux/MIPS. Only the `F_GETFL` (3) cmd is supported. Sets errno to `0x16` for all other commands |
| 4055 | fcntl | uint32 fd | int32 cmd | | Similar behavior as Linux/MIPS. Only the `F_GETFL` (3) cmd is supported. Sets errno to `0x16` for all other commands |
For all of the above syscalls, an error is indicated by setting the return register (`$v0`) to
For all of the above syscalls, an error is indicated by setting the return
`0xFFFFFFFF` (-1) and `errno` (`$a3`) is set accordingly.
register (`$v0`) to `0xFFFFFFFF` (-1) and `errno` (`$a3`) is set accordingly.
The VM must not modify any register other than `$v0` and `$a3` during syscall handling.
For unsupported syscalls, the VM must do nothing except to zero out the syscall return (`$v0`)
For unsupported syscalls, the VM must do nothing except to zero out the syscall return (`$v0`)