From 485fe40aecb1af1ece834417797b85e557ff9ae5 Mon Sep 17 00:00:00 2001 From: Facundo Date: Mon, 13 May 2024 19:27:07 +0100 Subject: [PATCH] fix(avm-simulator): fix env getters (#6357) --- .../public-vm/gen/_instruction-set.mdx | 26 +++--- .../InstructionSet/InstructionSet.js | 36 +++++---- .../aztec-nr/aztec/src/context/avm_context.nr | 1 + .../avm/opcodes/environment_getters.test.ts | 13 +-- .../src/avm/opcodes/environment_getters.ts | 79 +++---------------- 5 files changed, 54 insertions(+), 101 deletions(-) diff --git a/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx b/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx index 1c275e77e92..8b8eeb3f76b 100644 --- a/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx +++ b/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx @@ -800,7 +800,7 @@ Get the address of the currently executing l2 contract - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.address` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/ADDRESS.png)](/img/protocol-specs/public-vm/bit-formats/ADDRESS.png) @@ -818,7 +818,7 @@ Get the _storage_ address of the currently executing context - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.storageAddress` - **Details**: The storage address is used for public storage accesses. -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/STORAGEADDRESS.png)](/img/protocol-specs/public-vm/bit-formats/STORAGEADDRESS.png) @@ -835,7 +835,7 @@ Get the address of the sender (caller of the current context) - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.sender` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/SENDER.png)](/img/protocol-specs/public-vm/bit-formats/SENDER.png) @@ -852,7 +852,7 @@ Get the fee to be paid per "L2 gas" - constant for entire transaction - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.feePerL2Gas` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/FEEPERL2GAS.png)](/img/protocol-specs/public-vm/bit-formats/FEEPERL2GAS.png) @@ -869,7 +869,7 @@ Get the fee to be paid per "DA gas" - constant for entire transaction - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.feePerDaGas` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/FEEPERDAGAS.png)](/img/protocol-specs/public-vm/bit-formats/FEEPERDAGAS.png) @@ -886,7 +886,7 @@ Get the computed transaction fee during teardown phase, zero otherwise - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.transactionFee` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 @@ -903,7 +903,7 @@ Get how many contract calls deep the current call context is - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.contractCallDepth` - **Details**: Note: security issues with EVM's tx.origin can be resolved by asserting `calldepth == 0`. -- **Tag updates**: `T[dstOffset] = u8` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/CONTRACTCALLDEPTH.png)](/img/protocol-specs/public-vm/bit-formats/CONTRACTCALLDEPTH.png) @@ -920,7 +920,7 @@ Get this rollup's L1 chain ID - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.globals.chainId` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/CHAINID.png)](/img/protocol-specs/public-vm/bit-formats/CHAINID.png) @@ -937,7 +937,7 @@ Get this rollup's L2 version ID - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.globals.version` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/VERSION.png)](/img/protocol-specs/public-vm/bit-formats/VERSION.png) @@ -954,7 +954,7 @@ Get this L2 block's number - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.globals.blocknumber` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/BLOCKNUMBER.png)](/img/protocol-specs/public-vm/bit-formats/BLOCKNUMBER.png) @@ -988,7 +988,7 @@ Get the block's beneficiary address - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.globals.coinbase` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/COINBASE.png)](/img/protocol-specs/public-vm/bit-formats/COINBASE.png) @@ -1005,7 +1005,7 @@ Total amount of "L2 gas" that a block can consume - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.globals.l2GasLimit` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/BLOCKL2GASLIMIT.png)](/img/protocol-specs/public-vm/bit-formats/BLOCKL2GASLIMIT.png) @@ -1022,7 +1022,7 @@ Total amount of "DA gas" that a block can consume - **Args**: - **dstOffset**: memory offset specifying where to store operation's result - **Expression**: `M[dstOffset] = context.environment.globals.daGasLimit` -- **Tag updates**: `T[dstOffset] = u32` +- **Tag updates**: `T[dstOffset] = field` - **Bit-size**: 56 [![](/img/protocol-specs/public-vm/bit-formats/BLOCKDAGASLIMIT.png)](/img/protocol-specs/public-vm/bit-formats/BLOCKDAGASLIMIT.png) diff --git a/docs/src/preprocess/InstructionSet/InstructionSet.js b/docs/src/preprocess/InstructionSet/InstructionSet.js index fac2b3e0239..492236d3c1c 100644 --- a/docs/src/preprocess/InstructionSet/InstructionSet.js +++ b/docs/src/preprocess/InstructionSet/InstructionSet.js @@ -511,7 +511,7 @@ const INSTRUCTION_SET_RAW = [ Summary: "Get the address of the currently executing l2 contract", Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "storageaddress", @@ -529,7 +529,7 @@ const INSTRUCTION_SET_RAW = [ Summary: "Get the _storage_ address of the currently executing context", Details: "The storage address is used for public storage accesses.", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "sender", @@ -547,7 +547,7 @@ const INSTRUCTION_SET_RAW = [ Summary: "Get the address of the sender (caller of the current context)", Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "feeperl2gas", @@ -566,7 +566,7 @@ const INSTRUCTION_SET_RAW = [ 'Get the fee to be paid per "L2 gas" - constant for entire transaction', Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "feeperdagas", @@ -585,7 +585,7 @@ const INSTRUCTION_SET_RAW = [ 'Get the fee to be paid per "DA gas" - constant for entire transaction', Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "transactionfee", @@ -604,7 +604,7 @@ const INSTRUCTION_SET_RAW = [ "Get the computed transaction fee during teardown phase, zero otherwise", Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "contractcalldepth", @@ -623,7 +623,7 @@ const INSTRUCTION_SET_RAW = [ Details: "Note: security issues with EVM's tx.origin can be resolved by asserting `calldepth == 0`.", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u8`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "chainid", @@ -641,7 +641,7 @@ const INSTRUCTION_SET_RAW = [ Summary: "Get this rollup's L1 chain ID", Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "version", @@ -659,7 +659,7 @@ const INSTRUCTION_SET_RAW = [ Summary: "Get this rollup's L2 version ID", Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "blocknumber", @@ -677,7 +677,7 @@ const INSTRUCTION_SET_RAW = [ Summary: "Get this L2 block's number", Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "timestamp", @@ -713,7 +713,7 @@ const INSTRUCTION_SET_RAW = [ Summary: "Get the block's beneficiary address", Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "blockl2gaslimit", @@ -731,7 +731,7 @@ const INSTRUCTION_SET_RAW = [ Summary: 'Total amount of "L2 gas" that a block can consume', Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "blockdagaslimit", @@ -749,7 +749,7 @@ const INSTRUCTION_SET_RAW = [ Summary: 'Total amount of "DA gas" that a block can consume', Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", + "Tag updates": "`T[dstOffset] = field`", }, { id: "calldatacopy", @@ -1549,7 +1549,8 @@ halt }, { name: "dstOffset", - description: "memory offset specifying where the first limb of the radix-conversion result is stored.", + description: + "memory offset specifying where the first limb of the radix-conversion result is stored.", }, { name: "radix", @@ -1562,14 +1563,15 @@ halt description: "the number of limbs the word will be converted into.", type: "u32", mode: "immediate", - } + }, ], Expression: `TBD: Storage of limbs and if T[dstOffset] is constrained to U8`, Summary: "Convert a word to an array of limbs in little-endian radix form", - Details: "The limbs will be stored in a contiguous memory block starting at `dstOffset`.", + Details: + "The limbs will be stored in a contiguous memory block starting at `dstOffset`.", "Tag checks": "`T[srcOffset] == field`", - } + }, ]; const INSTRUCTION_SET = INSTRUCTION_SET_RAW.map((instr) => { instr["Bit-size"] = instructionSize(instr); diff --git a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr b/noir-projects/aztec-nr/aztec/src/context/avm_context.nr index d87c5e92c9b..577c9180d69 100644 --- a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/avm_context.nr @@ -30,6 +30,7 @@ impl AvmContext { pub fn fee_per_da_gas(self) -> Field { fee_per_da_gas() } + /** * Emit a log with the given event selector and message. * diff --git a/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts b/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts index 00d23a0ae1d..3b447af01a4 100644 --- a/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts @@ -1,5 +1,6 @@ import { Fr } from '@aztec/foundation/fields'; +import { TypeTag } from '../avm_memory_types.js'; import { initContext, initExecutionEnvironment, initGlobalVariables } from '../fixtures/index.js'; import { Address, @@ -49,6 +50,7 @@ describe.each([ await instruction.execute(context); + expect(context.machineState.memory.getTag(0)).toBe(TypeTag.FIELD); const actual = context.machineState.memory.get(0).toFr(); expect(actual).toEqual(value); }); @@ -56,11 +58,11 @@ describe.each([ type GlobalsInstruction = typeof ChainId | typeof Version | typeof BlockNumber | typeof Timestamp; describe.each([ - [ChainId, 'chainId'], - [Version, 'version'], - [BlockNumber, 'blockNumber'], - [Timestamp, 'timestamp'], -])('Global Variables', (clsValue: GlobalsInstruction, key: string) => { + [ChainId, 'chainId', TypeTag.FIELD], + [Version, 'version', TypeTag.FIELD], + [BlockNumber, 'blockNumber', TypeTag.FIELD], + [Timestamp, 'timestamp', TypeTag.UINT64], +])('Global Variables', (clsValue: GlobalsInstruction, key: string, tag: TypeTag) => { it(`${clsValue.name} should (de)serialize correctly`, () => { const buf = Buffer.from([ clsValue.opcode, // opcode @@ -81,6 +83,7 @@ describe.each([ await instruction.execute(context); + expect(context.machineState.memory.getTag(0)).toBe(tag); const actual = context.machineState.memory.get(0).toFr(); expect(actual).toEqual(value); }); diff --git a/yarn-project/simulator/src/avm/opcodes/environment_getters.ts b/yarn-project/simulator/src/avm/opcodes/environment_getters.ts index 2ecaacb067f..53dbb24cfe5 100644 --- a/yarn-project/simulator/src/avm/opcodes/environment_getters.ts +++ b/yarn-project/simulator/src/avm/opcodes/environment_getters.ts @@ -1,17 +1,15 @@ -import { type Fr } from '@aztec/circuits.js'; - import type { AvmContext } from '../avm_context.js'; import type { AvmExecutionEnvironment } from '../avm_execution_environment.js'; -import { Field, type MemoryValue } from '../avm_memory_types.js'; +import { Field, type MemoryValue, Uint64 } from '../avm_memory_types.js'; import { Opcode } from '../serialization/instruction_serialization.js'; import { GetterInstruction } from './instruction_impl.js'; abstract class EnvironmentGetterInstruction extends GetterInstruction { protected getValue(context: AvmContext): MemoryValue { - return new Field(this.getEnvironmentValue(context.environment)); + return this.getEnvironmentValue(context.environment); } - protected abstract getEnvironmentValue(env: AvmExecutionEnvironment): Fr | number | bigint; + protected abstract getEnvironmentValue(env: AvmExecutionEnvironment): MemoryValue; } export class Address extends EnvironmentGetterInstruction { @@ -19,7 +17,7 @@ export class Address extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.ADDRESS; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.address; + return new Field(env.address.toField()); } } @@ -28,7 +26,7 @@ export class StorageAddress extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.STORAGEADDRESS; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.storageAddress; + return new Field(env.storageAddress.toField()); } } @@ -37,7 +35,7 @@ export class Sender extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.SENDER; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.sender; + return new Field(env.sender.toField()); } } @@ -46,7 +44,7 @@ export class FeePerL2Gas extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.FEEPERL2GAS; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.feePerL2Gas; + return new Field(env.feePerL2Gas); } } @@ -55,7 +53,7 @@ export class FeePerDAGas extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.FEEPERDAGAS; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.feePerDaGas; + return new Field(env.feePerDaGas); } } @@ -64,7 +62,7 @@ export class TransactionFee extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.TRANSACTIONFEE; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.transactionFee; + return new Field(env.transactionFee); } } @@ -73,7 +71,7 @@ export class ChainId extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.CHAINID; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.globals.chainId; + return new Field(env.globals.chainId); } } @@ -82,7 +80,7 @@ export class Version extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.VERSION; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.globals.version; + return new Field(env.globals.version); } } @@ -91,7 +89,7 @@ export class BlockNumber extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.BLOCKNUMBER; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.globals.blockNumber; + return new Field(env.globals.blockNumber); } } @@ -100,57 +98,6 @@ export class Timestamp extends EnvironmentGetterInstruction { static readonly opcode: Opcode = Opcode.TIMESTAMP; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.globals.timestamp; + return new Uint64(env.globals.timestamp.toBigInt()); } } - -// export class Coinbase extends EnvironmentGetterInstruction { -// static type: string = 'COINBASE'; -// static numberOfOperands = 1; - -// constructor(private destOffset: number) { -// super(); -// } - -// async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise { -// const {coinbase} = machineState.executionEnvironment.globals; - -// machineState.memory.set(this.destOffset, coinbase); - -// this.incrementPc(machineState); -// } -// } - -// export class BlockL2GasLimit extends EnvironmentGetterInstruction { -// static type: string = 'BLOCKL2GASLIMIT'; -// static numberOfOperands = 1; - -// constructor(private destOffset: number) { -// super(); -// } - -// async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise { -// const {blockL2GasLimit} = machineState.executionEnvironment.globals; - -// machineState.memory.set(this.destOffset, blockL2GasLimit); - -// this.incrementPc(machineState); -// } -// } - -// export class BlockDAGasLimit extends EnvironmentGetterInstruction { -// static type: string = 'BLOCKDAGASLIMIT'; -// static numberOfOperands = 1; - -// constructor(private destOffset: number) { -// super(); -// } - -// async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise { -// const {blockDAGasLimit} = machineState.executionEnvironment.globals; - -// machineState.memory.set(this.destOffset, blockDAGasLimit); - -// this.incrementPc(machineState); -// } -// }