diff --git a/CODEOWNERS b/CODEOWNERS index 9d8055da4cd..48a9dbe1b12 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -12,8 +12,8 @@ /barretenberg/cpp/pil @Maddiaa0 @jeanmon @IlyasRidhuan @fcarreiro # on changes to PIL-generated C++ /barretenberg/cpp/src/barretenberg/**/generated @jeanmon @IlyasRidhuan @fcarreiro -# on changes to AVM trace (C++ witness generator) -/barretenberg/cpp/src/barretenberg/vm/avm_trace @jeanmon @IlyasRidhuan @fcarreiro +# on changes to AVM C++ code +/barretenberg/cpp/src/barretenberg/vm @jeanmon @IlyasRidhuan @fcarreiro # on changes to public context in aztec-nr /noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr @fcarreiro @dbanks12 /noir-projects/aztec-nr/aztec/src/context/public_context.nr @fcarreiro @dbanks12 @@ -24,7 +24,6 @@ /yarn-project/simulator/src/public/side_effect_trace.test.ts @fcarreiro @dbanks12 /yarn-project/simulator/src/public/side_effect_trace.ts @fcarreiro @dbanks12 /yarn-project/simulator/src/public/side_effect_trace_interface.ts @fcarreiro @dbanks12 -/yarn-project/simulator/src/public/transitional_adaptors.ts @fcarreiro @dbanks12 # on changes to the AVM transpiler /avm-transpiler/src @fcarreiro @dbanks12 ##################################################### diff --git a/yarn-project/bb-prover/src/avm_proving.test.ts b/yarn-project/bb-prover/src/avm_proving.test.ts index 53987df2e8c..6f465bf4d95 100644 --- a/yarn-project/bb-prover/src/avm_proving.test.ts +++ b/yarn-project/bb-prover/src/avm_proving.test.ts @@ -285,9 +285,9 @@ const proveAndVerifyAvmTestContract = async ( // TODO: pub somewhere more usable - copied from abstract phase manager const getPublicInputs = (result: PublicExecutionResult): PublicCircuitPublicInputs => { return PublicCircuitPublicInputs.from({ - callContext: result.execution.callContext, + callContext: result.executionRequest.callContext, proverAddress: AztecAddress.ZERO, - argsHash: computeVarArgsHash(result.execution.args), + argsHash: computeVarArgsHash(result.executionRequest.args), newNoteHashes: padArrayEnd(result.newNoteHashes, NoteHash.empty(), MAX_NEW_NOTE_HASHES_PER_CALL), newNullifiers: padArrayEnd(result.newNullifiers, Nullifier.empty(), MAX_NEW_NULLIFIERS_PER_CALL), newL2ToL1Msgs: padArrayEnd(result.newL2ToL1Messages, L2ToL1Message.empty(), MAX_NEW_L2_TO_L1_MSGS_PER_CALL), diff --git a/yarn-project/prover-client/src/mocks/test_context.ts b/yarn-project/prover-client/src/mocks/test_context.ts index 507068e36ae..1573ba7f68d 100644 --- a/yarn-project/prover-client/src/mocks/test_context.ts +++ b/yarn-project/prover-client/src/mocks/test_context.ts @@ -21,7 +21,7 @@ import { type DebugLogger } from '@aztec/foundation/log'; import { openTmpStore } from '@aztec/kv-store/utils'; import { type ContractsDataSourcePublicDB, - type PublicExecution, + type PublicExecutionRequest, type PublicExecutionResult, PublicExecutionResultBuilder, type PublicExecutor, @@ -164,7 +164,7 @@ export class TestContext { txValidator?: TxValidator, ) { const defaultExecutorImplementation = ( - execution: PublicExecution, + execution: PublicExecutionRequest, _globalVariables: GlobalVariables, availableGas: Gas, _txContext: TxContext, @@ -204,7 +204,7 @@ export class TestContext { blockProver?: BlockProver, txValidator?: TxValidator, executorMock?: ( - execution: PublicExecution, + execution: PublicExecutionRequest, globalVariables: GlobalVariables, availableGas: Gas, txContext: TxContext, diff --git a/yarn-project/simulator/src/avm/avm_message_call_result.ts b/yarn-project/simulator/src/avm/avm_contract_call_result.ts similarity index 92% rename from yarn-project/simulator/src/avm/avm_message_call_result.ts rename to yarn-project/simulator/src/avm/avm_contract_call_result.ts index 49e5355b3d2..7db56bc44de 100644 --- a/yarn-project/simulator/src/avm/avm_message_call_result.ts +++ b/yarn-project/simulator/src/avm/avm_contract_call_result.ts @@ -5,7 +5,7 @@ import { type AvmRevertReason } from './errors.js'; /** * Results of an contract call's execution in the AVM. */ -export class AvmContractCallResults { +export class AvmContractCallResult { constructor(public reverted: boolean, public output: Fr[], public revertReason?: AvmRevertReason) {} toString(): string { diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.ts b/yarn-project/simulator/src/avm/avm_execution_environment.ts index c4794b1a02b..2e73d8e384e 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.ts @@ -17,7 +17,6 @@ export class AvmContextInputs { * Contains variables that remain constant during AVM execution * These variables are provided by the public kernel circuit */ -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/3992): gas not implemented export class AvmExecutionEnvironment { private readonly calldataPrefixLength; constructor( @@ -35,15 +34,15 @@ export class AvmExecutionEnvironment { public readonly gasSettings: GasSettings, public readonly transactionFee: Fr, - // Function selector is temporary since eventually public contract bytecode will be one blob - // containing all functions, and function selector will become an application-level mechanism + // Function selector may be temporary since eventually public contract bytecode will likely be one + // blob containing all functions, and function selector will become an application-level mechanism // (e.g. first few bytes of calldata + compiler-generated jump table) - public readonly temporaryFunctionSelector: FunctionSelector, + public readonly functionSelector: FunctionSelector, ) { // We encode some extra inputs (AvmContextInputs) in calldata. // This will have to go once we move away from one proof per call. const inputs = new AvmContextInputs( - temporaryFunctionSelector.toField(), + functionSelector.toField(), computeVarArgsHash(calldata), isStaticCall, ).toFields(); diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index 7fb9ef31bb8..097a19cdfb4 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -9,11 +9,11 @@ import { type Fieldable } from '@aztec/foundation/serialize'; import { mock } from 'jest-mock-extended'; import { type PublicSideEffectTraceInterface } from '../public/side_effect_trace_interface.js'; -import { isAvmBytecode, markBytecodeAsAvm } from '../public/transitional_adaptors.js'; import { type AvmExecutionEnvironment } from './avm_execution_environment.js'; import { AvmMachineState } from './avm_machine_state.js'; import { type MemoryValue, TypeTag, type Uint8 } from './avm_memory_types.js'; import { AvmSimulator } from './avm_simulator.js'; +import { isAvmBytecode, markBytecodeAsAvm } from './bytecode_utils.js'; import { adjustCalldataIndex, getAvmTestContractBytecode, @@ -308,7 +308,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { it('selector', async () => { const context = initContext({ env: initExecutionEnvironment({ - temporaryFunctionSelector: FunctionSelector.fromSignature('check_selector()'), + functionSelector: FunctionSelector.fromSignature('check_selector()'), }), }); const bytecode = getAvmTestContractBytecode('check_selector'); @@ -345,8 +345,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { describe('Side effects, world state, nested calls', () => { const address = new Fr(1); - // TODO(dbanks12): should be able to make address and storage address different - const storageAddress = new Fr(1); + const storageAddress = new Fr(2); const sender = new Fr(42); const leafIndex = new Fr(7); const slotNumber = 1; // must update Noir contract if changing this @@ -411,7 +410,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { describe.each([[/*exists=*/ false], [/*exists=*/ true]])('Nullifier checks', (exists: boolean) => { const existsStr = exists ? 'DOES exist' : 'does NOT exist'; - it(`Should return ${exists} (and be traced) when noteHash ${existsStr}`, async () => { + it(`Should return ${exists} (and be traced) when nullifier ${existsStr}`, async () => { const calldata = [value0]; const context = createContext(calldata); const bytecode = getAvmTestContractBytecode('nullifier_exists'); @@ -430,7 +429,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const tracedLeafIndex = exists && !isPending ? leafIndex : Fr.ZERO; expect(trace.traceNullifierCheck).toHaveBeenCalledWith( storageAddress, - value0, + /*nullifier=*/ value0, tracedLeafIndex, exists, isPending, @@ -451,7 +450,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { ? `at leafIndex=${mockAtLeafIndex.toNumber()} (exists at leafIndex=${leafIndex.toNumber()})` : ''; - it(`Should return ${expectFound} (and be traced) when noteHash ${existsStr} ${foundAtStr}`, async () => { + it(`Should return ${expectFound} (and be traced) when message ${existsStr} ${foundAtStr}`, async () => { const calldata = [value0, leafIndex]; const context = createContext(calldata); const bytecode = getAvmTestContractBytecode('l1_to_l2_msg_exists'); @@ -466,7 +465,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(trace.traceL1ToL2MessageCheck).toHaveBeenCalledTimes(1); expect(trace.traceL1ToL2MessageCheck).toHaveBeenCalledWith( address, - /*noteHash=*/ value0, + /*msgHash=*/ value0, leafIndex, /*exists=*/ expectFound, ); @@ -485,7 +484,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(trace.traceNewNoteHash).toHaveBeenCalledTimes(1); expect(trace.traceNewNoteHash).toHaveBeenCalledWith( expect.objectContaining(storageAddress), - /*nullifier=*/ value0, + /*noteHash=*/ value0, ); }); @@ -525,7 +524,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { // leafIndex is returned from DB call for nullifiers, so it is absent on DB miss expect(trace.traceNullifierCheck).toHaveBeenCalledWith( storageAddress, - value0, + /*nullifier=*/ value0, /*leafIndex=*/ Fr.ZERO, /*exists=*/ true, /*isPending=*/ true, @@ -639,8 +638,8 @@ describe('AVM simulator: transpiled Noir contracts', () => { const results = await new AvmSimulator(context).executeBytecode(bytecode); expect(results.reverted).toBe(false); - expect(await context.persistableState.peekStorage(address, listSlot0)).toEqual(calldata[0]); - expect(await context.persistableState.peekStorage(address, listSlot1)).toEqual(calldata[1]); + expect(await context.persistableState.peekStorage(storageAddress, listSlot0)).toEqual(calldata[0]); + expect(await context.persistableState.peekStorage(storageAddress, listSlot1)).toEqual(calldata[1]); expect(trace.tracePublicStorageWrite).toHaveBeenCalledTimes(2); expect(trace.tracePublicStorageWrite).toHaveBeenCalledWith(storageAddress, listSlot0, value0); diff --git a/yarn-project/simulator/src/avm/avm_simulator.ts b/yarn-project/simulator/src/avm/avm_simulator.ts index 64d13a2ffbe..e62b2a57c74 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.ts @@ -2,9 +2,9 @@ import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { strict as assert } from 'assert'; -import { decompressBytecodeIfCompressed, isAvmBytecode } from '../public/transitional_adaptors.js'; import type { AvmContext } from './avm_context.js'; -import { AvmContractCallResults } from './avm_message_call_result.js'; +import { AvmContractCallResult } from './avm_contract_call_result.js'; +import { decompressBytecodeIfCompressed, isAvmBytecode } from './bytecode_utils.js'; import { AvmExecutionError, InvalidProgramCounterError, @@ -20,18 +20,16 @@ export class AvmSimulator { private bytecode: Buffer | undefined; constructor(private context: AvmContext) { - this.log = createDebugLogger( - `aztec:avm_simulator:core(f:${context.environment.temporaryFunctionSelector.toString()})`, - ); + this.log = createDebugLogger(`aztec:avm_simulator:core(f:${context.environment.functionSelector.toString()})`); } /** * Fetch the bytecode and execute it in the current context. */ - public async execute(): Promise { + public async execute(): Promise { const bytecode = await this.context.persistableState.getBytecode( this.context.environment.address, - this.context.environment.temporaryFunctionSelector, + this.context.environment.functionSelector, ); // This assumes that we will not be able to send messages to accounts without code @@ -54,7 +52,7 @@ export class AvmSimulator { * Executes the provided bytecode in the current context. * This method is useful for testing and debugging. */ - public async executeBytecode(bytecode: Buffer): Promise { + public async executeBytecode(bytecode: Buffer): Promise { const decompressedBytecode = await decompressBytecodeIfCompressed(bytecode); assert(isAvmBytecode(decompressedBytecode), "AVM simulator can't execute non-AVM bytecode"); @@ -66,7 +64,7 @@ export class AvmSimulator { * Executes the provided instructions in the current context. * This method is useful for testing and debugging. */ - public async executeInstructions(instructions: Instruction[]): Promise { + public async executeInstructions(instructions: Instruction[]): Promise { assert(instructions.length > 0); const { machineState } = this.context; try { @@ -95,7 +93,7 @@ export class AvmSimulator { const output = machineState.getOutput(); const reverted = machineState.getReverted(); const revertReason = reverted ? revertReasonFromExplicitRevert(output, this.context) : undefined; - const results = new AvmContractCallResults(reverted, output, revertReason); + const results = new AvmContractCallResult(reverted, output, revertReason); this.log.debug(`Context execution results: ${results.toString()}`); // Return results for processing by calling context return results; @@ -108,7 +106,7 @@ export class AvmSimulator { const revertReason = revertReasonFromExceptionalHalt(err, this.context); // Note: "exceptional halts" cannot return data, hence [] - const results = new AvmContractCallResults(/*reverted=*/ true, /*output=*/ [], revertReason); + const results = new AvmContractCallResult(/*reverted=*/ true, /*output=*/ [], revertReason); this.log.debug(`Context execution results: ${results.toString()}`); // Return results for processing by calling context return results; diff --git a/yarn-project/simulator/src/avm/bytecode_utils.ts b/yarn-project/simulator/src/avm/bytecode_utils.ts new file mode 100644 index 00000000000..52b0f31032e --- /dev/null +++ b/yarn-project/simulator/src/avm/bytecode_utils.ts @@ -0,0 +1,32 @@ +import { promisify } from 'util'; +import { gunzip } from 'zlib'; + +import { Mov } from '../avm/opcodes/memory.js'; + +const AVM_MAGIC_SUFFIX = Buffer.from([ + Mov.opcode, // opcode + 0x00, // indirect + ...Buffer.from('000018ca', 'hex'), // srcOffset + ...Buffer.from('000018ca', 'hex'), // dstOffset +]); + +export function markBytecodeAsAvm(bytecode: Buffer): Buffer { + return Buffer.concat([bytecode, AVM_MAGIC_SUFFIX]); +} + +// This is just a helper function for the AVM simulator +export async function decompressBytecodeIfCompressed(bytecode: Buffer): Promise { + try { + return await promisify(gunzip)(bytecode); + } catch { + // If the bytecode is not compressed, the gunzip call will throw an error + // In this case, we assume the bytecode is not compressed and continue. + return Promise.resolve(bytecode); + } +} + +export async function isAvmBytecode(bytecode: Buffer): Promise { + const decompressedBytecode = await decompressBytecodeIfCompressed(bytecode); + const magicSize = AVM_MAGIC_SUFFIX.length; + return decompressedBytecode.subarray(-magicSize).equals(AVM_MAGIC_SUFFIX); +} diff --git a/yarn-project/simulator/src/avm/errors.ts b/yarn-project/simulator/src/avm/errors.ts index 46f759fc736..06d35a2abc9 100644 --- a/yarn-project/simulator/src/avm/errors.ts +++ b/yarn-project/simulator/src/avm/errors.ts @@ -113,7 +113,7 @@ function createRevertReason(message: string, context: AvmContext, nestedError?: message, /*failingFunction=*/ { contractAddress: context.environment.address, - functionSelector: context.environment.temporaryFunctionSelector, + functionSelector: context.environment.functionSelector, }, /*noirCallStack=*/ [...context.machineState.internalCallStack, context.machineState.pc].map(pc => `0.${pc}`), /*options=*/ { cause: nestedError }, diff --git a/yarn-project/simulator/src/avm/fixtures/index.ts b/yarn-project/simulator/src/avm/fixtures/index.ts index d7926c28dfe..fdcb07c8d31 100644 --- a/yarn-project/simulator/src/avm/fixtures/index.ts +++ b/yarn-project/simulator/src/avm/fixtures/index.ts @@ -82,7 +82,7 @@ export function initExecutionEnvironment(overrides?: Partial { const tracedLeafIndex = exists && !isPending ? leafIndex : Fr.ZERO; expect(trace.traceNullifierCheck).toHaveBeenCalledWith( storageAddress, - value0, + /*nullifier=*/ value0, tracedLeafIndex, exists, isPending, @@ -292,7 +292,7 @@ describe('Accrued Substate', () => { expect(trace.traceL1ToL2MessageCheck).toHaveBeenCalledTimes(1); expect(trace.traceL1ToL2MessageCheck).toHaveBeenCalledWith( address, - /*noteHash=*/ value0, + /*msgHash=*/ value0, leafIndex, /*exists=*/ expectFound, ); diff --git a/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts b/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts index 19da62cc3a1..b6ce36a0cd8 100644 --- a/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts @@ -3,9 +3,9 @@ import { Fr } from '@aztec/foundation/fields'; import { mock } from 'jest-mock-extended'; import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js'; -import { markBytecodeAsAvm } from '../../public/transitional_adaptors.js'; import { type AvmContext } from '../avm_context.js'; import { Field, Uint8, Uint32 } from '../avm_memory_types.js'; +import { markBytecodeAsAvm } from '../bytecode_utils.js'; import { adjustCalldataIndex, initContext, initHostStorage, initPersistableStateManager } from '../fixtures/index.js'; import { type HostStorage } from '../journal/host_storage.js'; import { type AvmPersistableStateManager } from '../journal/journal.js'; diff --git a/yarn-project/simulator/src/avm/opcodes/external_calls.ts b/yarn-project/simulator/src/avm/opcodes/external_calls.ts index 3830d4db0e9..034f666cb7f 100644 --- a/yarn-project/simulator/src/avm/opcodes/external_calls.ts +++ b/yarn-project/simulator/src/avm/opcodes/external_calls.ts @@ -2,9 +2,9 @@ import { FunctionSelector, Gas } from '@aztec/circuits.js'; import { padArrayEnd } from '@aztec/foundation/collection'; import type { AvmContext } from '../avm_context.js'; +import { type AvmContractCallResult } from '../avm_contract_call_result.js'; import { gasLeftToGas } from '../avm_gas.js'; import { Field, TypeTag, Uint8 } from '../avm_memory_types.js'; -import { type AvmContractCallResults } from '../avm_message_call_result.js'; import { AvmSimulator } from '../avm_simulator.js'; import { RethrownError } from '../errors.js'; import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; @@ -88,7 +88,7 @@ abstract class ExternalCall extends Instruction { ); const simulator = new AvmSimulator(nestedContext); - const nestedCallResults: AvmContractCallResults = await simulator.execute(); + const nestedCallResults: AvmContractCallResult = await simulator.execute(); const success = !nestedCallResults.reverted; // TRANSITIONAL: We rethrow here so that the MESSAGE gets propagated. @@ -120,7 +120,6 @@ abstract class ExternalCall extends Instruction { // Accept the nested call's state and trace the nested call await context.persistableState.processNestedCall( /*nestedState=*/ nestedContext.persistableState, - /*success=*/ success, /*nestedEnvironment=*/ nestedContext.environment, /*startGasLeft=*/ Gas.from(allocatedGas), /*endGasLeft=*/ Gas.from(nestedContext.machineState.gasLeft), diff --git a/yarn-project/simulator/src/mocks/fixtures.ts b/yarn-project/simulator/src/mocks/fixtures.ts index 7bbd49b1f7a..0ce4c87bc71 100644 --- a/yarn-project/simulator/src/mocks/fixtures.ts +++ b/yarn-project/simulator/src/mocks/fixtures.ts @@ -14,10 +14,10 @@ import { makeAztecAddress, makeSelector } from '@aztec/circuits.js/testing'; import { FunctionType } from '@aztec/foundation/abi'; import { padArrayEnd } from '@aztec/foundation/collection'; -import { type PublicExecution, type PublicExecutionResult } from '../public/execution.js'; +import { type PublicExecutionRequest, type PublicExecutionResult } from '../public/execution.js'; export class PublicExecutionResultBuilder { - private _execution: PublicExecution; + private _executionRequest: PublicExecutionRequest; private _nestedExecutions: PublicExecutionResult[] = []; private _contractStorageUpdateRequests: ContractStorageUpdateRequest[] = []; private _contractStorageReads: ContractStorageRead[] = []; @@ -25,8 +25,8 @@ export class PublicExecutionResultBuilder { private _reverted = false; private _revertReason: SimulationError | undefined = undefined; - constructor(execution: PublicExecution) { - this._execution = execution; + constructor(executionRequest: PublicExecutionRequest) { + this._executionRequest = executionRequest; } static fromPublicCallRequest({ @@ -120,7 +120,7 @@ export class PublicExecutionResultBuilder { build(overrides: Partial = {}): PublicExecutionResult { return { - execution: this._execution, + executionRequest: this._executionRequest, nestedExecutions: this._nestedExecutions, noteHashReadRequests: [], nullifierReadRequests: [], diff --git a/yarn-project/simulator/src/public/abstract_phase_manager.ts b/yarn-project/simulator/src/public/abstract_phase_manager.ts index fecc49988d2..f9bb9d14926 100644 --- a/yarn-project/simulator/src/public/abstract_phase_manager.ts +++ b/yarn-project/simulator/src/public/abstract_phase_manager.ts @@ -57,7 +57,7 @@ import { computeVarArgsHash } from '@aztec/circuits.js/hash'; import { padArrayEnd } from '@aztec/foundation/collection'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { - type PublicExecution, + type PublicExecutionRequest, type PublicExecutionResult, type PublicExecutor, accumulateReturnValues, @@ -256,7 +256,7 @@ export abstract class AbstractPhaseManager { const enqueuedCallResults = []; for (const enqueuedCall of enqueuedCalls) { - const executionStack: (PublicExecution | PublicExecutionResult)[] = [enqueuedCall]; + const executionStack: (PublicExecutionRequest | PublicExecutionResult)[] = [enqueuedCall]; // Keep track of which result is for the top/enqueued call let enqueuedExecutionResult: PublicExecutionResult | undefined; @@ -283,10 +283,10 @@ export abstract class AbstractPhaseManager { // Sanity check for a current upstream assumption. // Consumers of the result seem to expect "reverted <=> revertReason !== undefined". - const functionSelector = result.execution.functionSelector.toString(); + const functionSelector = result.executionRequest.functionSelector.toString(); if (result.reverted && !result.revertReason) { throw new Error( - `Simulation of ${result.execution.contractAddress.toString()}:${functionSelector}(${ + `Simulation of ${result.executionRequest.contractAddress.toString()}:${functionSelector}(${ result.functionName }) reverted with no reason.`, ); @@ -294,7 +294,7 @@ export abstract class AbstractPhaseManager { if (result.reverted && !PhaseIsRevertible[this.phase]) { this.log.debug( - `Simulation error on ${result.execution.contractAddress.toString()}:${functionSelector}(${ + `Simulation error on ${result.executionRequest.contractAddress.toString()}:${functionSelector}(${ result.functionName }) with reason: ${result.revertReason}`, ); @@ -308,7 +308,7 @@ export abstract class AbstractPhaseManager { // Simulate the public kernel circuit. this.log.debug( - `Running public kernel circuit for ${result.execution.contractAddress.toString()}:${functionSelector}(${ + `Running public kernel circuit for ${result.executionRequest.contractAddress.toString()}:${functionSelector}(${ result.functionName })`, ); @@ -331,7 +331,7 @@ export abstract class AbstractPhaseManager { // but the kernel carries the reverted flag forward. But if the simulator reverts, so should the kernel. if (result.reverted && kernelPublicOutput.revertCode.isOK()) { throw new Error( - `Public kernel circuit did not revert on ${result.execution.contractAddress.toString()}:${functionSelector}(${ + `Public kernel circuit did not revert on ${result.executionRequest.contractAddress.toString()}:${functionSelector}(${ result.functionName }), but simulator did.`, ); @@ -341,7 +341,7 @@ export abstract class AbstractPhaseManager { // So safely return the revert reason and the kernel output (which has had its revertible side effects dropped) if (result.reverted) { this.log.debug( - `Reverting on ${result.execution.contractAddress.toString()}:${functionSelector}(${ + `Reverting on ${result.executionRequest.contractAddress.toString()}:${functionSelector}(${ result.functionName }) with reason: ${result.revertReason}`, ); @@ -430,9 +430,9 @@ export abstract class AbstractPhaseManager { ); const publicCircuitPublicInputs = PublicCircuitPublicInputs.from({ - callContext: result.execution.callContext, + callContext: result.executionRequest.callContext, proverAddress: AztecAddress.ZERO, - argsHash: computeVarArgsHash(result.execution.args), + argsHash: computeVarArgsHash(result.executionRequest.args), newNoteHashes: padArrayEnd(result.newNoteHashes, NoteHash.empty(), MAX_NEW_NOTE_HASHES_PER_CALL), newNullifiers: padArrayEnd(result.newNullifiers, Nullifier.empty(), MAX_NEW_NULLIFIERS_PER_CALL), newL2ToL1Msgs: padArrayEnd(result.newL2ToL1Messages, L2ToL1Message.empty(), MAX_NEW_L2_TO_L1_MSGS_PER_CALL), @@ -481,8 +481,8 @@ export abstract class AbstractPhaseManager { }); return new PublicCallStackItem( - result.execution.contractAddress, - new FunctionData(result.execution.functionSelector, false), + result.executionRequest.contractAddress, + new FunctionData(result.executionRequest.functionSelector, false), publicCircuitPublicInputs, isExecutionRequest, ); diff --git a/yarn-project/simulator/src/public/execution.ts b/yarn-project/simulator/src/public/execution.ts index e5ca2cecd53..75fe296a285 100644 --- a/yarn-project/simulator/src/public/execution.ts +++ b/yarn-project/simulator/src/public/execution.ts @@ -18,8 +18,8 @@ import { type Gas } from '../avm/avm_gas.js'; * The public function execution result. */ export interface PublicExecutionResult { - /** The execution that triggered this result. */ - execution: PublicExecution; + /** The execution request that triggered this result. */ + executionRequest: PublicExecutionRequest; /** The side effect counter at the start of the function call. */ startSideEffectCounter: Fr; @@ -90,9 +90,13 @@ export interface PublicExecutionResult { } /** - * The execution of a public function. + * The execution request of a public function. + * A subset of PublicCallRequest */ -export type PublicExecution = Pick; +export type PublicExecutionRequest = Pick< + PublicCallRequest, + 'contractAddress' | 'functionSelector' | 'callContext' | 'args' +>; /** * Returns if the input is a public execution result and not just a public execution. @@ -100,9 +104,9 @@ export type PublicExecution = Pick { transactionFee, }); const reverted = false; - const avmCallResults = new AvmContractCallResults(reverted, returnValues); + const avmCallResults = new AvmContractCallResult(reverted, returnValues); let startCounter: number; let startCounterFr: Fr; diff --git a/yarn-project/simulator/src/public/side_effect_trace.ts b/yarn-project/simulator/src/public/side_effect_trace.ts index 72d253dd5da..79181547ebb 100644 --- a/yarn-project/simulator/src/public/side_effect_trace.ts +++ b/yarn-project/simulator/src/public/side_effect_trace.ts @@ -21,16 +21,16 @@ 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 { type AvmContractCallResults } from '../avm/avm_message_call_result.js'; import { createSimulationError } from '../common/errors.js'; -import { type PublicExecution, type PublicExecutionResult } from './execution.js'; +import { type PublicExecutionRequest, type PublicExecutionResult } from './execution.js'; import { type PublicSideEffectTraceInterface } from './side_effect_trace_interface.js'; export type TracedContractInstance = { exists: boolean } & ContractInstanceWithAddress; export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { - public logger = createDebugLogger('aztec:side-effects'); + public logger = createDebugLogger('aztec:public_side_effect_trace'); /** The side effect counter increments with every call to the trace. */ private sideEffectCounter: number; // kept as number until finalized for efficiency @@ -224,7 +224,7 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { /** Bytecode used for this execution. */ bytecode: Buffer, /** The call's results */ - avmCallResults: AvmContractCallResults, + avmCallResults: AvmContractCallResult, /** Function name for logging */ functionName: string = 'unknown', ) { @@ -270,14 +270,14 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { /** Bytecode used for this execution. */ bytecode: Buffer, /** The call's results */ - avmCallResults: AvmContractCallResults, + avmCallResults: AvmContractCallResult, /** Function name for logging */ functionName: string = 'unknown', /** The side effect counter of the execution request itself */ requestSideEffectCounter: number = this.startSideEffectCounter, ): PublicExecutionResult { return { - execution: createPublicExecutionRequest(requestSideEffectCounter, avmEnvironment), + executionRequest: createPublicExecutionRequest(requestSideEffectCounter, avmEnvironment), startSideEffectCounter: new Fr(this.startSideEffectCounter), endSideEffectCounter: new Fr(this.sideEffectCounter), @@ -322,21 +322,20 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface { function createPublicExecutionRequest( requestSideEffectCounter: number, avmEnvironment: AvmExecutionEnvironment, -): PublicExecution { +): PublicExecutionRequest { const callContext = CallContext.from({ msgSender: avmEnvironment.sender, storageContractAddress: avmEnvironment.storageAddress, - functionSelector: avmEnvironment.temporaryFunctionSelector, + functionSelector: avmEnvironment.functionSelector, isDelegateCall: avmEnvironment.isDelegateCall, isStaticCall: avmEnvironment.isStaticCall, sideEffectCounter: requestSideEffectCounter, }); - const execution: PublicExecution = { + return { contractAddress: avmEnvironment.address, - functionSelector: avmEnvironment.temporaryFunctionSelector, + functionSelector: avmEnvironment.functionSelector, callContext, // execution request does not contain AvmContextInputs prefix args: avmEnvironment.getCalldataWithoutPrefix(), }; - return execution; } diff --git a/yarn-project/simulator/src/public/side_effect_trace_interface.ts b/yarn-project/simulator/src/public/side_effect_trace_interface.ts index a44eecbca49..91326fb021b 100644 --- a/yarn-project/simulator/src/public/side_effect_trace_interface.ts +++ b/yarn-project/simulator/src/public/side_effect_trace_interface.ts @@ -1,8 +1,8 @@ import { type Gas } from '@aztec/circuits.js'; import { type Fr } from '@aztec/foundation/fields'; +import { type AvmContractCallResult } from '../avm/avm_contract_call_result.js'; import { type AvmExecutionEnvironment } from '../avm/avm_execution_environment.js'; -import { type AvmContractCallResults } from '../avm/avm_message_call_result.js'; import { type TracedContractInstance } from './side_effect_trace.js'; export interface PublicSideEffectTraceInterface { @@ -34,7 +34,7 @@ export interface PublicSideEffectTraceInterface { /** Bytecode used for this execution. */ bytecode: Buffer, /** The call's results */ - avmCallResults: AvmContractCallResults, + avmCallResults: AvmContractCallResult, /** Function name */ functionName: string, ): void; diff --git a/yarn-project/simulator/src/public/transitional_adaptors.ts b/yarn-project/simulator/src/public/transitional_adaptors.ts deleted file mode 100644 index 9cea3c78075..00000000000 --- a/yarn-project/simulator/src/public/transitional_adaptors.ts +++ /dev/null @@ -1,70 +0,0 @@ -// All code in this file needs to die once the public executor is phased out in favor of the AVM. -import { type GasSettings, type GlobalVariables, type Header } from '@aztec/circuits.js'; -import { Fr } from '@aztec/foundation/fields'; - -import { promisify } from 'util'; -import { gunzip } from 'zlib'; - -import { AvmExecutionEnvironment } from '../avm/avm_execution_environment.js'; -import { Mov } from '../avm/opcodes/memory.js'; -import { type PublicExecution } from './execution.js'; - -/** - * Convert a PublicExecution(Environment) object to an AvmExecutionEnvironment - * - * @param current - * @param globalVariables - * @returns - */ -export function createAvmExecutionEnvironment( - current: PublicExecution, - header: Header, - globalVariables: GlobalVariables, - gasSettings: GasSettings, - transactionFee: Fr, -): AvmExecutionEnvironment { - return new AvmExecutionEnvironment( - current.contractAddress, - current.callContext.storageContractAddress, - current.callContext.msgSender, - globalVariables.gasFees.feePerL2Gas, - globalVariables.gasFees.feePerDaGas, - /*contractCallDepth=*/ Fr.zero(), - header, - globalVariables, - current.callContext.isStaticCall, - current.callContext.isDelegateCall, - current.args, - gasSettings, - transactionFee, - current.functionSelector, - ); -} - -const AVM_MAGIC_SUFFIX = Buffer.from([ - Mov.opcode, // opcode - 0x00, // indirect - ...Buffer.from('000018ca', 'hex'), // srcOffset - ...Buffer.from('000018ca', 'hex'), // dstOffset -]); - -export function markBytecodeAsAvm(bytecode: Buffer): Buffer { - return Buffer.concat([bytecode, AVM_MAGIC_SUFFIX]); -} - -// This is just a helper function for the AVM circuit. -export async function decompressBytecodeIfCompressed(bytecode: Buffer): Promise { - try { - return await promisify(gunzip)(bytecode); - } catch { - // If the bytecode is not compressed, the gunzip call will throw an error - // In this case, we assume the bytecode is not compressed and continue. - return Promise.resolve(bytecode); - } -} - -export async function isAvmBytecode(bytecode: Buffer): Promise { - const decompressedBytecode = await decompressBytecodeIfCompressed(bytecode); - const magicSize = AVM_MAGIC_SUFFIX.length; - return decompressedBytecode.subarray(-magicSize).equals(AVM_MAGIC_SUFFIX); -}