diff --git a/yarn-project/acir-simulator/src/avm/avm_context.ts b/yarn-project/acir-simulator/src/avm/avm_context.ts index 45491765805..a644d1319ff 100644 --- a/yarn-project/acir-simulator/src/avm/avm_context.ts +++ b/yarn-project/acir-simulator/src/avm/avm_context.ts @@ -4,7 +4,7 @@ import { Fr } from '@aztec/foundation/fields'; import { AvmExecutionEnvironment } from './avm_execution_environment.js'; import { AvmMachineState } from './avm_machine_state.js'; import { AvmMessageCallResult } from './avm_message_call_result.js'; -import { AvmInterpreter } from './interpreter/index.js'; +import { AvmInterpreter, AvmInterpreterError } from './interpreter/index.js'; import { AvmJournal } from './journal/journal.js'; import { decodeBytecode } from './opcodes/decode_bytecode.js'; import { Instruction } from './opcodes/index.js'; @@ -42,9 +42,10 @@ export class AvmContext { selector, ); - // TODO: handle this gracefully ! with account abstraction can we allow this? + // This assumes that we will not be able to send messages to accounts without code + // Pending classes and instances impl details if (!bytecode) { - throw new Error('No bytecode found'); + throw new NoBytecodeFoundInterpreterError(this.executionEnvironment.address); } const instructions: Instruction[] = decodeBytecode(bytecode); @@ -63,7 +64,6 @@ export class AvmContext { return new AvmContext(this.executionEnvironment, forkedState); } - // TODO: more documentation / thinking /** * Create a new forked avm context - for external calls */ @@ -72,6 +72,17 @@ export class AvmContext { return new AvmContext(executionEnvironment, forkedState); } + /** + * Prepare a new AVM context that will be ready for an external call + * - It will fork the journal + * - It will set the correct execution Environment Variables for a call + * - Alter both address and storageAddress + * + * @param address - The contract to call + * @param executionEnvironment - The current execution environment + * @param journal - The current journal + * @returns new AvmContext instance + */ public static prepExternalCall( address: AztecAddress, executionEnvironment: AvmExecutionEnvironment, @@ -82,6 +93,17 @@ export class AvmContext { return new AvmContext(newExecutionEnvironment, forkedState); } + /** + * Prepare a new AVM context that will be ready for an external static call + * - It will fork the journal + * - It will set the correct execution Environment Variables for a call + * - Alter both address and storageAddress + * + * @param address - The contract to call + * @param executionEnvironment - The current execution environment + * @param journal - The current journal + * @returns new AvmContext instance + */ public static prepExternalStaticCall( address: AztecAddress, executionEnvironment: AvmExecutionEnvironment, @@ -92,8 +114,18 @@ export class AvmContext { return new AvmContext(newExecutionEnvironment, forkedState); } - // TODO: document + /** + * Merge the journal of this call with it's parent + * NOTE: this should never be called on a root context - only from within a nested call + */ public mergeJournal() { this.journal.mergeWithParent(); } } + +class NoBytecodeFoundInterpreterError extends AvmInterpreterError { + constructor(contractAddress: AztecAddress) { + super(`No bytecode found at: ${contractAddress}`); + this.name = 'NoBytecodeFoundInterpreterError'; + } +} diff --git a/yarn-project/acir-simulator/src/avm/avm_execution_environment.test.ts b/yarn-project/acir-simulator/src/avm/avm_execution_environment.test.ts index 9eae3d22b25..1cc018cb0b6 100644 --- a/yarn-project/acir-simulator/src/avm/avm_execution_environment.test.ts +++ b/yarn-project/acir-simulator/src/avm/avm_execution_environment.test.ts @@ -33,13 +33,16 @@ describe('Execution Environment', () => { const executionEnvironment = initExecutionEnvironment(); const newExecutionEnvironment = executionEnvironment.newStaticCall(newAddress); - allTheSameExcept(executionEnvironment, newExecutionEnvironment, { address: newAddress, storageAddress: newAddress, isStaticCall: true }); + allTheSameExcept(executionEnvironment, newExecutionEnvironment, { + address: newAddress, + storageAddress: newAddress, + isStaticCall: true, + }); }); }); /** * Check all properties of one object are the same, except for the specified differentProperties - * TODO: maybe move this into some foundation test utilities file? */ function allTheSameExcept(referenceObject: any, comparingObject: any, differentProperties: Record): void { for (const key in referenceObject) { diff --git a/yarn-project/acir-simulator/src/avm/avm_execution_environment.ts b/yarn-project/acir-simulator/src/avm/avm_execution_environment.ts index 6f8373179f9..904f59737c0 100644 --- a/yarn-project/acir-simulator/src/avm/avm_execution_environment.ts +++ b/yarn-project/acir-simulator/src/avm/avm_execution_environment.ts @@ -7,6 +7,7 @@ import { Fr } from '@aztec/foundation/fields'; * 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 { constructor( /** - */ @@ -37,7 +38,6 @@ export class AvmExecutionEnvironment { public readonly calldata: Fr[], ) {} - // TODO: gas not implemented public newCall(address: AztecAddress): AvmExecutionEnvironment { return new AvmExecutionEnvironment( address, @@ -74,7 +74,6 @@ export class AvmExecutionEnvironment { ); } - // TODO: gas not implemented public newDelegateCall(address: AztecAddress): AvmExecutionEnvironment { return new AvmExecutionEnvironment( address, diff --git a/yarn-project/acir-simulator/src/avm/opcodes/external_calls.test.ts b/yarn-project/acir-simulator/src/avm/opcodes/external_calls.test.ts index 5656e4d0758..abaf09a217e 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/external_calls.test.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/external_calls.test.ts @@ -30,7 +30,7 @@ describe('External Calls', () => { }); describe('Call', () => { - // TODO: gas not implemented + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3992): gas not implemented it('Should execute a call correctly', async () => { const gasOffset = 0; const gas = Fr.zero(); @@ -51,7 +51,6 @@ describe('External Calls', () => { machineState.writeMemory(1, addr); machineState.writeMemoryChunk(2, args); - // TODO: mock the call that is made -> set the bytecode to be a return of two values const otherContextInstructions: [Opcode, any[]][] = [ // Place [1,2,3] into memory [Opcode.CALLDATACOPY, [/* value */ 0, /* copySize*/ argsSize, /* destOffset */ 0]], diff --git a/yarn-project/acir-simulator/src/avm/opcodes/external_calls.ts b/yarn-project/acir-simulator/src/avm/opcodes/external_calls.ts index 41b1a98b175..f90dbad3b3b 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/external_calls.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/external_calls.ts @@ -21,7 +21,7 @@ export class Call extends Instruction { super(); } - // TODO: there is no concept of remaining / available gas at this moment + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3992): there is no concept of remaining / available gas at this moment async execute(machineState: AvmMachineState, journal: AvmJournal): Promise { const callAddress = machineState.readMemory(this.addrOffset); const calldata = machineState.readMemoryChunk(this.argsOffset, this.argSize);