Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(yellowpaper): avm tree-access operations #4552

Merged
merged 8 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions avm-transpiler/src/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,18 @@ pub enum AvmOpcode {
CMOV,

// World State
BLOCKHEADERBYNUMBER,
SLOAD, // Public Storage
SSTORE, // Public Storage
READL1TOL2MSG, // Messages
SENDL2TOL1MSG, // Messages
EMITNOTEHASH, // Notes & Nullifiers
EMITNULLIFIER, // Notes & Nullifiers
SLOAD, // Public Storage
SSTORE, // Public Storage
NOTEHASHEXISTS, // Notes & Nullifiers
EMITNOTEHASH, // Notes & Nullifiers
NULLIFIEREXISTS, // Notes & Nullifiers
EMITNULLIFIER, // Notes & Nullifiers
READL1TOL2MSG, // Messages
HEADERMEMBER, // Archive tree & Headers

// Accrued Substate
EMITUNENCRYPTEDLOG,
SENDL2TOL1MSG,

// Control Flow - Contract Calls
CALL,
Expand Down Expand Up @@ -143,16 +145,18 @@ impl AvmOpcode {
AvmOpcode::CMOV => "CMOV",

// World State
AvmOpcode::BLOCKHEADERBYNUMBER => "BLOCKHEADERBYNUMBER",
AvmOpcode::SLOAD => "SLOAD", // Public Storage
AvmOpcode::SSTORE => "SSTORE", // Public Storage
AvmOpcode::NOTEHASHEXISTS => "NOTEHASHEXISTS", // Notes & Nullifiers
AvmOpcode::EMITNOTEHASH => "EMITNOTEHASH", // Notes & Nullifiers
AvmOpcode::NULLIFIEREXISTS => "NULLIFIEREXISTS", // Notes & Nullifiers
AvmOpcode::EMITNULLIFIER => "EMITNULLIFIER", // Notes & Nullifiers
AvmOpcode::READL1TOL2MSG => "READL1TOL2MSG", // Messages
AvmOpcode::SENDL2TOL1MSG => "SENDL2TOL1MSG", // Messages
AvmOpcode::EMITNOTEHASH => "EMITNOTEHASH", // Notes & Nullifiers
AvmOpcode::EMITNULLIFIER => "EMITNULLIFIER", // Notes & Nullifiers
AvmOpcode::HEADERMEMBER => "HEADERMEMBER", // Archive tree & Headers

// Accrued Substate
AvmOpcode::EMITUNENCRYPTEDLOG => "EMITUNENCRYPTEDLOG",
AvmOpcode::SENDL2TOL1MSG => "SENDL2TOL1MSG",

// Control Flow - Contract Calls
AvmOpcode::CALL => "CALL",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,18 @@ const std::unordered_map<OpCode, size_t> Bytecode::OPERANDS_NUM = {
//{ OpCode::CMOV, },

//// World State
//{ OpCode::BLOCKHEADERBYNUMBER, },
//{ OpCode::SLOAD, }, // Public Storage
//{ OpCode::SSTORE, }, // Public Storage
//{ OpCode::READL1TOL2MSG, }, // Messages
//{ OpCode::SENDL2TOL1MSG, }, // Messages
//{ OpCode::NOTEHASHEXISTS, }, // Notes & Nullifiers
//{ OpCode::EMITNOTEHASH, }, // Notes & Nullifiers
//{ OpCode::NULLIFIEREXISTS, }, // Notes & Nullifiers
//{ OpCode::EMITNULLIFIER, }, // Notes & Nullifiers
//{ OpCode::READL1TOL2MSG, }, // Messages
//{ OpCode::HEADERMEMBER, },

//// Accrued Substate
//{ OpCode::EMITUNENCRYPTEDLOG, },
//{ OpCode::SENDL2TOL1MSG, },

//// Control Flow - Contract Calls
//{ OpCode::CALL, },
Expand Down Expand Up @@ -135,14 +137,16 @@ bool Bytecode::has_in_tag(OpCode const op_code)
case OpCode::INTERNALRETURN:
case OpCode::MOV:
case OpCode::CMOV:
case OpCode::BLOCKHEADERBYNUMBER:
case OpCode::SLOAD:
case OpCode::SSTORE:
case OpCode::READL1TOL2MSG:
case OpCode::SENDL2TOL1MSG:
case OpCode::NOTEHASHEXISTS:
case OpCode::EMITNOTEHASH:
case OpCode::NULLIFIEREXISTS:
case OpCode::EMITNULLIFIER:
case OpCode::READL1TOL2MSG:
case OpCode::HEADERMEMBER:
case OpCode::EMITUNENCRYPTEDLOG:
case OpCode::SENDL2TOL1MSG:
case OpCode::CALL:
case OpCode::STATICCALL:
case OpCode::RETURN:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,18 @@ enum class OpCode : uint8_t {
CMOV,

// World State
BLOCKHEADERBYNUMBER,
SLOAD, // Public Storage
SSTORE, // Public Storage
READL1TOL2MSG, // Messages
SENDL2TOL1MSG, // Messages
EMITNOTEHASH, // Notes & Nullifiers
EMITNULLIFIER, // Notes & Nullifiers
SLOAD, // Public Storage
SSTORE, // Public Storage
NOTEHASHEXISTS, // Notes & Nullifiers
EMITNOTEHASH, // Notes & Nullifiers
NULLIFIEREXISTS, // Notes & Nullifiers
EMITNULLIFIER, // Notes & Nullifiers
READL1TOL2MSG, // Messages
HEADERMEMBER, // Archive tree & Headers

// Accrued Substate
EMITUNENCRYPTEDLOG,
SENDL2TOL1MSG, // Messages

// Control Flow - Contract Calls
CALL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,25 @@ const INSTRUCTION_SET = () =>
[FeePerL1Gas.opcode, FeePerL1Gas],
[FeePerL2Gas.opcode, FeePerL2Gas],
[FeePerDAGas.opcode, FeePerDAGas],
// [Contractcalldepth.opcode, Contractcalldepth],
//[Contractcalldepth.opcode, Contractcalldepth],
// Execution Environment - Globals
[ChainId.opcode, ChainId],
[Version.opcode, Version],
[BlockNumber.opcode, BlockNumber],
[Timestamp.opcode, Timestamp],
// [Coinbase.opcode, Coinbase],
// [Blockl1gaslimit.opcode, Blockl1gaslimit],
// [Blockl2gaslimit.opcode, Blockl2gaslimit],
// [Blockdagaslimit.opcode, Blockdagaslimit],
// // Execution Environment - Calldata
//[Coinbase.opcode, Coinbase],
//[Blockl1gaslimit.opcode, Blockl1gaslimit],
//[Blockl2gaslimit.opcode, Blockl2gaslimit],
//[Blockdagaslimit.opcode, Blockdagaslimit],
// Execution Environment - Calldata
[CalldataCopy.opcode, CalldataCopy],

// //// Machine State
// // Machine State - Gas
// //[L1gasleft.opcode, L1gasleft],
// //[L2gasleft.opcode, L2gasleft],
// //[Dagasleft.opcode, Dagasleft],
// //// Machine State - Internal Control Flow
// Machine State
// Machine State - Gas
//[L1gasleft.opcode, L1gasleft],
//[L2gasleft.opcode, L2gasleft],
//[Dagasleft.opcode, Dagasleft],
// Machine State - Internal Control Flow
[Jump.opcode, Jump],
[JumpI.opcode, JumpI],
[InternalCall.opcode, InternalCall],
Expand All @@ -107,27 +107,29 @@ const INSTRUCTION_SET = () =>
[Mov.opcode, Mov],
[CMov.opcode, CMov],

// //// World State
// //[Blockheaderbynumber.opcode, Blockheaderbynumber],
// World State
[SLoad.opcode, SLoad], // Public Storage
[SStore.opcode, SStore], // Public Storage
// //[Readl1tol2msg.opcode, Readl1tol2msg], // Messages
[SendL2ToL1Message.opcode, SendL2ToL1Message], // Messages
//[NoteHashExists.opcode, NoteHashExists], // Notes & Nullifiers
[EmitNoteHash.opcode, EmitNoteHash], // Notes & Nullifiers
//[NullifierExists.opcode, NullifierExists], // Notes & Nullifiers
[EmitNullifier.opcode, EmitNullifier], // Notes & Nullifiers
//[Readl1tol2msg.opcode, Readl1tol2msg], // Messages
//[HeaderMember.opcode, HeaderMember], // Header

// //// Accrued Substate
// Accrued Substate
[EmitUnencryptedLog.opcode, EmitUnencryptedLog],
[SendL2ToL1Message.opcode, SendL2ToL1Message],

// //// Control Flow - Contract Calls
// Control Flow - Contract Calls
[Call.opcode, Call],
[StaticCall.opcode, StaticCall],
[Return.opcode, Return],
[Revert.opcode, Revert],

// //// Gadgets
// //[Keccak.opcode, Keccak],
// //[Poseidon.opcode, Poseidon],
// Gadgets
//[Keccak.opcode, Keccak],
//[Poseidon.opcode, Poseidon],
]);

interface Serializable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,16 @@ export enum Opcode {
SET,
MOV,
CMOV,
BLOCKHEADERBYNUMBER,
SLOAD, // Public Storage
SSTORE, // Public Storage
READL1TOL2MSG, // Messages
SENDL2TOL1MSG, // Messages
EMITNOTEHASH, // Notes & Nullifiers
EMITNULLIFIER, // Notes & Nullifiers
SLOAD,
SSTORE,
NOTEHASHEXISTS,
EMITNOTEHASH,
NULLIFIEREXISTS,
EMITNULLIFIER,
READL1TOL2MSG,
HEADERMEMBER,
EMITUNENCRYPTEDLOG,
SENDL2TOL1MSG,
CALL,
STATICCALL,
RETURN,
Expand Down
84 changes: 51 additions & 33 deletions yellow-paper/docs/public-vm/avm.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ The entirety of a contract's public code is represented as a single block of byt
Many terms and definitions here are borrowed from the [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf).
:::

Initialized by a contract call, an **execution context** includes the information necessary to initiate AVM execution along with all state maintained by the AVM throughout execution:
An **execution context** includes the information and state relevant to a contract call's execution. When a contract call is made, an execution context is initialized as specified in the ["Initial contract calls"](#initial-contract-calls) and ["Nested contract calls"](#nested-contract-calls) sections.

#### _AvmContext_
| Field | Type |
Expand All @@ -62,7 +62,7 @@ Initialized by a contract call, an **execution context** includes the informatio

### Execution Environment

A context's **execution environment** remains constant throughout the context's execution. When a contract call initializes its execution context, it fully specifies the execution environment.
A context's **execution environment** remains constant throughout a contract call's execution. When a contract call initializes its execution context, it fully specifies the execution environment. This is expanded on in the ["Initial contract calls"](#initial-contract-calls) and ["Nested contract calls"](#nested-contract-calls) sections.

#### _ExecutionEnvironment_
| Field | Type | Description |
Expand All @@ -87,10 +87,10 @@ A context's **execution environment** remains constant throughout the context's
Finally, when a contract call halts, it sets the context's **contract call results** to communicate results to the caller.

#### _ContractCallResults_
| Field | Type | Description |
| --- | --- | --- |
| `reverted` | `boolean` | |
| `output` | `[field; <output-length>]` | |
| Field | Type | Description |
| --- | --- | --- |
| reverted | `boolean` | |
| output | `[field; <output-length>]` | |

## Execution

Expand Down Expand Up @@ -210,9 +210,9 @@ The AVM's exceptional halting conditions area listed below:
1. **World state modification attempt during a static call**
```
assert !environment.isStaticCall
OR environment.bytecode[machineState.pc].opcode not in WS_MODIFYING_OPS
OR environment.bytecode[machineState.pc].opcode not in WS_AS_MODIFYING_OPS
```
> Definition: `WS_MODIFYING_OPS` represents the list of all opcodes corresponding to instructions that modify world state.
> Definition: `WS_AS_MODIFYING_OPS` represents the list of all opcodes corresponding to instructions that modify world state or accrued substate.
1. **Maximum contract call depth (1024) exceeded**
```
assert environment.contractCallDepth <= 1024
Expand All @@ -231,35 +231,57 @@ The AVM's exceptional halting conditions area listed below:
assert environment.bytecode[machineState.pc].opcode != INTERNALCALL
OR environment.contractCallDepth < 1024
```
1. **Maximum world state accesses (1024-per-type) exceeded**
1. **Maximum world state accesses (1024-per-category) exceeded**
```
assert publicStorageAccesses.length <= 1024
AND l1ToL2MessagesReads.length <= 1024
AND newL2ToL1Messages.length <= 1024
AND newNoteHashes.length <= 1024
AND newNullifiers.length <= 1024
assert worldStateAccessTrace.publicStorageReads.length <= 1024
AND worldStateAccessTrace.publicStorageWrites.length <= 1024
AND worldStateAccessTrace.noteHashChecks.length <= 1024
AND worldStateAccessTrace.newNoteHashes.length <= 1024
AND worldStateAccessTrace.nullifierChecks.length <= 1024
AND worldStateAccessTrace.newNullifiers.length <= 1024
AND worldStateAccessTrace.l1ToL2MessageReads.length <= 1024
AND worldStateAccessTrace.archiveChecks.length <= 1024

// Storage
assert environment.bytecode[machineState.pc].opcode not in {SLOAD, SSTORE}
OR publicStorageAccesses.length < 1024

// L1 to L2 messages
assert environment.bytecode[machineState.pc].opcode != GETL1TOL2MSG
OR l1ToL2MessagesReads.length < 1024

// L2 to L1 messages
assert environment.bytecode[machineState.pc].opcode != SENDL2TOL1MSG
OR newL2ToL1Messages.length < 1024
assert environment.bytecode[machineState.pc].opcode != SLOAD
OR worldStateAccessTrace.publicStorageReads.length < 1024
assert environment.bytecode[machineState.pc].opcode != SSTORE
OR worldStateAccessTrace.publicStorageWrites.length < 1024

// Note hashes
assert environment.bytecode[machineState.pc].opcode != NOTEHASHEXISTS
OR noteHashChecks.length < 1024
assert environment.bytecode[machineState.pc].opcode != EMITNOTEHASH
OR newNoteHashes.length < 1024

// Nullifiers
assert environment.bytecode[machineState.pc].opcode != NULLIFIEREXISTS
OR nullifierChecks.length < 1024
assert environment.bytecode[machineState.pc].opcode != EMITNULLIFIER
OR newNullifiers.length < 1024

// Read L1 to L2 messages
assert environment.bytecode[machineState.pc].opcode != READL1TOL2MSG
OR worldStateAccessTrace.l1ToL2MessagesReads.length < 1024

// Archive tree & Headers
assert environment.bytecode[machineState.pc].opcode != HEADERMEMBER
OR archiveChecks.length < 1024
```
1. **Maximum accrued substate entries (per-category) exceeded**
```
> Definition: `WS_MODIFYING_OPS` represents the list of all opcodes corresponding to instructions that modify world state.
assert accruedSubstate.unencryptedLogs.length <= MAX_UNENCRYPTED_LOGS
AND accruedSubstate.sentL2ToL1Messages.length <= MAX_SENT_L2_TO_L1_MESSAGES

// Unencrypted logs
assert environment.bytecode[machineState.pc].opcode != ULOG
OR unencryptedLogs.length < MAX_UNENCRYPTED_LOGS

// Sent L2 to L1 messages
assert environment.bytecode[machineState.pc].opcode != SENDL2TOL1MSG
OR sentL2ToL1Messages.length < MAX_SENT_L2_TO_L1_MESSAGES
```
> Note that ideally the AVM should limit the _total_ accrued substate entries per-category instead of the entries per-call.

## Initial contract calls

Expand All @@ -273,8 +295,8 @@ context = AvmContext {
environment = INITIAL_EXECUTION_ENVIRONMENT,
machineState = INITIAL_MACHINE_STATE,
worldState = <latest world state>,
worldStateAccessTrace = { [], [], ... [] } // all trace vectors empty,
accruedSubstate = INITIAL_ACCRUED_SUBSTATE,
worldStateAccessTrace = { [], [], ... [] }, // all trace vectors empty,
accruedSubstate = { [], ... [], }, // all substate vectors empty
results = INITIAL_CONTRACT_CALL_RESULTS,
}
```
Expand Down Expand Up @@ -310,10 +332,6 @@ INITIAL_MACHINE_STATE = MachineState {
memory = [0, ..., 0], // all 2^32 entries are initialized to zero
}

INITIAL_ACCRUED_SUBSTATE = AccruedSubstate {
unencryptedLogs = [], // initialized as empty
}

INITIAL_CONTRACT_CALL_RESULTS = ContractCallResults {
reverted = false,
output = [], // initialized as empty
Expand All @@ -334,7 +352,7 @@ nestedContext = AvmContext {
machineState: nestedMachineState, // defined below
worldState: callingContext.worldState,
worldStateAccessTrace: callingContext.worldStateAccessTrace,
accruedSubstate: INITIAL_ACCRUED_SUBSTATE,
accruedSubstate = { [], ... [], }, // all substate vectors empty
results: INITIAL_CONTRACT_CALL_RESULTS,
}
```
Expand Down Expand Up @@ -425,7 +443,7 @@ if !nestedContext.results.reverted AND instr.opcode != STATICCALL_OP:
Regardless of whether a nested context has reverted, its [world state access trace](./state#world-state-access-trace) updates are absorbed into the calling context along with a new `contractCalls` entry.
```
context.worldStateAccessTrace = nestedContext.worldStateAccessTrace
context.worldStateAccessTrace.contractCalls.append({nestedContext.address, clk})
context.worldStateAccessTrace.contractCalls.append({nestedContext.address, nestedContext.storageAddress, clk})
```

> Reminder: a nested call cannot make updates to the world state or accrued substate if it is a [`STATICCALL`](./instruction-set/#isa-section-staticcall).
Loading
Loading