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): refresh of avm instruction set #4081

Merged
merged 12 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from 11 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
101 changes: 54 additions & 47 deletions yarn-project/acir-simulator/src/avm/opcodes/opcodes.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,84 @@
/**
* All avm opcodes
* All AVM opcodes
*/
export enum Opcodes {
// Arithmetic
// Compute
// Compute - Arithmetic
ADD,
SUB,
MUL,
DIV,
// Compute - Comparators
EQ,
LT,
LTE,
// Compute - Bitwise
AND,
OR,
XOR,
NOT,
SHL,
SHR,
// Compute - Type Conversions
CAST,
// Memory
SET,
MOV,
CMOV,
CALLDATACOPY,

// Logs
EMITNOTEHASH,
EMITNULLIFIER,
SENDL2TOL1MSG,
ULOG,
// Control flow
JUMP,
JUMPI,
INTERNALCALL,
INTERNALRETURN,

// Storage
SLOAD,
SSTORE,
// Contract call control flow
RETURN,
REVERT,
CALL,
STATICCALL,

// Execution Environment
ADDRESS,
STORAGEADDRESS,
ORIGIN,
SENDER,
PORTAL,
FEEPERL1GAS,
FEEPERL2GAS,
FEEPERDAGAS,
CONTRACTCALLDEPTH,
// Execution Environment - Globals
CHAINID,
VERSION,
BLOCKNUMBER,
TIMESTAMP,
COINBASE,
BLOCKL1GASLIMIT,
BLOCKL2GASLIMIT,
NULLIFIERSOOT,
CONTRACTSROOT,
MSGSROOT,
NOTESROOT,
PUBLICDATAROOT,
GLOBALSHASH,
BLOCKSROOT,
GRANDROOT,
BLOCKDAGASLIMIT,
// Execution Environment - Calldata
CALLDATACOPY,

// Call context
ORIGIN,
REFUNDEE,
FEEPERL1GAS,
FEEPERL2GAS,
CALLER,
ADDRESS,
PORTAL,
CALLDEPTH,
l1GAS,
L2GAS,
// Machine State
// Machine State - Gas
L1GASLEFT,
L2GASLEFT,
DAGASLEFT,
// Machine State - Internal Control Flow
JUMP,
JUMPI,
INTERNALCALL,
INTERNALRETURN,
INTERNALCALLDEPTH,
// Machine State - Memory
SET,
MOV,
CMOV,

// World State
BLOCKHEADERBYNUMBER,
SLOAD, // Public Storage
SSTORE, // Public Storage
READL1TOL2MSG, // Messages
SENDL2TOL1MSG, // Messages
EMITNOTEHASH, // Notes & Nullifiers
EMITNULLIFIER, // Notes & Nullifiers

// Accrued Substate
EMITUNENCRYPTEDLOG,

// Control Flow - Contract Calls
CALL,
STATICCALL,
RETURN,
REVERT,

// Black box
// Gadgets
KECCAK,
POSEIDON,
}
55 changes: 26 additions & 29 deletions yellow-paper/docs/public-vm/avm.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ A **caller** is a contract call's initiator. The caller of an initial contract c

