Skip to content

Commit 4f8326b

Browse files
authored
docs(yellowpaper): refresh of avm instruction set (AztecProtocol#4081)
- Misc cleanup - Recategorized and *reordered* instructions - Updated instruction expressions to match context structure in high-level spec - Removed opcode numbers from section titles as it makes links ugly - Removed opcode numbers from images so they don't need to be regenerated for now - `in-tag` -> `inTag`, same with `dstTag` - Intro Instruction Set section with some relevant notes - Removed misc `*ROOT` opcodes in favor of `BLOCKHEADERBYNUM` opcode - Cleanup in high-level avm spec
1 parent eab3600 commit 4f8326b

75 files changed

Lines changed: 1217 additions & 1281 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,84 @@
11
/**
2-
* All avm opcodes
2+
* All AVM opcodes
33
*/
44
export enum Opcodes {
5-
// Arithmetic
5+
// Compute
6+
// Compute - Arithmetic
67
ADD,
78
SUB,
89
MUL,
910
DIV,
11+
// Compute - Comparators
1012
EQ,
1113
LT,
1214
LTE,
15+
// Compute - Bitwise
1316
AND,
1417
OR,
1518
XOR,
1619
NOT,
1720
SHL,
1821
SHR,
22+
// Compute - Type Conversions
1923
CAST,
20-
// Memory
21-
SET,
22-
MOV,
23-
CMOV,
24-
CALLDATACOPY,
25-
26-
// Logs
27-
EMITNOTEHASH,
28-
EMITNULLIFIER,
29-
SENDL2TOL1MSG,
30-
ULOG,
31-
// Control flow
32-
JUMP,
33-
JUMPI,
34-
INTERNALCALL,
35-
INTERNALRETURN,
36-
37-
// Storage
38-
SLOAD,
39-
SSTORE,
40-
// Contract call control flow
41-
RETURN,
42-
REVERT,
43-
CALL,
44-
STATICCALL,
4524

25+
// Execution Environment
26+
ADDRESS,
27+
STORAGEADDRESS,
28+
ORIGIN,
29+
SENDER,
30+
PORTAL,
31+
FEEPERL1GAS,
32+
FEEPERL2GAS,
33+
FEEPERDAGAS,
34+
CONTRACTCALLDEPTH,
35+
// Execution Environment - Globals
4636
CHAINID,
4737
VERSION,
4838
BLOCKNUMBER,
4939
TIMESTAMP,
5040
COINBASE,
5141
BLOCKL1GASLIMIT,
5242
BLOCKL2GASLIMIT,
53-
NULLIFIERSOOT,
54-
CONTRACTSROOT,
55-
MSGSROOT,
56-
NOTESROOT,
57-
PUBLICDATAROOT,
58-
GLOBALSHASH,
59-
BLOCKSROOT,
60-
GRANDROOT,
43+
BLOCKDAGASLIMIT,
44+
// Execution Environment - Calldata
45+
CALLDATACOPY,
6146

62-
// Call context
63-
ORIGIN,
64-
REFUNDEE,
65-
FEEPERL1GAS,
66-
FEEPERL2GAS,
67-
CALLER,
68-
ADDRESS,
69-
PORTAL,
70-
CALLDEPTH,
71-
l1GAS,
72-
L2GAS,
47+
// Machine State
48+
// Machine State - Gas
49+
L1GASLEFT,
50+
L2GASLEFT,
51+
DAGASLEFT,
52+
// Machine State - Internal Control Flow
53+
JUMP,
54+
JUMPI,
55+
INTERNALCALL,
56+
INTERNALRETURN,
57+
INTERNALCALLDEPTH,
58+
// Machine State - Memory
59+
SET,
60+
MOV,
61+
CMOV,
62+
63+
// World State
64+
BLOCKHEADERBYNUMBER,
65+
SLOAD, // Public Storage
66+
SSTORE, // Public Storage
67+
READL1TOL2MSG, // Messages
68+
SENDL2TOL1MSG, // Messages
69+
EMITNOTEHASH, // Notes & Nullifiers
70+
EMITNULLIFIER, // Notes & Nullifiers
71+
72+
// Accrued Substate
73+
EMITUNENCRYPTEDLOG,
74+
75+
// Control Flow - Contract Calls
76+
CALL,
77+
STATICCALL,
78+
RETURN,
79+
REVERT,
7380

74-
// Black box
81+
// Gadgets
7582
KECCAK,
7683
POSEIDON,
7784
}

yellow-paper/docs/public-vm/avm.md

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ A **caller** is a contract call's initiator. The caller of an initial contract c
2222

2323
- [**Public contract bytecode**](#public-contract-bytecode) (aka AVM bytecode)
2424
- [**Execution context**](#execution-context), outlining the AVM's environment and state
25-
- [**Execution**](#execution), outlining control flow, gas tracking, halting, and reverting
25+
- [**Execution**](#execution), outlining control flow, gas tracking, normal halting, and exceptional halting
2626
- [**Initial contract calls**](#initial-contract-calls), outlining the initiation of a contract call from a public execution request
2727
- [**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
2828

@@ -69,14 +69,13 @@ ExecutionEnvironment {
6969
address: AztecAddress,
7070
storageAddress: AztecAddress,
7171
origin: AztecAddress,
72-
l1GasPrice: field,
73-
l2GasPrice: field,
74-
daGasPrice: field,
7572
sender: AztecAddress,
7673
portal: AztecAddress,
77-
blockHeader: BlockHeader,
78-
globalVariables: PublicGlobalVariables,
74+
feePerL1Gas: field,
75+
feePerL2Gas: field,
76+
feePerDaGas: field,
7977
contractCallDepth: field,
78+
globals: PublicGlobalVariables,
8079
isStaticCall: boolean,
8180
isDelegateCall: boolean,
8281
calldata: [field; <calldata-length>],
@@ -95,7 +94,7 @@ MachineState {
9594
daGasLeft: field,
9695
pc: field = 0,
9796
internalCallStack: Vector<field> = [], // initialized as empty
98-
memory: [field; 32768] = [0, ..., 0], // all 32768 (2^32) entries are initialized to zero
97+
memory: [field; 2^32] = [0, ..., 0], // all 2^32 entries are initialized to zero
9998
}
10099
```
101100

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

218217
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:
219218
- [`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`.
220-
- 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.
219+
- 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.
221220
- 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`.
222221
- 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)).
223222
- 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".
@@ -226,11 +225,11 @@ An instruction's gas cost is meant to reflect the computational cost of generati
226225
227226
> 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.
228227
229-
## Halting
228+
### Halting
230229

231230
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.
232231

233-
### Normal halting
232+
#### Normal halting
234233

235234
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.
236235

@@ -246,7 +245,7 @@ results.output = machineState.memory[instr.args.retOffset:instr.args.retOffset+i
246245
247246
> `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.
248247
249-
### Exceptional halting
248+
#### Exceptional halting
250249

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

@@ -352,7 +351,7 @@ context = AvmContext {
352351
worldState = <latest world state>,
353352
journal = INITIAL_JOURNAL,
354353
accruedSubstate = INITIAL_ACCRUED_SUBSTATE,
355-
results = INITIAL_MESSAGE_CALL_RESULTS,
354+
results = INITIAL_CONTRACT_CALL_RESULTS,
356355
}
357356
```
358357
@@ -365,14 +364,13 @@ INITIAL_EXECUTION_ENVIRONMENT = ExecutionEnvironment {
365364
address = PublicCallRequest.contractAddress,
366365
storageAddress = PublicCallRequest.CallContext.storageContractAddress,
367366
origin = TxRequest.origin,
368-
l1GasPrice = TxRequest.l1GasPrice,
369-
l2GasPrice = TxRequest.l2GasPrice,
370-
daGasPrice = TxRequest.daGasPrice,
371367
sender = PublicCallRequest.CallContext.msgSender,
372368
portal = PublicCallRequest.CallContext.portalContractAddress,
373-
blockHeader = <latest block header>,
374-
globalVariables = <latest global variable values>
369+
feePerL1Gas = TxRequest.feePerL1Gas,
370+
feePerL2Gas = TxRequest.feePerL2Gas,
371+
feePerDaGas = TxRequest.feePerDaGas,
375372
contractCallDepth = 0,
373+
globals = <latest global variable values>
376374
isStaticCall = PublicCallRequest.CallContext.isStaticCall,
377375
isDelegateCall = PublicCallRequest.CallContext.isDelegateCall,
378376
calldata = PublicCallRequest.args,
@@ -385,7 +383,7 @@ INITIAL_MACHINE_STATE = MachineState {
385383
daGasLeft = TxRequest.daGasLimit,
386384
pc = 0,
387385
internalCallStack = [], // initialized as empty
388-
memory = [0, ..., 0], // all 32768 (2^32) entries are initialized to zero
386+
memory = [0, ..., 0], // all 2^32 entries are initialized to zero
389387
}
390388

391389
INITIAL_JOURNAL = Journal {
@@ -402,7 +400,7 @@ INITIAL_ACCRUED_SUBSTATE = AccruedSubstate {
402400
unencryptedLogs = [], // initialized as empty
403401
}
404402

405-
INITIAL_MESSAGE_CALL_RESULTS = ContractCallResults {
403+
INITIAL_CONTRACT_CALL_RESULTS = ContractCallResults {
406404
reverted = false,
407405
output = [], // initialized as empty
408406
}
@@ -423,7 +421,7 @@ nestedContext = AvmContext {
423421
worldState: callingContext.worldState,
424422
journal: callingContext.journal,
425423
accruedSubstate: INITIAL_ACCRUED_SUBSTATE,
426-
results: INITIAL_MESSAGE_CALL_RESULTS,
424+
results: INITIAL_CONTRACT_CALL_RESULTS,
427425
}
428426
```
429427
@@ -442,17 +440,16 @@ calldataStart = instr.args.argsOffset
442440
calldataEnd = calldataStart + instr.args.argsSize
443441

444442
nestedExecutionEnvironment = ExecutionEnvironment {
445-
address: instr.args.addr,
446-
storageAddress: isDelegateCall ? callingContext.environment.storageAddress : instr.args.addr,
447443
origin: callingContext.origin,
448-
l1GasPrice: callingContext.l1GasPrice,
449-
l2GasPrice: callingContext.l2GasPrice,
450-
daGasPrice: callingContext.daGasPrice,
451444
sender: callingContext.address,
445+
address: instr.args.addr,
446+
storageAddress: isDelegateCall ? callingContext.environment.storageAddress : instr.args.addr,
452447
portal: contract.portal,
453-
blockHeader: callingContext.blockHeader,
454-
globalVariables: callingContext.globalVariables,
448+
feePerL1Gas: callingContext.feePerL1Gas,
449+
feePerL2Gas: callingContext.feePerL2Gas,
450+
feePerDaGas: callingContext.feePerDaGas,
455451
contractCallDepth: callingContext.contractCallDepth + 1,
452+
globals: callingContext.globals,
456453
isStaticCall: isStaticCall,
457454
isDelegateCall: isDelegateCall,
458455
calldata: callingContext.memory[calldataStart:calldataEnd],
@@ -465,7 +462,7 @@ nestedMachineState = MachineState {
465462
daGasLeft: callingContext.machineState.memory[instr.args.gasOffset+2],
466463
pc = 0,
467464
internalCallStack = [], // initialized as empty
468-
memory = [0, ..., 0], // all 32768 (2^32) entries are initialized to zero
465+
memory = [0, ..., 0], // all 2^32 entries are initialized to zero
469466
}
470467
```
471468
> 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`.

0 commit comments

Comments
 (0)