Skip to main content

State

This section describes the types of state maintained by the AVM.

Machine State

Machine state is transformed on an instruction-per-instruction basis. Each execution context has its own machine state.

MachineState

FieldTypeDescription
l2GasLeftfieldTracks the amount of L2 gas remaining at any point during execution. Initialized from contract call arguments.
daGasLeftfieldTracks the amount of DA gas remaining at any point during execution. Initialized from contract call arguments.
pcfieldIndex into the contract's bytecode indicating which instruction to execute. Initialized to 0 during context initialization.
internalCallStackVector<field>A stack of program counters pushed to and popped from by INTERNALCALL and INTERNALRETURN instructions. Initialized as empty during context initialization.
memory[field; 2^32]A 2322^{32} entry memory space accessible by user code (AVM instructions). All 2322^{32} entries are assigned default value 0 during context initialization. See "Memory Model" for a complete description of AVM memory.

World State

AVM's access to Aztec State

Aztec's global state is implemented as a few merkle trees. These trees are exposed to the AVM as follows:

StateTreeMerkle Tree TypeAVM Access
Public StoragePublic Data TreeUpdatablemembership-checks (latest), reads, writes
Note HashesNote Hash TreeAppend-onlymembership-checks (start-of-block), appends
NullifiersNullifier TreeIndexedmembership-checks (latest), appends
L1-to-L2 MessagesL1-to-L2 Message TreeAppend-onlymembership-checks (start-of-block)
HeadersArchive TreeAppend-onlymembership-checks, leaf-preimage-reads
Contracts*---

* As described in "Contract Deployment", contracts are not stored in a dedicated tree. A contract class is represented as an unencrypted log containing the ContractClass structure (which contains the bytecode) and a nullifier representing the class identifier. A contract instance is represented as an unencrypted log containing the ContractInstance structure and a nullifier representing the contract address.

AVM World State

The AVM does not directly modify Aztec state. Instead, it stages modifications to be applied later pending successful execution. As part of each execution context, the AVM maintains world state which is a representation of Aztec state that includes staged modifications.

As the AVM executes contract code, instructions may read or modify the world state within the current context. If execution within a particular context reverts, staged world state modifications are rejected by the caller. If execution succeeds, staged world state modifications are accepted.

AvmWorldState

The following table defines an AVM context's world state interface:

FieldAVM Instructions & Access
contracts*CALL (special case, see below*)
publicStorageSLOAD (membership-checks (latest) & reads), SSTORE (writes)
noteHashesNOTEHASHEXISTS (membership-checks (start-of-block)), EMITNOTEHASH (appends)
nullifiersNULLIFIERSEXISTS membership-checks (latest), EMITNULLIFIER (appends)
l1ToL2MessagesL1TOL2MSGEXISTS (membership-checks (start-of-block))
headersHEADERMEMBER (membership-checks & leaf-preimage-reads)

* *CALL is short for CALL/STATICCALL/DELEGATECALL.

* For the purpose of the AVM, the world state's contracts member is readable for bytecode fetching, and it is effectively updated when a new contract class or instance is created (along with a nullifier for the contract class identifier or contract address).

World State Access Trace

The circuit implementation of the AVM does not prove that its world state accesses are valid and properly sequenced, and does not perform actual tree updates. Thus, all world state accesses, regardless of whether they are rejected due to a revert, must be traced and eventually handed off to downstream circuits (public kernel and rollup circuits) for comprehensive validation and tree updates.

This trace of an AVM session's contract calls and world state accesses is named the world state access trace.

The world state access trace is also important for enforcing limitations on the maximum number of allowable world state accesses.

WorldStateAccessTrace

Each entry in the world state access trace is listed below along with its type and the instructions that append to it:

FieldRelevant StateTypeInstructions
accessCounterall statefieldincremented by all instructions below
contractCallsContractsVector<TracedContractCall>*CALL
publicStorageReadsPublic StorageVector<TracedStorageRead>SLOAD
publicStorageWritesPublic StorageVector<TracedStorageWrite>SSTORE
noteHashChecksNote HashesVector<TracedNoteHashCheck>NOTEHASHEXISTS
noteHashesNote HashesVector<TracedNoteHash>EMITNOTEHASH
nullifierChecksNullifiersVector<TracedNullifierCheck>NULLIFIERSEXISTS
nullifiersNullifiersVector<TracedNullifier>EMITNULLIFIER
l1ToL2MessageChecksL1-To-L2 MessagesVector<TracedL1ToL2MessageCheck>L1TOL2MSGEXISTS
archiveChecksHeadersVector<TracedArchiveLeafCheck>HEADERMEMBER

The types tracked in these trace vectors are defined here.

*CALL is short for CALL/STATICCALL/DELEGATECALL.

Aztec tree operations like membership checks, appends, or leaf updates are performed in-circuit by downstream circuits (public kernel and rollup circuits), after AVM execution. The world state access trace is a list of requests made by the AVM for later circuits to perform.

Accrued Substate

The term "accrued substate" is borrowed from the Ethereum Yellow Paper.

Accrued substate is accrued throughout a context's execution, but updates to it are strictly never relevant to subsequent instructions, contract calls, or transactions. An execution context is always initialized with empty accrued substate. Its vectors are append-only, and the instructions listed below append to these vectors. If a contract call's execution succeeds, its accrued substate is appended to the caller's. If a contract's execution reverts, its accrued substate is ignored.

AccruedSubstate

FieldTypeInstructions
unencryptedLogsVector<UnencryptedLog>EMITUNENCRYPTEDLOG
sentL2ToL1MessagesVector<SentL2ToL1Message>SENDL1TOL2MSG

The types tracked in these vectors are defined here.