diff --git a/yarn-project/circuits.js/src/structs/l2_to_l1_message.ts b/yarn-project/circuits.js/src/structs/l2_to_l1_message.ts index 37d1ae3c8115..b3343a2f0d30 100644 --- a/yarn-project/circuits.js/src/structs/l2_to_l1_message.ts +++ b/yarn-project/circuits.js/src/structs/l2_to_l1_message.ts @@ -76,10 +76,6 @@ export class L2ToL1Message { isEmpty(): boolean { return this.recipient.isZero() && this.content.isZero() && !this.counter; } - - scope(contractAddress: AztecAddress) { - return new ScopedL2ToL1Message(this, contractAddress); - } } export class ScopedL2ToL1Message { diff --git a/yarn-project/circuits.js/src/structs/log_hash.ts b/yarn-project/circuits.js/src/structs/log_hash.ts index b0691826bbf3..a51086e5d113 100644 --- a/yarn-project/circuits.js/src/structs/log_hash.ts +++ b/yarn-project/circuits.js/src/structs/log_hash.ts @@ -40,10 +40,6 @@ export class LogHash implements Ordered { return `value=${this.value} counter=${this.counter} length=${this.length}`; } - scope(contractAddress: AztecAddress) { - return new ScopedLogHash(this, contractAddress); - } - [inspect.custom](): string { return `LogHash { ${this.toString()} }`; } diff --git a/yarn-project/prover-client/src/mocks/test_context.ts b/yarn-project/prover-client/src/mocks/test_context.ts index d73e304c3a0e..84732a4c12b2 100644 --- a/yarn-project/prover-client/src/mocks/test_context.ts +++ b/yarn-project/prover-client/src/mocks/test_context.ts @@ -8,14 +8,7 @@ import { type Tx, type TxValidator, } from '@aztec/circuit-types'; -import { - type CombinedConstantData, - type Gas, - type GlobalVariables, - Header, - type Nullifier, - type TxContext, -} from '@aztec/circuits.js'; +import { type Gas, type GlobalVariables, Header, type Nullifier, type TxContext } from '@aztec/circuits.js'; import { type Fr } from '@aztec/foundation/fields'; import { type DebugLogger } from '@aztec/foundation/log'; import { openTmpStore } from '@aztec/kv-store/utils'; @@ -162,7 +155,7 @@ export class TestContext { ) { const defaultExecutorImplementation = ( execution: PublicExecutionRequest, - _constants: CombinedConstantData, + _globalVariables: GlobalVariables, availableGas: Gas, _txContext: TxContext, _pendingNullifiers: Nullifier[], @@ -202,7 +195,7 @@ export class TestContext { txValidator?: TxValidator, executorMock?: ( execution: PublicExecutionRequest, - constants: CombinedConstantData, + globalVariables: GlobalVariables, availableGas: Gas, txContext: TxContext, pendingNullifiers: Nullifier[], diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index d7378b83e51b..e3820001f6f6 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -10,7 +10,6 @@ import { type Fieldable } from '@aztec/foundation/serialize'; import { randomInt } from 'crypto'; import { mock } from 'jest-mock-extended'; -import { PublicEnqueuedCallSideEffectTrace } from '../public/enqueued_call_side_effect_trace.js'; import { type WorldStateDB } from '../public/public_db_sources.js'; import { type PublicSideEffectTraceInterface } from '../public/side_effect_trace_interface.js'; import { type AvmContext } from './avm_context.js'; @@ -31,23 +30,7 @@ import { resolveAvmTestContractAssertionMessage, } from './fixtures/index.js'; import { type AvmPersistableStateManager } from './journal/journal.js'; -import { - Add, - CalldataCopy, - EmitNoteHash, - EmitNullifier, - EmitUnencryptedLog, - type Instruction, - Jump, - L1ToL2MessageExists, - NoteHashExists, - NullifierExists, - Return, - SLoad, - SStore, - SendL2ToL1Message, - Set, -} from './opcodes/index.js'; +import { Add, CalldataCopy, Return, Set } from './opcodes/index.js'; import { encodeToBytecode } from './serialization/bytecode_serialization.js'; import { Opcode } from './serialization/instruction_serialization.js'; import { @@ -953,62 +936,6 @@ describe('AVM simulator: transpiled Noir contracts', () => { ); }); }); - - describe('Side effect trace errors on overflow', () => { - const trace = new PublicEnqueuedCallSideEffectTrace(); - const persistableState = initPersistableStateManager({ worldStateDB, trace }); - - it.each([ - ['Public storage writes', () => new SStore(/*indirect=*/ 0, /*srcOffset=*/ 0, /*slotOffset=*/ 0)], - ['Public storage reads', () => new SLoad(/*indirect=*/ 0, /*slotOffset=*/ 0, /*dstOffset=*/ 0)], - [ - 'Note hash checks', - () => new NoteHashExists(/*indirect=*/ 0, /*noteHashOffset=*/ 0, /*leafIndexOffest=*/ 0, /*existsOffset=*/ 1), - ], - ['New note hashes', () => new EmitNoteHash(/*indirect=*/ 0, /*noteHashOffset=*/ 0)], - [ - 'Nullifier checks', - () => new NullifierExists(/*indirect=*/ 0, /*nullifierOffset=*/ 0, /*addressOffest=*/ 0, /*existsOffset=*/ 1), - ], - ['New nullifiers', () => new EmitNullifier(/*indirect=*/ 0, /*noteHashOffset=*/ 0)], - [ - 'L1 to L2 message checks', - () => - new L1ToL2MessageExists( - /*indirect=*/ 0, - /*msgHashOffset=*/ 0, - /*msgLeafIndexOffest=*/ 0, - /*existsOffset=*/ 1, - ), - ], - ['New unencrypted logs', () => new EmitUnencryptedLog(/*indirect=*/ 0, /*logOffset=*/ 0, /*logSizeOffest=*/ 1)], - [ - 'New L1 to L2 messages', - () => new SendL2ToL1Message(/*indirect=*/ 0, /*recipientOffset=*/ 0, /*contentOffest=*/ 0), - ], - ])(`Overrun of %s`, async (_sideEffectType: string, createInstr: () => Instruction) => { - const bytecode = encodeToBytecode([ - new Set(/*indirect*/ 0, TypeTag.FIELD, /*value*/ 0, /*dstOffset*/ 0).as(Opcode.SET_8, Set.wireFormat8), - new Set(/*indirect*/ 0, TypeTag.FIELD, /*value*/ 100, /*dstOffset*/ 100).as(Opcode.SET_8, Set.wireFormat8), - new Set(/*indirect*/ 0, TypeTag.UINT32, /*value*/ 1, /*dstOffset*/ 1).as(Opcode.SET_8, Set.wireFormat8), - createInstr(), - // change value at memory offset 0 so each instr operates on a different value (important for nullifier emission) - new Add(/*indirect=*/ 0, TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 100, /*dstOffset=*/ 0).as( - Opcode.ADD_8, - Add.wireFormat8, - ), - // infinitely loop back to the tested instruction - // infinite loop should break on side effect overrun error, - // but otherwise will run out of gas - new Jump(/*jumpOffset*/ 2), - ]); - const context = initContext({ persistableState }); - const results = await new AvmSimulator(context).executeBytecode(markBytecodeAsAvm(bytecode)); - expect(results.reverted).toBe(true); - expect(results.output).toEqual([]); - expect(results.revertReason?.message).toMatch('Reached the limit'); - }); - }); }); }); diff --git a/yarn-project/simulator/src/avm/avm_simulator.ts b/yarn-project/simulator/src/avm/avm_simulator.ts index 6c036ecface2..e768d27958d6 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.ts @@ -2,7 +2,6 @@ import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { strict as assert } from 'assert'; -import { SideEffectLimitReachedError } from '../public/side_effect_errors.js'; import type { AvmContext } from './avm_context.js'; import { AvmContractCallResult } from './avm_contract_call_result.js'; import { isAvmBytecode } from './bytecode_utils.js'; @@ -99,7 +98,7 @@ export class AvmSimulator { return results; } catch (err: any) { this.log.verbose('Exceptional halt (revert by something other than REVERT opcode)'); - if (!(err instanceof AvmExecutionError || err instanceof SideEffectLimitReachedError)) { + if (!(err instanceof AvmExecutionError)) { this.log.verbose(`Unknown error thrown by AVM: ${err}`); throw err; } diff --git a/yarn-project/simulator/src/avm/journal/journal.ts b/yarn-project/simulator/src/avm/journal/journal.ts index c00150d03444..7594254e099e 100644 --- a/yarn-project/simulator/src/avm/journal/journal.ts +++ b/yarn-project/simulator/src/avm/journal/journal.ts @@ -1,6 +1,6 @@ import { AztecAddress, type FunctionSelector, type Gas } from '@aztec/circuits.js'; import { Fr } from '@aztec/foundation/fields'; -import { createDebugLogger } from '@aztec/foundation/log'; +import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { SerializableContractInstance } from '@aztec/types/contracts'; import { getPublicFunctionDebugName } from '../../common/debug_fn_name.js'; @@ -22,7 +22,7 @@ import { PublicStorage } from './public_storage.js'; * Manages merging of successful/reverted child state into current state. */ export class AvmPersistableStateManager { - private readonly log = createDebugLogger('aztec:avm_simulator:state_manager'); + private readonly log: DebugLogger = createDebugLogger('aztec:avm_simulator:state_manager'); constructor( /** Reference to node storage */ diff --git a/yarn-project/simulator/src/public/dual_side_effect_trace.ts b/yarn-project/simulator/src/public/dual_side_effect_trace.ts deleted file mode 100644 index 1146feb6e6ab..000000000000 --- a/yarn-project/simulator/src/public/dual_side_effect_trace.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { type CombinedConstantData, type Gas, type VMCircuitPublicInputs } from '@aztec/circuits.js'; -import { type Fr } from '@aztec/foundation/fields'; -import { type ContractInstanceWithAddress } from '@aztec/types/contracts'; - -import { assert } from 'console'; - -import { type AvmContractCallResult } from '../avm/avm_contract_call_result.js'; -import { type AvmExecutionEnvironment } from '../avm/avm_execution_environment.js'; -import { type PublicEnqueuedCallSideEffectTrace } from './enqueued_call_side_effect_trace.js'; -import { type PublicExecutionResult } from './execution.js'; -import { type PublicSideEffectTrace } from './side_effect_trace.js'; -import { type PublicSideEffectTraceInterface } from './side_effect_trace_interface.js'; - -export type TracedContractInstance = { exists: boolean } & ContractInstanceWithAddress; - -export class DualSideEffectTrace implements PublicSideEffectTraceInterface { - constructor( - public readonly innerCallTrace: PublicSideEffectTrace, - public readonly enqueuedCallTrace: PublicEnqueuedCallSideEffectTrace, - ) {} - - public fork() { - return new DualSideEffectTrace(this.innerCallTrace.fork(), this.enqueuedCallTrace.fork()); - } - - public getCounter() { - assert(this.innerCallTrace.getCounter() == this.enqueuedCallTrace.getCounter()); - return this.innerCallTrace.getCounter(); - } - - public tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, exists: boolean, cached: boolean) { - this.innerCallTrace.tracePublicStorageRead(storageAddress, slot, value, exists, cached); - this.enqueuedCallTrace.tracePublicStorageRead(storageAddress, slot, value, exists, cached); - } - - public tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr) { - this.innerCallTrace.tracePublicStorageWrite(storageAddress, slot, value); - this.enqueuedCallTrace.tracePublicStorageWrite(storageAddress, slot, value); - } - - // TODO(8287): _exists can be removed once we have the vm properly handling the equality check - public traceNoteHashCheck(_storageAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean) { - this.innerCallTrace.traceNoteHashCheck(_storageAddress, noteHash, leafIndex, exists); - this.enqueuedCallTrace.traceNoteHashCheck(_storageAddress, noteHash, leafIndex, exists); - } - - public traceNewNoteHash(_storageAddress: Fr, noteHash: Fr) { - this.innerCallTrace.traceNewNoteHash(_storageAddress, noteHash); - this.enqueuedCallTrace.traceNewNoteHash(_storageAddress, noteHash); - } - - public traceNullifierCheck(storageAddress: Fr, nullifier: Fr, leafIndex: Fr, exists: boolean, isPending: boolean) { - this.innerCallTrace.traceNullifierCheck(storageAddress, nullifier, leafIndex, exists, isPending); - this.enqueuedCallTrace.traceNullifierCheck(storageAddress, nullifier, leafIndex, exists, isPending); - } - - public traceNewNullifier(storageAddress: Fr, nullifier: Fr) { - this.innerCallTrace.traceNewNullifier(storageAddress, nullifier); - this.enqueuedCallTrace.traceNewNullifier(storageAddress, nullifier); - } - - public traceL1ToL2MessageCheck(contractAddress: Fr, msgHash: Fr, msgLeafIndex: Fr, exists: boolean) { - this.innerCallTrace.traceL1ToL2MessageCheck(contractAddress, msgHash, msgLeafIndex, exists); - this.enqueuedCallTrace.traceL1ToL2MessageCheck(contractAddress, msgHash, msgLeafIndex, exists); - } - - public traceNewL2ToL1Message(contractAddress: Fr, recipient: Fr, content: Fr) { - this.innerCallTrace.traceNewL2ToL1Message(contractAddress, recipient, content); - this.enqueuedCallTrace.traceNewL2ToL1Message(contractAddress, recipient, content); - } - - public traceUnencryptedLog(contractAddress: Fr, log: Fr[]) { - this.innerCallTrace.traceUnencryptedLog(contractAddress, log); - this.enqueuedCallTrace.traceUnencryptedLog(contractAddress, log); - } - - public traceGetContractInstance(instance: TracedContractInstance) { - this.innerCallTrace.traceGetContractInstance(instance); - this.enqueuedCallTrace.traceGetContractInstance(instance); - } - - /** - * Trace a nested call. - * Accept some results from a finished nested call's trace into this one. - */ - public traceNestedCall( - /** The trace of the nested call. */ - nestedCallTrace: this, - /** The execution environment of the nested call. */ - nestedEnvironment: AvmExecutionEnvironment, - /** How much gas was available for this public execution. */ - startGasLeft: Gas, - /** How much gas was left after this public execution. */ - endGasLeft: Gas, - /** Bytecode used for this execution. */ - bytecode: Buffer, - /** The call's results */ - avmCallResults: AvmContractCallResult, - /** Function name for logging */ - functionName: string = 'unknown', - ) { - this.innerCallTrace.traceNestedCall( - nestedCallTrace.innerCallTrace, - nestedEnvironment, - startGasLeft, - endGasLeft, - bytecode, - avmCallResults, - functionName, - ); - this.enqueuedCallTrace.traceNestedCall( - nestedCallTrace.enqueuedCallTrace, - nestedEnvironment, - startGasLeft, - endGasLeft, - bytecode, - avmCallResults, - functionName, - ); - } - - /** - * Convert this trace to a PublicExecutionResult for use externally to the simulator. - */ - public toPublicExecutionResult( - /** The execution environment of the nested call. */ - avmEnvironment: AvmExecutionEnvironment, - /** How much gas was available for this public execution. */ - startGasLeft: Gas, - /** How much gas was left after this public execution. */ - endGasLeft: Gas, - /** Bytecode used for this execution. */ - bytecode: Buffer, - /** The call's results */ - avmCallResults: AvmContractCallResult, - /** Function name for logging */ - functionName: string = 'unknown', - ): PublicExecutionResult { - return this.innerCallTrace.toPublicExecutionResult( - avmEnvironment, - startGasLeft, - endGasLeft, - bytecode, - avmCallResults, - functionName, - ); - } - - public toVMCircuitPublicInputs( - /** Constants */ - constants: CombinedConstantData, - /** The execution environment of the nested call. */ - avmEnvironment: AvmExecutionEnvironment, - /** How much gas was available for this public execution. */ - startGasLeft: Gas, - /** How much gas was left after this public execution. */ - endGasLeft: Gas, - /** The call's results */ - avmCallResults: AvmContractCallResult, - ): VMCircuitPublicInputs { - return this.enqueuedCallTrace.toVMCircuitPublicInputs( - constants, - avmEnvironment, - startGasLeft, - endGasLeft, - avmCallResults, - ); - } -} diff --git a/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.test.ts b/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.test.ts deleted file mode 100644 index 950b4411c31f..000000000000 --- a/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.test.ts +++ /dev/null @@ -1,489 +0,0 @@ -import { UnencryptedL2Log } from '@aztec/circuit-types'; -import { - AztecAddress, - CombinedConstantData, - EthAddress, - Gas, - L2ToL1Message, - LogHash, - MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, - MAX_L2_TO_L1_MSGS_PER_TX, - MAX_NOTE_HASHES_PER_TX, - MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIERS_PER_TX, - MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_UNENCRYPTED_LOGS_PER_TX, - NoteHash, - Nullifier, - PublicAccumulatedData, - PublicAccumulatedDataArrayLengths, - PublicDataRead, - PublicDataUpdateRequest, - PublicValidationRequestArrayLengths, - PublicValidationRequests, - ReadRequest, - TreeLeafReadRequest, -} from '@aztec/circuits.js'; -import { Fr } from '@aztec/foundation/fields'; -import { SerializableContractInstance } from '@aztec/types/contracts'; - -import { randomBytes, randomInt } from 'crypto'; - -import { AvmContractCallResult } from '../avm/avm_contract_call_result.js'; -import { initExecutionEnvironment } from '../avm/fixtures/index.js'; -import { PublicEnqueuedCallSideEffectTrace, type TracedContractInstance } from './enqueued_call_side_effect_trace.js'; -import { SideEffectLimitReachedError } from './side_effect_errors.js'; - -function randomTracedContractInstance(): TracedContractInstance { - const instance = SerializableContractInstance.random(); - const address = AztecAddress.random(); - return { exists: true, ...instance, address }; -} - -describe('Enqueued-call Side Effect Trace', () => { - const address = Fr.random(); - const utxo = Fr.random(); - const leafIndex = Fr.random(); - const slot = Fr.random(); - const value = Fr.random(); - const recipient = Fr.random(); - const content = Fr.random(); - const log = [Fr.random(), Fr.random(), Fr.random()]; - const contractInstance = SerializableContractInstance.empty().withAddress(new Fr(42)); - - const startGasLeft = Gas.fromFields([new Fr(randomInt(10000)), new Fr(randomInt(10000))]); - const endGasLeft = Gas.fromFields([new Fr(randomInt(10000)), new Fr(randomInt(10000))]); - const transactionFee = Fr.random(); - const calldata = [Fr.random(), Fr.random(), Fr.random(), Fr.random()]; - const bytecode = randomBytes(100); - const returnValues = [Fr.random(), Fr.random()]; - - const constants = CombinedConstantData.empty(); - const avmEnvironment = initExecutionEnvironment({ - address, - calldata, - transactionFee, - }); - const avmCallResults = new AvmContractCallResult(/*reverted=*/ false, returnValues); - const avmCallRevertedResults = new AvmContractCallResult(/*reverted=*/ true, returnValues); - - const emptyValidationRequests = PublicValidationRequests.empty(); - - let startCounter: number; - let startCounterFr: Fr; - let startCounterPlus1: number; - let trace: PublicEnqueuedCallSideEffectTrace; - - beforeEach(() => { - startCounter = randomInt(/*max=*/ 1000000); - startCounterFr = new Fr(startCounter); - startCounterPlus1 = startCounter + 1; - trace = new PublicEnqueuedCallSideEffectTrace(startCounter); - }); - - const toVMCircuitPublicInputs = (trc: PublicEnqueuedCallSideEffectTrace) => { - return trc.toVMCircuitPublicInputs(constants, avmEnvironment, startGasLeft, endGasLeft, avmCallResults); - }; - - it('Should trace storage reads', () => { - const exists = true; - const cached = false; - trace.tracePublicStorageRead(address, slot, value, exists, cached); - expect(trace.getCounter()).toBe(startCounterPlus1); - - const expectedArray = PublicValidationRequests.empty().publicDataReads; - expectedArray[0] = new PublicDataRead(slot, value, startCounter /*contractAddress*/); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(circuitPublicInputs.validationRequests.publicDataReads).toEqual(expectedArray); - expect(trace.getAvmCircuitHints().storageValues.items).toEqual([{ key: startCounterFr, value: value }]); - }); - - it('Should trace storage writes', () => { - trace.tracePublicStorageWrite(address, slot, value); - expect(trace.getCounter()).toBe(startCounterPlus1); - - const expectedArray = PublicAccumulatedData.empty().publicDataUpdateRequests; - expectedArray[0] = new PublicDataUpdateRequest(slot, value, startCounter /*contractAddress*/); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(circuitPublicInputs.accumulatedData.publicDataUpdateRequests).toEqual(expectedArray); - }); - - it('Should trace note hash checks', () => { - const exists = true; - trace.traceNoteHashCheck(address, utxo, leafIndex, exists); - - const expectedArray = PublicValidationRequests.empty().noteHashReadRequests; - expectedArray[0] = new TreeLeafReadRequest(utxo, leafIndex); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(circuitPublicInputs.validationRequests.noteHashReadRequests).toEqual(expectedArray); - - expect(trace.getAvmCircuitHints().noteHashExists.items).toEqual([{ key: leafIndex, value: new Fr(exists) }]); - }); - - it('Should trace note hashes', () => { - trace.traceNewNoteHash(address, utxo); - expect(trace.getCounter()).toBe(startCounterPlus1); - - const expectedArray = PublicAccumulatedData.empty().noteHashes; - expectedArray[0] = new NoteHash(utxo, startCounter).scope(address); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(circuitPublicInputs.accumulatedData.noteHashes).toEqual(expectedArray); - }); - - it('Should trace nullifier checks', () => { - const exists = true; - const isPending = false; - trace.traceNullifierCheck(address, utxo, leafIndex, exists, isPending); - expect(trace.getCounter()).toBe(startCounterPlus1); - - const expectedArray = PublicValidationRequests.empty().nullifierReadRequests; - expectedArray[0] = new ReadRequest(utxo, startCounter).scope(address); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(circuitPublicInputs.validationRequests.nullifierReadRequests).toEqual(expectedArray); - expect(circuitPublicInputs.validationRequests.nullifierNonExistentReadRequests).toEqual( - emptyValidationRequests.nullifierNonExistentReadRequests, - ); - - expect(trace.getAvmCircuitHints().nullifierExists.items).toEqual([{ key: startCounterFr, value: new Fr(exists) }]); - }); - - it('Should trace non-existent nullifier checks', () => { - const exists = false; - const isPending = false; - trace.traceNullifierCheck(address, utxo, leafIndex, exists, isPending); - expect(trace.getCounter()).toBe(startCounterPlus1); - - const expectedArray = PublicValidationRequests.empty().nullifierNonExistentReadRequests; - expectedArray[0] = new ReadRequest(utxo, startCounter).scope(address); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(circuitPublicInputs.validationRequests.nullifierReadRequests).toEqual( - emptyValidationRequests.nullifierReadRequests, - ); - expect(circuitPublicInputs.validationRequests.nullifierNonExistentReadRequests).toEqual(expectedArray); - - expect(trace.getAvmCircuitHints().nullifierExists.items).toEqual([{ key: startCounterFr, value: new Fr(exists) }]); - }); - - it('Should trace nullifiers', () => { - trace.traceNewNullifier(address, utxo); - expect(trace.getCounter()).toBe(startCounterPlus1); - - const expectedArray = PublicAccumulatedData.empty().nullifiers; - expectedArray[0] = new Nullifier(utxo, startCounter, Fr.ZERO); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(circuitPublicInputs.accumulatedData.nullifiers).toEqual(expectedArray); - }); - - it('Should trace L1ToL2 Message checks', () => { - const exists = true; - trace.traceL1ToL2MessageCheck(address, utxo, leafIndex, exists); - - const expectedArray = PublicValidationRequests.empty().l1ToL2MsgReadRequests; - expectedArray[0] = new TreeLeafReadRequest(utxo, leafIndex); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(circuitPublicInputs.validationRequests.l1ToL2MsgReadRequests).toEqual(expectedArray); - - expect(trace.getAvmCircuitHints().l1ToL2MessageExists.items).toEqual([ - { - key: leafIndex, - value: new Fr(exists), - }, - ]); - }); - - it('Should trace new L2ToL1 messages', () => { - trace.traceNewL2ToL1Message(address, recipient, content); - expect(trace.getCounter()).toBe(startCounterPlus1); - - const expectedArray = PublicAccumulatedData.empty().l2ToL1Msgs; - expectedArray[0] = new L2ToL1Message(EthAddress.fromField(recipient), content, startCounter).scope(address); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(circuitPublicInputs.accumulatedData.l2ToL1Msgs).toEqual(expectedArray); - }); - - it('Should trace new unencrypted logs', () => { - trace.traceUnencryptedLog(address, log); - expect(trace.getCounter()).toBe(startCounterPlus1); - - const expectedLog = new UnencryptedL2Log( - AztecAddress.fromField(address), - Buffer.concat(log.map(f => f.toBuffer())), - ); - const expectedArray = PublicAccumulatedData.empty().unencryptedLogsHashes; - expectedArray[0] = new LogHash( - Fr.fromBuffer(expectedLog.hash()), - startCounter, - new Fr(expectedLog.length + 4), - ).scope(AztecAddress.fromField(address)); - - const circuitPublicInputs = toVMCircuitPublicInputs(trace); - expect(trace.getUnencryptedLogs()).toEqual([expectedLog]); - expect(circuitPublicInputs.accumulatedData.unencryptedLogsHashes).toEqual(expectedArray); - }); - - it('Should trace get contract instance', () => { - const instance = randomTracedContractInstance(); - const { version: _, ...instanceWithoutVersion } = instance; - trace.traceGetContractInstance(instance); - expect(trace.getCounter()).toBe(startCounterPlus1); - - //const circuitPublicInputs = toVMCircuitPublicInputs(trace); - // TODO(dbanks12): once this emits nullifier read, check here - expect(trace.getAvmCircuitHints().contractInstances.items).toEqual([ - { - // hint omits "version" and has "exists" as an Fr - ...instanceWithoutVersion, - exists: new Fr(instance.exists), - }, - ]); - }); - describe('Maximum accesses', () => { - it('Should enforce maximum number of public storage reads', () => { - for (let i = 0; i < MAX_PUBLIC_DATA_READS_PER_TX; i++) { - trace.tracePublicStorageRead(new Fr(i), new Fr(i), new Fr(i), true, true); - } - expect(() => trace.tracePublicStorageRead(new Fr(42), new Fr(42), new Fr(42), true, true)).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('Should enforce maximum number of public storage writes', () => { - for (let i = 0; i < MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; i++) { - trace.tracePublicStorageWrite(new Fr(i), new Fr(i), new Fr(i)); - } - expect(() => trace.tracePublicStorageWrite(new Fr(42), new Fr(42), new Fr(42))).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('Should enforce maximum number of note hash checks', () => { - for (let i = 0; i < MAX_NOTE_HASH_READ_REQUESTS_PER_TX; i++) { - trace.traceNoteHashCheck(new Fr(i), new Fr(i), new Fr(i), true); - } - expect(() => trace.traceNoteHashCheck(new Fr(42), new Fr(42), new Fr(42), true)).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('Should enforce maximum number of new note hashes', () => { - for (let i = 0; i < MAX_NOTE_HASHES_PER_TX; i++) { - trace.traceNewNoteHash(new Fr(i), new Fr(i)); - } - expect(() => trace.traceNewNoteHash(new Fr(42), new Fr(42))).toThrow(SideEffectLimitReachedError); - }); - - it('Should enforce maximum number of nullifier checks', () => { - for (let i = 0; i < MAX_NULLIFIER_READ_REQUESTS_PER_TX; i++) { - trace.traceNullifierCheck(new Fr(i), new Fr(i), new Fr(i), true, true); - } - expect(() => trace.traceNullifierCheck(new Fr(42), new Fr(42), new Fr(42), true, true)).toThrow( - SideEffectLimitReachedError, - ); - // NOTE: also cannot do a non-existent check once existent checks have filled up - expect(() => trace.traceNullifierCheck(new Fr(42), new Fr(42), new Fr(42), false, true)).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('Should enforce maximum number of nullifier non-existent checks', () => { - for (let i = 0; i < MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX; i++) { - trace.traceNullifierCheck(new Fr(i), new Fr(i), new Fr(i), false, true); - } - expect(() => trace.traceNullifierCheck(new Fr(42), new Fr(42), new Fr(42), false, true)).toThrow( - SideEffectLimitReachedError, - ); - // NOTE: also cannot do a existent check once non-existent checks have filled up - expect(() => trace.traceNullifierCheck(new Fr(42), new Fr(42), new Fr(42), true, true)).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('Should enforce maximum number of new nullifiers', () => { - for (let i = 0; i < MAX_NULLIFIERS_PER_TX; i++) { - trace.traceNewNullifier(new Fr(i), new Fr(i)); - } - expect(() => trace.traceNewNullifier(new Fr(42), new Fr(42))).toThrow(SideEffectLimitReachedError); - }); - - it('Should enforce maximum number of L1 to L2 message checks', () => { - for (let i = 0; i < MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX; i++) { - trace.traceL1ToL2MessageCheck(new Fr(i), new Fr(i), new Fr(i), true); - } - expect(() => trace.traceL1ToL2MessageCheck(new Fr(42), new Fr(42), new Fr(42), true)).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('Should enforce maximum number of new l2 to l1 messages', () => { - for (let i = 0; i < MAX_L2_TO_L1_MSGS_PER_TX; i++) { - trace.traceNewL2ToL1Message(new Fr(i), new Fr(i), new Fr(i)); - } - expect(() => trace.traceNewL2ToL1Message(new Fr(42), new Fr(42), new Fr(42))).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('Should enforce maximum number of new logs hashes', () => { - for (let i = 0; i < MAX_UNENCRYPTED_LOGS_PER_TX; i++) { - trace.traceUnencryptedLog(new Fr(i), [new Fr(i), new Fr(i)]); - } - expect(() => trace.traceUnencryptedLog(new Fr(42), [new Fr(42), new Fr(42)])).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('Should enforce maximum number of nullifier checks for GETCONTRACTINSTANCE', () => { - for (let i = 0; i < MAX_NULLIFIER_READ_REQUESTS_PER_TX; i++) { - trace.traceNullifierCheck(new Fr(i), new Fr(i), new Fr(i), true, true); - } - expect(() => trace.traceGetContractInstance({ ...contractInstance, exists: true })).toThrow( - SideEffectLimitReachedError, - ); - // NOTE: also cannot do a existent check once non-existent checks have filled up - expect(() => trace.traceGetContractInstance({ ...contractInstance, exists: false })).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('Should enforce maximum number of nullifier non-existent checks for GETCONTRACTINSTANCE', () => { - for (let i = 0; i < MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX; i++) { - trace.traceNullifierCheck(new Fr(i), new Fr(i), new Fr(i), false, true); - } - expect(() => trace.traceGetContractInstance({ ...contractInstance, exists: false })).toThrow( - SideEffectLimitReachedError, - ); - // NOTE: also cannot do a existent check once non-existent checks have filled up - expect(() => trace.traceGetContractInstance({ ...contractInstance, exists: true })).toThrow( - SideEffectLimitReachedError, - ); - }); - - it('PreviousValidationRequestArrayLengths and PreviousAccumulatedDataArrayLengths contribute to limits', () => { - trace = new PublicEnqueuedCallSideEffectTrace( - 0, - new PublicValidationRequestArrayLengths( - MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, - MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX, - ), - new PublicAccumulatedDataArrayLengths( - MAX_NOTE_HASHES_PER_TX, - MAX_NULLIFIERS_PER_TX, - MAX_L2_TO_L1_MSGS_PER_TX, - 0, - 0, - MAX_UNENCRYPTED_LOGS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX, - 0, - ), - ); - expect(() => trace.tracePublicStorageRead(new Fr(42), new Fr(42), new Fr(42), true, true)).toThrow( - SideEffectLimitReachedError, - ); - expect(() => trace.tracePublicStorageWrite(new Fr(42), new Fr(42), new Fr(42))).toThrow( - SideEffectLimitReachedError, - ); - expect(() => trace.traceNoteHashCheck(new Fr(42), new Fr(42), new Fr(42), true)).toThrow( - SideEffectLimitReachedError, - ); - expect(() => trace.traceNewNoteHash(new Fr(42), new Fr(42))).toThrow(SideEffectLimitReachedError); - expect(() => trace.traceNullifierCheck(new Fr(42), new Fr(42), new Fr(42), false, true)).toThrow( - SideEffectLimitReachedError, - ); - expect(() => trace.traceNullifierCheck(new Fr(42), new Fr(42), new Fr(42), true, true)).toThrow( - SideEffectLimitReachedError, - ); - expect(() => trace.traceNewNullifier(new Fr(42), new Fr(42))).toThrow(SideEffectLimitReachedError); - expect(() => trace.traceL1ToL2MessageCheck(new Fr(42), new Fr(42), new Fr(42), true)).toThrow( - SideEffectLimitReachedError, - ); - expect(() => trace.traceNewL2ToL1Message(new Fr(42), new Fr(42), new Fr(42))).toThrow( - SideEffectLimitReachedError, - ); - expect(() => trace.traceUnencryptedLog(new Fr(42), [new Fr(42), new Fr(42)])).toThrow( - SideEffectLimitReachedError, - ); - expect(() => trace.traceGetContractInstance({ ...contractInstance, exists: false })).toThrow( - SideEffectLimitReachedError, - ); - expect(() => trace.traceGetContractInstance({ ...contractInstance, exists: true })).toThrow( - SideEffectLimitReachedError, - ); - }); - }); - - describe.each([avmCallResults, avmCallRevertedResults])('Should trace & absorb nested calls', callResults => { - it(`${callResults.reverted ? 'Reverted' : 'Successful'} calls should be traced and absorbed properly`, () => { - const existsDefault = true; - const cached = false; - const isPending = false; - - const nestedTrace = new PublicEnqueuedCallSideEffectTrace(startCounter); - let testCounter = startCounter; - nestedTrace.tracePublicStorageRead(address, slot, value, existsDefault, cached); - testCounter++; - nestedTrace.tracePublicStorageWrite(address, slot, value); - testCounter++; - nestedTrace.traceNoteHashCheck(address, utxo, leafIndex, existsDefault); - // counter does not increment for note hash checks - nestedTrace.traceNewNoteHash(address, utxo); - testCounter++; - nestedTrace.traceNullifierCheck(address, utxo, leafIndex, /*exists=*/ true, isPending); - testCounter++; - nestedTrace.traceNullifierCheck(address, utxo, leafIndex, /*exists=*/ false, isPending); - testCounter++; - nestedTrace.traceNewNullifier(address, utxo); - testCounter++; - nestedTrace.traceL1ToL2MessageCheck(address, utxo, leafIndex, existsDefault); - // counter does not increment for l1tol2 message checks - nestedTrace.traceNewL2ToL1Message(address, recipient, content); - testCounter++; - nestedTrace.traceUnencryptedLog(address, log); - testCounter++; - nestedTrace.traceGetContractInstance({ ...contractInstance, exists: true }); - testCounter++; - nestedTrace.traceGetContractInstance({ ...contractInstance, exists: false }); - testCounter++; - - trace.traceNestedCall(nestedTrace, avmEnvironment, startGasLeft, endGasLeft, bytecode, callResults); - - // parent trace adopts nested call's counter - expect(trace.getCounter()).toBe(testCounter); - - // parent absorbs child's side effects - const parentSideEffects = trace.getSideEffects(); - const childSideEffects = nestedTrace.getSideEffects(); - if (callResults.reverted) { - expect(parentSideEffects.contractStorageReads).toEqual(childSideEffects.contractStorageReads); - expect(parentSideEffects.contractStorageUpdateRequests).toEqual(childSideEffects.contractStorageUpdateRequests); - expect(parentSideEffects.noteHashReadRequests).toEqual(childSideEffects.noteHashReadRequests); - expect(parentSideEffects.noteHashes).toEqual([]); - expect(parentSideEffects.nullifierReadRequests).toEqual(childSideEffects.nullifierReadRequests); - expect(parentSideEffects.nullifierNonExistentReadRequests).toEqual( - childSideEffects.nullifierNonExistentReadRequests, - ); - expect(parentSideEffects.nullifiers).toEqual(childSideEffects.nullifiers); - expect(parentSideEffects.l1ToL2MsgReadRequests).toEqual(childSideEffects.l1ToL2MsgReadRequests); - expect(parentSideEffects.l2ToL1Msgs).toEqual([]); - expect(parentSideEffects.unencryptedLogs).toEqual([]); - expect(parentSideEffects.unencryptedLogsHashes).toEqual([]); - } else { - expect(parentSideEffects).toEqual(childSideEffects); - } - }); - }); -}); diff --git a/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts b/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts deleted file mode 100644 index fb09b3122b74..000000000000 --- a/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts +++ /dev/null @@ -1,552 +0,0 @@ -import { UnencryptedL2Log } from '@aztec/circuit-types'; -import { - AvmContractInstanceHint, - AvmExecutionHints, - AvmExternalCallHint, - AvmKeyValueHint, - AztecAddress, - CallContext, - type CombinedConstantData, - ContractStorageRead, - ContractStorageUpdateRequest, - EthAddress, - Gas, - L2ToL1Message, - LogHash, - MAX_ENCRYPTED_LOGS_PER_TX, - MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, - MAX_L2_TO_L1_MSGS_PER_TX, - MAX_NOTE_ENCRYPTED_LOGS_PER_TX, - MAX_NOTE_HASHES_PER_TX, - MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIERS_PER_TX, - MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_UNENCRYPTED_LOGS_PER_TX, - NoteHash, - Nullifier, - PublicAccumulatedData, - PublicAccumulatedDataArrayLengths, - PublicCallRequest, - PublicDataRead, - PublicDataUpdateRequest, - PublicInnerCallRequest, - PublicValidationRequestArrayLengths, - PublicValidationRequests, - ReadRequest, - RollupValidationRequests, - ScopedL2ToL1Message, - ScopedLogHash, - ScopedNoteHash, - type ScopedNullifier, - ScopedReadRequest, - TreeLeafReadRequest, - VMCircuitPublicInputs, -} from '@aztec/circuits.js'; -import { computeVarArgsHash } from '@aztec/circuits.js/hash'; -import { makeTuple } from '@aztec/foundation/array'; -import { padArrayEnd } from '@aztec/foundation/collection'; -import { Fr } from '@aztec/foundation/fields'; -import { createDebugLogger } from '@aztec/foundation/log'; -import { type ContractInstanceWithAddress } from '@aztec/types/contracts'; - -import { type AvmContractCallResult } from '../avm/avm_contract_call_result.js'; -import { type AvmExecutionEnvironment } from '../avm/avm_execution_environment.js'; -import { SideEffectLimitReachedError } from './side_effect_errors.js'; -import { type PublicSideEffectTraceInterface } from './side_effect_trace_interface.js'; - -export type TracedContractInstance = { exists: boolean } & ContractInstanceWithAddress; - -/** - * A struct containing just the side effects as regular arrays - * as opposed to "Tuple" arrays used by circuit public inputs. - * This struct is helpful for testing and checking array lengths. - **/ -export type SideEffects = { - contractStorageReads: ContractStorageRead[]; - contractStorageUpdateRequests: ContractStorageUpdateRequest[]; - - noteHashReadRequests: TreeLeafReadRequest[]; - noteHashes: ScopedNoteHash[]; - - nullifierReadRequests: ScopedReadRequest[]; - nullifierNonExistentReadRequests: ScopedReadRequest[]; - nullifiers: ScopedNullifier[]; - - l1ToL2MsgReadRequests: TreeLeafReadRequest[]; - l2ToL1Msgs: ScopedL2ToL1Message[]; - - unencryptedLogs: UnencryptedL2Log[]; - unencryptedLogsHashes: ScopedLogHash[]; -}; - -/** - * Trace side effects for an entire enqueued call. - */ -export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceInterface { - public log = createDebugLogger('aztec:public_enqueued_call_side_effect_trace'); - - /** The side effect counter increments with every call to the trace. */ - private sideEffectCounter: number; - - // TODO(dbanks12): make contract address mandatory in ContractStorage* structs, - // and include it in serialization, or modify PublicData* structs for this. - private contractStorageReads: ContractStorageRead[] = []; - private contractStorageUpdateRequests: ContractStorageUpdateRequest[] = []; - - private noteHashReadRequests: TreeLeafReadRequest[] = []; - private noteHashes: ScopedNoteHash[] = []; - - private nullifierReadRequests: ScopedReadRequest[] = []; - private nullifierNonExistentReadRequests: ScopedReadRequest[] = []; - private nullifiers: ScopedNullifier[] = []; - - private l1ToL2MsgReadRequests: TreeLeafReadRequest[] = []; - private l2ToL1Msgs: ScopedL2ToL1Message[] = []; - - private unencryptedLogs: UnencryptedL2Log[] = []; - private unencryptedLogsHashes: ScopedLogHash[] = []; - - private avmCircuitHints: AvmExecutionHints; - - constructor( - /** The counter of this trace's first side effect. */ - public readonly startSideEffectCounter: number = 0, - /** Track parent's (or previous kernel's) lengths so the AVM can properly enforce TX-wide limits, - * otherwise the public kernel can fail to prove because TX limits are breached. - */ - private readonly previousValidationRequestArrayLengths: PublicValidationRequestArrayLengths = PublicValidationRequestArrayLengths.empty(), - private readonly previousAccumulatedDataArrayLengths: PublicAccumulatedDataArrayLengths = PublicAccumulatedDataArrayLengths.empty(), - ) { - this.sideEffectCounter = startSideEffectCounter; - this.avmCircuitHints = AvmExecutionHints.empty(); - } - - public fork() { - return new PublicEnqueuedCallSideEffectTrace( - this.sideEffectCounter, - new PublicValidationRequestArrayLengths( - this.previousValidationRequestArrayLengths.noteHashReadRequests + this.noteHashReadRequests.length, - this.previousValidationRequestArrayLengths.nullifierReadRequests + this.nullifierReadRequests.length, - this.previousValidationRequestArrayLengths.nullifierNonExistentReadRequests + - this.nullifierNonExistentReadRequests.length, - this.previousValidationRequestArrayLengths.l1ToL2MsgReadRequests + this.l1ToL2MsgReadRequests.length, - this.previousValidationRequestArrayLengths.publicDataReads + this.contractStorageReads.length, - ), - new PublicAccumulatedDataArrayLengths( - this.previousAccumulatedDataArrayLengths.noteHashes + this.noteHashes.length, - this.previousAccumulatedDataArrayLengths.nullifiers + this.nullifiers.length, - this.previousAccumulatedDataArrayLengths.l2ToL1Msgs + this.l2ToL1Msgs.length, - this.previousAccumulatedDataArrayLengths.noteEncryptedLogsHashes, - this.previousAccumulatedDataArrayLengths.encryptedLogsHashes, - this.previousAccumulatedDataArrayLengths.unencryptedLogsHashes + this.unencryptedLogsHashes.length, - this.previousAccumulatedDataArrayLengths.publicDataUpdateRequests + this.contractStorageUpdateRequests.length, - this.previousAccumulatedDataArrayLengths.publicCallStack, - ), - ); - } - - public getCounter() { - return this.sideEffectCounter; - } - - private incrementSideEffectCounter() { - this.sideEffectCounter++; - } - - public tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, _exists: boolean, _cached: boolean) { - // NOTE: exists and cached are unused for now but may be used for optimizations or kernel hints later - if ( - this.contractStorageReads.length + this.previousValidationRequestArrayLengths.publicDataReads >= - MAX_PUBLIC_DATA_READS_PER_TX - ) { - throw new SideEffectLimitReachedError('contract storage read', MAX_PUBLIC_DATA_READS_PER_TX); - } - - this.contractStorageReads.push( - new ContractStorageRead(slot, value, this.sideEffectCounter, AztecAddress.fromField(storageAddress)), - ); - this.avmCircuitHints.storageValues.items.push( - new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ value), - ); - this.log.debug(`SLOAD cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`); - this.incrementSideEffectCounter(); - } - - public tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr) { - if ( - this.contractStorageUpdateRequests.length + this.previousAccumulatedDataArrayLengths.publicDataUpdateRequests >= - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX - ) { - throw new SideEffectLimitReachedError('contract storage write', MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX); - } - - this.contractStorageUpdateRequests.push( - new ContractStorageUpdateRequest(slot, value, this.sideEffectCounter, storageAddress), - ); - this.log.debug(`SSTORE cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`); - this.incrementSideEffectCounter(); - } - - // TODO(8287): _exists can be removed once we have the vm properly handling the equality check - public traceNoteHashCheck(_storageAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean) { - // NOTE: storageAddress is unused because noteHash is an already-siloed leaf - if ( - this.noteHashReadRequests.length + this.previousValidationRequestArrayLengths.noteHashReadRequests >= - MAX_NOTE_HASH_READ_REQUESTS_PER_TX - ) { - throw new SideEffectLimitReachedError('note hash read request', MAX_NOTE_HASH_READ_REQUESTS_PER_TX); - } - - this.noteHashReadRequests.push(new TreeLeafReadRequest(noteHash, leafIndex)); - this.avmCircuitHints.noteHashExists.items.push( - new AvmKeyValueHint(/*key=*/ new Fr(leafIndex), /*value=*/ exists ? Fr.ONE : Fr.ZERO), - ); - // NOTE: counter does not increment for note hash checks (because it doesn't rely on pending note hashes) - } - - public traceNewNoteHash(storageAddress: Fr, noteHash: Fr) { - if (this.noteHashes.length + this.previousAccumulatedDataArrayLengths.noteHashes >= MAX_NOTE_HASHES_PER_TX) { - throw new SideEffectLimitReachedError('note hash', MAX_NOTE_HASHES_PER_TX); - } - - this.noteHashes.push(new NoteHash(noteHash, this.sideEffectCounter).scope(AztecAddress.fromField(storageAddress))); - this.log.debug(`NEW_NOTE_HASH cnt: ${this.sideEffectCounter}`); - this.incrementSideEffectCounter(); - } - - public traceNullifierCheck(storageAddress: Fr, nullifier: Fr, _leafIndex: Fr, exists: boolean, _isPending: boolean) { - // NOTE: isPending and leafIndex are unused for now but may be used for optimizations or kernel hints later - this.enforceLimitOnNullifierChecks(); - - const readRequest = new ReadRequest(nullifier, this.sideEffectCounter).scope( - AztecAddress.fromField(storageAddress), - ); - if (exists) { - this.nullifierReadRequests.push(readRequest); - } else { - this.nullifierNonExistentReadRequests.push(readRequest); - } - this.avmCircuitHints.nullifierExists.items.push( - new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ new Fr(exists ? 1 : 0)), - ); - this.log.debug(`NULLIFIER_EXISTS cnt: ${this.sideEffectCounter}`); - this.incrementSideEffectCounter(); - } - - public traceNewNullifier(storageAddress: Fr, nullifier: Fr) { - if (this.nullifiers.length + this.previousAccumulatedDataArrayLengths.nullifiers >= MAX_NULLIFIERS_PER_TX) { - throw new SideEffectLimitReachedError('nullifier', MAX_NULLIFIERS_PER_TX); - } - - this.nullifiers.push( - new Nullifier(nullifier, this.sideEffectCounter, /*noteHash=*/ Fr.ZERO).scope( - AztecAddress.fromField(storageAddress), - ), - ); - this.log.debug(`NEW_NULLIFIER cnt: ${this.sideEffectCounter}`); - this.incrementSideEffectCounter(); - } - - // TODO(8287): _exists can be removed once we have the vm properly handling the equality check - public traceL1ToL2MessageCheck(_contractAddress: Fr, msgHash: Fr, msgLeafIndex: Fr, exists: boolean) { - // NOTE: contractAddress is unused because msgHash is an already-siloed leaf - if ( - this.l1ToL2MsgReadRequests.length + this.previousValidationRequestArrayLengths.l1ToL2MsgReadRequests >= - MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX - ) { - throw new SideEffectLimitReachedError('l1 to l2 message read request', MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX); - } - - this.l1ToL2MsgReadRequests.push(new TreeLeafReadRequest(msgHash, msgLeafIndex)); - this.avmCircuitHints.l1ToL2MessageExists.items.push( - new AvmKeyValueHint(/*key=*/ new Fr(msgLeafIndex), /*value=*/ exists ? Fr.ONE : Fr.ZERO), - ); - } - - public traceNewL2ToL1Message(contractAddress: Fr, recipient: Fr, content: Fr) { - if (this.l2ToL1Msgs.length + this.previousAccumulatedDataArrayLengths.l2ToL1Msgs >= MAX_L2_TO_L1_MSGS_PER_TX) { - throw new SideEffectLimitReachedError('l2 to l1 message', MAX_L2_TO_L1_MSGS_PER_TX); - } - - const recipientAddress = EthAddress.fromField(recipient); - this.l2ToL1Msgs.push( - new L2ToL1Message(recipientAddress, content, this.sideEffectCounter).scope( - AztecAddress.fromField(contractAddress), - ), - ); - this.log.debug(`NEW_L2_TO_L1_MSG cnt: ${this.sideEffectCounter}`); - this.incrementSideEffectCounter(); - } - - public traceUnencryptedLog(contractAddress: Fr, log: Fr[]) { - if ( - this.unencryptedLogs.length + this.previousAccumulatedDataArrayLengths.unencryptedLogsHashes >= - MAX_UNENCRYPTED_LOGS_PER_TX - ) { - throw new SideEffectLimitReachedError('unencrypted log', MAX_UNENCRYPTED_LOGS_PER_TX); - } - - const ulog = new UnencryptedL2Log( - AztecAddress.fromField(contractAddress), - Buffer.concat(log.map(f => f.toBuffer())), - ); - const basicLogHash = Fr.fromBuffer(ulog.hash()); - this.unencryptedLogs.push(ulog); - // This length is for charging DA and is checked on-chain - has to be length of log preimage + 4 bytes. - // The .length call also has a +4 but that is unrelated - this.unencryptedLogsHashes.push( - new LogHash(basicLogHash, this.sideEffectCounter, new Fr(ulog.length + 4)).scope( - AztecAddress.fromField(contractAddress), - ), - ); - this.log.debug(`NEW_UNENCRYPTED_LOG cnt: ${this.sideEffectCounter}`); - this.incrementSideEffectCounter(); - } - - public traceGetContractInstance(instance: TracedContractInstance) { - this.enforceLimitOnNullifierChecks('(contract address nullifier from GETCONTRACTINSTANCE)'); - // TODO(dbanks12): should emit a nullifier read request - - this.avmCircuitHints.contractInstances.items.push( - new AvmContractInstanceHint( - instance.address, - new Fr(instance.exists ? 1 : 0), - instance.salt, - instance.deployer, - instance.contractClassId, - instance.initializationHash, - instance.publicKeysHash, - ), - ); - this.log.debug(`CONTRACT_INSTANCE cnt: ${this.sideEffectCounter}`); - this.incrementSideEffectCounter(); - } - - /** - * Trace a nested call. - * Accept some results from a finished nested call's trace into this one. - */ - public traceNestedCall( - /** The trace of the nested call. */ - nestedCallTrace: this, - /** The execution environment of the nested call. */ - _nestedEnvironment: AvmExecutionEnvironment, - /** How much gas was available for this public execution. */ - startGasLeft: Gas, - /** How much gas was left after this public execution. */ - endGasLeft: Gas, - /** Bytecode used for this execution. */ - _bytecode: Buffer, - /** The call's results */ - avmCallResults: AvmContractCallResult, - /** Function name for logging */ - _functionName: string = 'unknown', - ) { - // Store end side effect counter before it gets updated by absorbing nested call trace - const endSideEffectCounter = new Fr(this.sideEffectCounter); - - // TODO(4805): check if some threshold is reached for max nested calls (to unique contracts?) - // TODO(dbanks12): should emit a nullifier read request. There should be two thresholds. - // one for max unique contract calls, and another based on max nullifier reads. - // Since this trace function happens _after_ a nested call, such threshold limits must take - // place in another trace function that occurs _before_ a nested call. - if (avmCallResults.reverted) { - this.absorbRevertedNestedTrace(nestedCallTrace); - } else { - this.absorbSuccessfulNestedTrace(nestedCallTrace); - } - - const gasUsed = new Gas(startGasLeft.daGas - endGasLeft.daGas, startGasLeft.l2Gas - endGasLeft.l2Gas); - - this.avmCircuitHints.externalCalls.items.push( - new AvmExternalCallHint( - /*success=*/ new Fr(avmCallResults.reverted ? 0 : 1), - avmCallResults.output, - gasUsed, - endSideEffectCounter, - ), - ); - } - - public absorbSuccessfulNestedTrace(nestedTrace: this) { - this.sideEffectCounter = nestedTrace.sideEffectCounter; - this.contractStorageReads.push(...nestedTrace.contractStorageReads); - this.contractStorageUpdateRequests.push(...nestedTrace.contractStorageUpdateRequests); - this.noteHashReadRequests.push(...nestedTrace.noteHashReadRequests); - this.noteHashes.push(...nestedTrace.noteHashes); - this.nullifierReadRequests.push(...nestedTrace.nullifierReadRequests); - this.nullifierNonExistentReadRequests.push(...nestedTrace.nullifierNonExistentReadRequests); - this.nullifiers.push(...nestedTrace.nullifiers); - this.l1ToL2MsgReadRequests.push(...nestedTrace.l1ToL2MsgReadRequests); - this.l2ToL1Msgs.push(...nestedTrace.l2ToL1Msgs); - this.unencryptedLogs.push(...nestedTrace.unencryptedLogs); - this.unencryptedLogsHashes.push(...nestedTrace.unencryptedLogsHashes); - } - - public absorbRevertedNestedTrace(nestedTrace: this) { - // All read requests, and any writes (storage & nullifiers) that - // require complex validation in public kernel (with end lifetimes) - // must be absorbed even on revert. - - // TODO(dbanks12): What should happen to side effect counter on revert? - this.sideEffectCounter = nestedTrace.sideEffectCounter; - this.contractStorageReads.push(...nestedTrace.contractStorageReads); - this.contractStorageUpdateRequests.push(...nestedTrace.contractStorageUpdateRequests); - this.noteHashReadRequests.push(...nestedTrace.noteHashReadRequests); - // new noteHashes are tossed on revert - this.nullifierReadRequests.push(...nestedTrace.nullifierReadRequests); - this.nullifierNonExistentReadRequests.push(...nestedTrace.nullifierNonExistentReadRequests); - this.nullifiers.push(...nestedTrace.nullifiers); - this.l1ToL2MsgReadRequests.push(...nestedTrace.l1ToL2MsgReadRequests); - // new l2-to-l1 messages are tossed on revert - // new unencrypted logs are tossed on revert - } - - public getSideEffects(): SideEffects { - return { - contractStorageReads: this.contractStorageReads, - contractStorageUpdateRequests: this.contractStorageUpdateRequests, - noteHashReadRequests: this.noteHashReadRequests, - noteHashes: this.noteHashes, - nullifierReadRequests: this.nullifierReadRequests, - nullifierNonExistentReadRequests: this.nullifierNonExistentReadRequests, - nullifiers: this.nullifiers, - l1ToL2MsgReadRequests: this.l1ToL2MsgReadRequests, - l2ToL1Msgs: this.l2ToL1Msgs, - unencryptedLogs: this.unencryptedLogs, - unencryptedLogsHashes: this.unencryptedLogsHashes, - }; - } - - public toVMCircuitPublicInputs( - /** Constants. */ - constants: CombinedConstantData, - /** The execution environment of the nested call. */ - avmEnvironment: AvmExecutionEnvironment, - /** How much gas was available for this public execution. */ - startGasLeft: Gas, - /** How much gas was left after this public execution. */ - endGasLeft: Gas, - /** The call's results */ - avmCallResults: AvmContractCallResult, - ): VMCircuitPublicInputs { - return new VMCircuitPublicInputs( - /*constants=*/ constants, - /*callRequest=*/ createPublicCallRequest(avmEnvironment), - /*publicCallStack=*/ makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, PublicInnerCallRequest.empty), - /*previousValidationRequestArrayLengths=*/ this.previousValidationRequestArrayLengths, - /*validationRequests=*/ this.getValidationRequests(), - /*previousAccumulatedDataArrayLengths=*/ this.previousAccumulatedDataArrayLengths, - /*accumulatedData=*/ this.getAccumulatedData(startGasLeft.sub(endGasLeft)), - /*startSideEffectCounter=*/ this.startSideEffectCounter, - /*endSideEffectCounter=*/ this.sideEffectCounter, - /*startGasLeft=*/ startGasLeft, - // TODO(dbanks12): should have endGasLeft - /*transactionFee=*/ avmEnvironment.transactionFee, - /*reverted=*/ avmCallResults.reverted, - ); - } - - public getUnencryptedLogs() { - return this.unencryptedLogs; - } - - public getAvmCircuitHints() { - return this.avmCircuitHints; - } - - private getValidationRequests() { - return new PublicValidationRequests( - RollupValidationRequests.empty(), // TODO(dbanks12): what should this be? - padArrayEnd(this.noteHashReadRequests, TreeLeafReadRequest.empty(), MAX_NOTE_HASH_READ_REQUESTS_PER_TX), - padArrayEnd(this.nullifierReadRequests, ScopedReadRequest.empty(), MAX_NULLIFIER_READ_REQUESTS_PER_TX), - padArrayEnd( - this.nullifierNonExistentReadRequests, - ScopedReadRequest.empty(), - MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, - ), - padArrayEnd(this.l1ToL2MsgReadRequests, TreeLeafReadRequest.empty(), MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX), - // TODO(dbanks12): this is only necessary until VMCircuitPublicInputs uses unsiloed storage slots and pairs storage accesses with contract address - padArrayEnd( - this.contractStorageReads.map(r => new PublicDataRead(r.storageSlot, r.currentValue, r.counter)), - PublicDataRead.empty(), - MAX_PUBLIC_DATA_READS_PER_TX, - ), - ); - } - - private getAccumulatedData(gasUsed: Gas) { - return new PublicAccumulatedData( - padArrayEnd(this.noteHashes, ScopedNoteHash.empty(), MAX_NOTE_HASHES_PER_TX), - // TODO(dbanks12): should be able to use ScopedNullifier here - padArrayEnd( - this.nullifiers.map(n => new Nullifier(n.nullifier.value, n.nullifier.counter, n.nullifier.noteHash)), - Nullifier.empty(), - MAX_NULLIFIERS_PER_TX, - ), - padArrayEnd(this.l2ToL1Msgs, ScopedL2ToL1Message.empty(), MAX_L2_TO_L1_MSGS_PER_TX), - /*noteEncryptedLogsHashes=*/ makeTuple(MAX_NOTE_ENCRYPTED_LOGS_PER_TX, LogHash.empty), - /*encryptedLogsHashes=*/ makeTuple(MAX_ENCRYPTED_LOGS_PER_TX, ScopedLogHash.empty), - padArrayEnd(this.unencryptedLogsHashes, ScopedLogHash.empty(), MAX_UNENCRYPTED_LOGS_PER_TX), - // TODO(dbanks12): this is only necessary until VMCircuitPublicInputs uses unsiloed storage slots and pairs storage accesses with contract address - padArrayEnd( - this.contractStorageUpdateRequests.map(w => new PublicDataUpdateRequest(w.storageSlot, w.newValue, w.counter)), - PublicDataUpdateRequest.empty(), - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - ), - /*publicCallStack=*/ makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, PublicCallRequest.empty), - /*gasUsed=*/ gasUsed, - ); - } - - private enforceLimitOnNullifierChecks(errorMsgOrigin: string = '') { - // NOTE: Why error if _either_ limit was reached? If user code emits either an existent or non-existent - // nullifier read request (NULLIFIEREXISTS, GETCONTRACTINSTANCE, *CALL), and one of the limits has been - // reached (MAX_NULLIFIER_NON_EXISTENT_RRS vs MAX_NULLIFIER_RRS), but not the other, we must prevent the - // sequencer from lying and saying "this nullifier exists, but MAX_NULLIFIER_RRS has been reached, so I'm - // going to skip the read request and just revert instead" when the nullifier actually doesn't exist - // (or vice versa). So, if either maximum has been reached, any nullifier-reading operation must error. - if ( - this.nullifierReadRequests.length + this.previousValidationRequestArrayLengths.nullifierReadRequests >= - MAX_NULLIFIER_READ_REQUESTS_PER_TX - ) { - throw new SideEffectLimitReachedError( - `nullifier read request ${errorMsgOrigin}`, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, - ); - } - if ( - this.nullifierNonExistentReadRequests.length + - this.previousValidationRequestArrayLengths.nullifierNonExistentReadRequests >= - MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX - ) { - throw new SideEffectLimitReachedError( - `nullifier non-existent read request ${errorMsgOrigin}`, - MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, - ); - } - } -} - -/** - * Helper function to create a public execution request from an AVM execution environment - */ -function createPublicCallRequest(avmEnvironment: AvmExecutionEnvironment): PublicCallRequest { - const callContext = CallContext.from({ - msgSender: avmEnvironment.sender, - storageContractAddress: avmEnvironment.storageAddress, - functionSelector: avmEnvironment.functionSelector, - isDelegateCall: avmEnvironment.isDelegateCall, - isStaticCall: avmEnvironment.isStaticCall, - }); - return new PublicCallRequest( - avmEnvironment.address, - callContext, - computeVarArgsHash(avmEnvironment.calldata), - /*counter=*/ 0, - ); -} diff --git a/yarn-project/simulator/src/public/enqueued_call_simulator.ts b/yarn-project/simulator/src/public/enqueued_call_simulator.ts index c22cc233e1c3..83d6b578ee56 100644 --- a/yarn-project/simulator/src/public/enqueued_call_simulator.ts +++ b/yarn-project/simulator/src/public/enqueued_call_simulator.ts @@ -122,48 +122,33 @@ export class EnqueuedCallSimulator { ): Promise { const pendingNullifiers = this.getSiloedPendingNullifiers(previousPublicKernelOutput); const startSideEffectCounter = previousPublicKernelOutput.endSideEffectCounter + 1; - - const prevAccumulatedData = - phase === PublicKernelPhase.SETUP - ? previousPublicKernelOutput.endNonRevertibleData - : previousPublicKernelOutput.end; - const previousValidationRequestArrayLengths = PublicValidationRequestArrayLengths.new( - previousPublicKernelOutput.validationRequests, - ); - const previousAccumulatedDataArrayLengths = PublicAccumulatedDataArrayLengths.new(prevAccumulatedData); - - // If this is the first enqueued call in public, constants will be empty - // because private kernel does not expose them. - const constants = previousPublicKernelOutput.constants; - constants.globalVariables = this.globalVariables; - const result = await this.publicExecutor.simulate( executionRequest, - constants, + this.globalVariables, availableGas, tx.data.constants.txContext, pendingNullifiers, transactionFee, startSideEffectCounter, - previousValidationRequestArrayLengths, - previousAccumulatedDataArrayLengths, ); const callStack = makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, PublicInnerCallRequest.empty); callStack[0].item.contractAddress = callRequest.contractAddress; callStack[0].item.callContext = callRequest.callContext; callStack[0].item.argsHash = callRequest.argsHash; - + const prevAccumulatedData = + phase === PublicKernelPhase.SETUP + ? previousPublicKernelOutput.endNonRevertibleData + : previousPublicKernelOutput.end; const accumulatedData = PublicAccumulatedData.empty(); accumulatedData.publicCallStack[0] = callRequest; - const startVMCircuitOutput = new VMCircuitPublicInputs( previousPublicKernelOutput.constants, callRequest, callStack, - previousValidationRequestArrayLengths, + PublicValidationRequestArrayLengths.new(previousPublicKernelOutput.validationRequests), PublicValidationRequests.empty(), - previousAccumulatedDataArrayLengths, + PublicAccumulatedDataArrayLengths.new(prevAccumulatedData), accumulatedData, startSideEffectCounter, startSideEffectCounter, diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index cb4c3ec76926..95204219af36 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -1,15 +1,6 @@ import { type PublicExecutionRequest } from '@aztec/circuit-types'; import { type AvmSimulationStats } from '@aztec/circuit-types/stats'; -import { - type CombinedConstantData, - Fr, - Gas, - type GlobalVariables, - type Nullifier, - PublicAccumulatedDataArrayLengths, - PublicValidationRequestArrayLengths, - type TxContext, -} from '@aztec/circuits.js'; +import { Fr, Gas, type GlobalVariables, type Nullifier, type TxContext } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; import { type TelemetryClient } from '@aztec/telemetry-client'; @@ -20,8 +11,6 @@ import { AvmMachineState } from '../avm/avm_machine_state.js'; import { AvmSimulator } from '../avm/avm_simulator.js'; import { AvmPersistableStateManager } from '../avm/journal/index.js'; import { getPublicFunctionDebugName } from '../common/debug_fn_name.js'; -import { DualSideEffectTrace } from './dual_side_effect_trace.js'; -import { PublicEnqueuedCallSideEffectTrace } from './enqueued_call_side_effect_trace.js'; import { type PublicExecutionResult } from './execution.js'; import { ExecutorMetrics } from './executor_metrics.js'; import { type WorldStateDB } from './public_db_sources.js'; @@ -42,26 +31,22 @@ export class PublicExecutor { /** * Executes a public execution request. * @param executionRequest - The execution to run. - * @param constants - The constants (including global variables) to use. + * @param globalVariables - The global variables to use. * @param availableGas - The gas available at the start of this enqueued call. * @param txContext - Transaction context. * @param pendingSiloedNullifiers - The pending nullifier set from earlier parts of this TX. * @param transactionFee - Fee offered for this TX. * @param startSideEffectCounter - The counter of the first side-effect generated by this simulation. - * @param previousValidationRequestArrayLengths - Side effect array lengths from previous kernel - * @param previousAccumulatedDataArrayLengths - Side effect array lengths from previous kernel * @returns The result of execution, including the results of all nested calls. */ public async simulate( executionRequest: PublicExecutionRequest, - constants: CombinedConstantData, + globalVariables: GlobalVariables, availableGas: Gas, _txContext: TxContext, pendingSiloedNullifiers: Nullifier[], transactionFee: Fr = Fr.ZERO, startSideEffectCounter: number = 0, - previousValidationRequestArrayLengths: PublicValidationRequestArrayLengths = PublicValidationRequestArrayLengths.empty(), - previousAccumulatedDataArrayLengths: PublicAccumulatedDataArrayLengths = PublicAccumulatedDataArrayLengths.empty(), ): Promise { const address = executionRequest.contractAddress; const selector = executionRequest.callContext.functionSelector; @@ -70,20 +55,14 @@ export class PublicExecutor { PublicExecutor.log.verbose(`[AVM] Executing public external function ${fnName}@${address}.`); const timer = new Timer(); - const innerCallTrace = new PublicSideEffectTrace(startSideEffectCounter); - const enqueuedCallTrace = new PublicEnqueuedCallSideEffectTrace( - startSideEffectCounter, - previousValidationRequestArrayLengths, - previousAccumulatedDataArrayLengths, - ); - const trace = new DualSideEffectTrace(innerCallTrace, enqueuedCallTrace); + const trace = new PublicSideEffectTrace(startSideEffectCounter); const avmPersistableState = AvmPersistableStateManager.newWithPendingSiloedNullifiers( this.worldStateDB, trace, pendingSiloedNullifiers.map(n => n.value), ); - const avmExecutionEnv = createAvmExecutionEnvironment(executionRequest, constants.globalVariables, transactionFee); + const avmExecutionEnv = createAvmExecutionEnvironment(executionRequest, globalVariables, transactionFee); const avmMachineState = new AvmMachineState(availableGas); const avmContext = new AvmContext(avmPersistableState, avmExecutionEnv, avmMachineState); @@ -124,14 +103,6 @@ export class PublicExecutor { this.metrics.recordFunctionSimulation(bytecode.length, timer.ms()); } - const _vmCircuitPublicInputs = enqueuedCallTrace.toVMCircuitPublicInputs( - constants, - avmExecutionEnv, - /*startGasLeft=*/ availableGas, - /*endGasLeft=*/ Gas.from(avmContext.machineState.gasLeft), - avmResult, - ); - return publicExecutionResult; } } diff --git a/yarn-project/simulator/src/public/public_processor.test.ts b/yarn-project/simulator/src/public/public_processor.test.ts index e52f6fdbbab5..64e998c549ac 100644 --- a/yarn-project/simulator/src/public/public_processor.test.ts +++ b/yarn-project/simulator/src/public/public_processor.test.ts @@ -848,8 +848,6 @@ describe('public_processor', () => { expect.anything(), // pendingNullifiers new Fr(txFee), expect.anything(), // SideEffectCounter - expect.anything(), // PublicValidationRequestArrayLengths - expect.anything(), // PublicAccumulatedDataArrayLengths ]; expect(publicExecutor.simulate).toHaveBeenCalledTimes(3); diff --git a/yarn-project/txe/src/oracle/txe_oracle.ts b/yarn-project/txe/src/oracle/txe_oracle.ts index b552fa454d7c..69f7884c697f 100644 --- a/yarn-project/txe/src/oracle/txe_oracle.ts +++ b/yarn-project/txe/src/oracle/txe_oracle.ts @@ -12,8 +12,8 @@ import { import { type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats'; import { CallContext, - CombinedConstantData, Gas, + GlobalVariables, Header, type KeyValidationRequest, NULLIFIER_SUBTREE_HEIGHT, @@ -689,7 +689,7 @@ export class TXE implements TypedOracle { const executionResult = executor.simulate( execution, - CombinedConstantData.empty(), + GlobalVariables.empty(), Gas.test(), TxContext.empty(), /* pendingNullifiers */ [],