- [**Public contract bytecode**](#public-contract-bytecode) (aka AVM bytecode)
- [**Execution context**](#execution-context), outlining the AVM's environment and state
- [**Execution**](#execution), outlining control flow, gas tracking, halting, and reverting
- [**Execution**](#execution), outlining control flow, gas tracking, normal halting, and exceptional halting
- [**Initial contract calls**](#initial-contract-calls), outlining the initiation of a contract call from a public execution request
- [**Nested contract calls**](#nested-contract-calls), outlining the initiation of a contract call from an instruction as well as the processing of nested execution results, gas refunds, and state reverts

Expand Down Expand Up @@ -69,14 +69,13 @@ ExecutionEnvironment {
address: AztecAddress,
storageAddress: AztecAddress,
origin: AztecAddress,
l1GasPrice: field,
l2GasPrice: field,
daGasPrice: field,
sender: AztecAddress,
portal: AztecAddress,
blockHeader: BlockHeader,
globalVariables: PublicGlobalVariables,
feePerL1Gas: field,
feePerL2Gas: field,
feePerDaGas: field,
contractCallDepth: field,
globals: PublicGlobalVariables,
isStaticCall: boolean,
isDelegateCall: boolean,
calldata: [field; <calldata-length>],
Expand All @@ -95,7 +94,7 @@ MachineState {
daGasLeft: field,
pc: field = 0,
internalCallStack: Vector<field> = [], // initialized as empty
memory: [field; 32768] = [0, ..., 0], // all 32768 (2^32) entries are initialized to zero
memory: [field; 2^32] = [0, ..., 0], // all 2^32 entries are initialized to zero
}
```

Expand All @@ -121,7 +120,7 @@ WorldState {
contracts: AztecAddress => {bytecode, portalAddress}, // read-only from within AVM
blockHeaders: Vector<BlockHeader>, // read-only from within AVM
publicStorage: (AztecAddress, field) => value, // read/write
l1ToL2Messages: (AztecAddress, field) => message, // read-only from within AVM
l1ToL2Messages: field => message, // read-only from within AVM
l2ToL1Messages: Vector<[field; <msg-length>]>, // append-only (no reads) from within AVM
noteHashes: Vector<field>, // append-only (no reads) from within AVM
nullifiers: Vector<field>, // append-only (no reads) from within AVM
Expand Down Expand Up @@ -217,7 +216,7 @@ machineState.daGasLeft = 0

An instruction's gas cost is meant to reflect the computational cost of generating a proof of its correct execution. For some instructions, this computational cost changes based on inputs. Here are some examples and important notes:
- [`JUMP`](./instruction-set/#isa-section-jump) is an example of an instruction with constant gas cost. Regardless of its inputs, the instruction always incurs the same `l1GasCost`, `l2GasCost`, and `daGasCost`.
- The [`SET`](./instruction-set/#isa-section-set) instruction operates on a different sized constant (based on its `dst-type`). Therefore, this instruction's gas cost increases with the size of its input.
- The [`SET`](./instruction-set/#isa-section-set) instruction operates on a different sized constant (based on its `dstTag`). Therefore, this instruction's gas cost increases with the size of its input.
- Instructions that operate on a data range of a specified "size" scale in cost with that size. An example of this is the [`CALLDATACOPY`](./instruction-set/#isa-section-calldatacopy) argument which copies `copySize` words from `environment.calldata` to `machineState.memory`.
- The [`CALL`](./instruction-set/#isa-section-call)/[`STATICCALL`](./instruction-set/#isa-section-call)/`DELEGATECALL` instruction's gas cost is determined by its `*Gas` arguments, but any gas unused by the nested contract call's execution is refunded after its completion ([more on this later](#updating-the-calling-context-after-nested-call-halts)).
- An instruction with "offset" arguments (like [`ADD`](./instruction-set/#isa-section-add) and many others), has increased cost for each offset argument that is flagged as "indirect".
Expand All @@ -226,11 +225,11 @@ An instruction's gas cost is meant to reflect the computational cost of generati

> An instruction's gas cost takes into account the costs of associated downstream computations. An instruction that triggers accesses to the public data tree (`SLOAD`/`SSTORE`) incurs a cost that accounts for state access validation in later circuits (public kernel or rollup). A contract call instruction (`CALL`/`STATICCALL`/`DELEGATECALL`) incurs a cost accounting for the nested call's complete execution as well as any work required by the public kernel circuit for this additional call.

## Halting
### Halting

A context's execution can end with a **normal halt** or **exceptional halt**. A halt ends execution within the current context and returns control flow to the calling context.

### Normal halting
#### Normal halting

A normal halt occurs when the VM encounters an explicit halting instruction ([`RETURN`](./instruction-set#isa-section-return) or [`REVERT`](./instruction-set#isa-section-revert)). Such instructions consume gas normally and optionally initialize some output data before finally halting the current context's execution.

Expand All @@ -246,7 +245,7 @@ results.output = machineState.memory[instr.args.retOffset:instr.args.retOffset+i

> `results.output` is only relevant when the caller is a contract call itself. In other words, it is only relevant for [nested contract calls](#nested-contract-calls). When an [initial contract call](#initial-contract-calls) (initiated by a public execution request) halts normally, its `results.output` is ignored.

### Exceptional halting
#### Exceptional halting

An exceptional halt is not explicitly triggered by an instruction but instead occurs when an exceptional condition is met.

Expand Down Expand Up @@ -352,7 +351,7 @@ context = AvmContext {
worldState = <latest world state>,
journal = INITIAL_JOURNAL,
accruedSubstate = INITIAL_ACCRUED_SUBSTATE,
results = INITIAL_MESSAGE_CALL_RESULTS,
results = INITIAL_CONTRACT_CALL_RESULTS,
}
```

Expand All @@ -365,14 +364,13 @@ INITIAL_EXECUTION_ENVIRONMENT = ExecutionEnvironment {
address = PublicCallRequest.contractAddress,
storageAddress = PublicCallRequest.CallContext.storageContractAddress,
origin = TxRequest.origin,
l1GasPrice = TxRequest.l1GasPrice,
l2GasPrice = TxRequest.l2GasPrice,
daGasPrice = TxRequest.daGasPrice,
sender = PublicCallRequest.CallContext.msgSender,
portal = PublicCallRequest.CallContext.portalContractAddress,
blockHeader = <latest block header>,
globalVariables = <latest global variable values>
feePerL1Gas = TxRequest.feePerL1Gas,
feePerL2Gas = TxRequest.feePerL2Gas,
feePerDaGas = TxRequest.feePerDaGas,
contractCallDepth = 0,
globals = <latest global variable values>
isStaticCall = PublicCallRequest.CallContext.isStaticCall,
isDelegateCall = PublicCallRequest.CallContext.isDelegateCall,
calldata = PublicCallRequest.args,
Expand All @@ -385,7 +383,7 @@ INITIAL_MACHINE_STATE = MachineState {
daGasLeft = TxRequest.daGasLimit,
pc = 0,
internalCallStack = [], // initialized as empty
memory = [0, ..., 0], // all 32768 (2^32) entries are initialized to zero
memory = [0, ..., 0], // all 2^32 entries are initialized to zero
}

INITIAL_JOURNAL = Journal {
Expand All @@ -402,7 +400,7 @@ INITIAL_ACCRUED_SUBSTATE = AccruedSubstate {
unencryptedLogs = [], // initialized as empty
}

INITIAL_MESSAGE_CALL_RESULTS = ContractCallResults {
INITIAL_CONTRACT_CALL_RESULTS = ContractCallResults {
reverted = false,
output = [], // initialized as empty
}
Expand All @@ -423,7 +421,7 @@ nestedContext = AvmContext {
worldState: callingContext.worldState,
journal: callingContext.journal,
accruedSubstate: INITIAL_ACCRUED_SUBSTATE,
results: INITIAL_MESSAGE_CALL_RESULTS,
results: INITIAL_CONTRACT_CALL_RESULTS,
}
```

Expand All @@ -442,17 +440,16 @@ calldataStart = instr.args.argsOffset
calldataEnd = calldataStart + instr.args.argsSize

nestedExecutionEnvironment = ExecutionEnvironment {
address: instr.args.addr,
storageAddress: isDelegateCall ? callingContext.environment.storageAddress : instr.args.addr,
origin: callingContext.origin,
l1GasPrice: callingContext.l1GasPrice,
l2GasPrice: callingContext.l2GasPrice,
daGasPrice: callingContext.daGasPrice,
sender: callingContext.address,
address: instr.args.addr,
storageAddress: isDelegateCall ? callingContext.environment.storageAddress : instr.args.addr,
portal: contract.portal,
blockHeader: callingContext.blockHeader,
globalVariables: callingContext.globalVariables,
feePerL1Gas: callingContext.feePerL1Gas,
feePerL2Gas: callingContext.feePerL2Gas,
feePerDaGas: callingContext.feePerDaGas,
contractCallDepth: callingContext.contractCallDepth + 1,
globals: callingContext.globals,
isStaticCall: isStaticCall,
isDelegateCall: isDelegateCall,
calldata: callingContext.memory[calldataStart:calldataEnd],
Expand All @@ -465,7 +462,7 @@ nestedMachineState = MachineState {
daGasLeft: callingContext.machineState.memory[instr.args.gasOffset+2],
pc = 0,
internalCallStack = [], // initialized as empty
memory = [0, ..., 0], // all 32768 (2^32) entries are initialized to zero
memory = [0, ..., 0], // all 2^32 entries are initialized to zero
}
```
> The nested context's machine state's `*GasLeft` is initialized based on the call instruction's `gasOffset` argument. The caller allocates some amount of L1, L2, and DA gas to the nested call. It does so using the instruction's `gasOffset` argument. In particular, prior to the contract call instruction, the caller populates `M[gasOffset]` with the nested context's initial `l1GasLeft`. Likewise it populates `M[gasOffset+1]` with `l2GasLeft` and `M[gasOffset+2]` with `daGasLeft`.
Expand Down
Loading