From ec44f7a146bc010a899fb180dfcd0467e8b576a3 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Tue, 6 Feb 2024 01:00:02 +0000 Subject: [PATCH 1/8] hacky: wire up avm simulator --- .../src/sequencer/abstract_phase_manager.ts | 11 ++ .../src/avm/avm_execution_environment.ts | 7 +- yarn-project/simulator/src/avm/executor.ts | 163 ++++++++++++++++++ 3 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 yarn-project/simulator/src/avm/executor.ts diff --git a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts index abedccab59f6..3ad1b3044588 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -157,6 +157,17 @@ export abstract class AbstractPhaseManager { while (executionStack.length) { const current = executionStack.pop()!; const isExecutionRequest = !isPublicExecutionResult(current); + + // TODO: get this from the environment + // NOTE: temporary glue to incorporate avm execution calls + const isAvm = true; + let result; + if (isAvm) { + temporaryAvmExecutionGlue(current, this.globalVariables); + } else{ + result = isExecutionRequest ? await this.publicExecutor.simulate(current, this.globalVariables) : current; + } + const result = isExecutionRequest ? await this.publicExecutor.simulate(current, this.globalVariables) : current; newUnencryptedFunctionLogs.push(result.unencryptedLogs); const functionSelector = result.execution.functionData.selector.toString(); diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.ts b/yarn-project/simulator/src/avm/avm_execution_environment.ts index aa3bbb4672c4..805369620a86 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.ts @@ -1,4 +1,4 @@ -import { GlobalVariables } from '@aztec/circuits.js'; +import { FunctionSelector, GlobalVariables } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; @@ -35,6 +35,8 @@ export class AvmExecutionEnvironment { public readonly isDelegateCall: boolean, public readonly calldata: Fr[], + + public readonly temporaryFunctionSelector: FunctionSelector ) {} public deriveEnvironmentForNestedCall(address: AztecAddress, calldata: Fr[]): AvmExecutionEnvironment { @@ -52,6 +54,7 @@ export class AvmExecutionEnvironment { this.isStaticCall, this.isDelegateCall, /*calldata=*/ calldata, + this.temporaryFunctionSelector ); } @@ -70,6 +73,7 @@ export class AvmExecutionEnvironment { /*isStaticCall=*/ true, this.isDelegateCall, /*calldata=*/ calldata, + this.temporaryFunctionSelector ); } @@ -88,6 +92,7 @@ export class AvmExecutionEnvironment { this.isStaticCall, /*isDelegateCall=*/ true, /*calldata=*/ calldata, + this.temporaryFunctionSelector ); } } diff --git a/yarn-project/simulator/src/avm/executor.ts b/yarn-project/simulator/src/avm/executor.ts new file mode 100644 index 000000000000..7cc17e3e620b --- /dev/null +++ b/yarn-project/simulator/src/avm/executor.ts @@ -0,0 +1,163 @@ + +import { GlobalVariables, Header, PublicCircuitPublicInputs } from '@aztec/circuits.js'; +import { createDebugLogger } from '@aztec/foundation/log'; +import {Fr} from "@aztec/foundation/fields"; + +import { Oracle, acvm, extractCallStack, extractReturnWitness } from '../acvm/index.js'; +import { ExecutionError, createSimulationError } from '../common/errors.js'; +import { SideEffectCounter } from '../common/index.js'; +import { PackedArgsCache } from '../common/packed_args_cache.js'; +import { CommitmentsDB, PublicContractsDB, PublicStateDB } from '../public/db.js'; +import { PublicExecution, PublicExecutionResult } from '../public/execution.js'; +import { PublicExecutionContext } from '../public/public_execution_context.js'; +import { AvmSimulator } from './avm_simulator.js'; +import { AvmExecutionEnvironment } from './avm_execution_environment.js'; + +/** + * Execute a public function and return the execution result. + */ +export async function executeAvmFunction( + context: PublicExecutionContext, + bytecode: Buffer, + log = createDebugLogger('aztec:simulator:public_execution'), +): Promise { + const execution = context.execution; + const { contractAddress, functionData } = execution; + const selector = functionData.selector; + log(`Executing public external function ${contractAddress.toString()}:${selector}`); + + const initialWitness = context.getInitialWitness(); + const acvmCallback = new Oracle(context); + const { partialWitness } = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, acvmCallback).catch( + (err: Error) => { + throw new ExecutionError( + err.message, + { + contractAddress, + functionSelector: selector, + }, + extractCallStack(err), + { cause: err }, + ); + }, + ); + + const returnWitness = extractReturnWitness(acir, partialWitness); + const { + returnValues, + newL2ToL1Msgs, + newCommitments: newCommitmentsPadded, + newNullifiers: newNullifiersPadded, + } = PublicCircuitPublicInputs.fromFields(returnWitness); + + const newL2ToL1Messages = newL2ToL1Msgs.filter(v => !v.isZero()); + const newCommitments = newCommitmentsPadded.filter(v => !v.isEmpty()); + const newNullifiers = newNullifiersPadded.filter(v => !v.isEmpty()); + + const { contractStorageReads, contractStorageUpdateRequests } = context.getStorageActionData(); + log( + `Contract storage reads: ${contractStorageReads + .map(r => r.toFriendlyJSON() + ` - sec: ${r.sideEffectCounter}`) + .join(', ')}`, + ); + + const nestedExecutions = context.getNestedExecutions(); + const unencryptedLogs = context.getUnencryptedLogs(); + + return { + execution, + newCommitments, + newL2ToL1Messages, + newNullifiers, + contractStorageReads, + contractStorageUpdateRequests, + returnValues, + nestedExecutions, + unencryptedLogs, + }; +} + +export function temporaryAvmExecutionGlue(current: PublicExecution, globalVariables: GlobalVariables) { + let executionEnv = temporaryMapToExecutionEnvironment(current, globalVariables); + + +} + +function temporaryMapToExecutionEnvironment(current: PublicExecution, globalVariables: GlobalVariables) : AvmExecutionEnvironment{ + // TODO: need to temporarily include functionSelector in here + return new AvmExecutionEnvironment( + current.contractAddress, + current.callContext.storageContractAddress, + current.callContext.msgSender, // TODO: origin is not available + current.callContext.msgSender, + current.callContext.portalContractAddress, + /*feePerL1Gas=*/Fr.zero(), + /*feePerL2Gas=*/Fr.zero(), + /*feePerDaGas=*/Fr.zero(), + /*contractCallDepth=*/Fr.zero(), + globalVariables, + current.callContext.isStaticCall, + current.callContext.isDelegateCall, + current.args, + current.functionData.selector + ) +} + + +/** + * Handles execution of public functions. + */ +export class PublicExecutor { + constructor( + private readonly stateDb: PublicStateDB, + private readonly contractsDb: PublicContractsDB, + private readonly commitmentsDb: CommitmentsDB, + private readonly header: Header, + ) {} + + /** + * Executes a public execution request. + * @param execution - The execution to run. + * @param globalVariables - The global variables to use. + * @returns The result of the run plus all nested runs. + */ + public async simulate(execution: PublicExecution, globalVariables: GlobalVariables): Promise { + // TODO currently using the existing public function infrastructure to get this over the line + + // TODO: create context from public execution -> then trigger the simulator ( function selector is required here ) + // - trigger execution of the thing + // - only execute things that DO NOT HAVE A SIDE EFFECTS AT THIS POINT IN TIME + // - this means that we can use the public kernel without much effort + + // const simulator = new AvmSimulator + + const selector = execution.functionData.selector; + const bytecode = await this.contractsDb.getBytecode(execution.contractAddress, selector); + if (!bytecode) { + throw new Error(`Bytecode not found for ${execution.contractAddress}:${selector}`); + } + + // Functions can request to pack arguments before calling other functions. + // We use this cache to hold the packed arguments. + const packedArgs = PackedArgsCache.create([]); + + const sideEffectCounter = new SideEffectCounter(); + + const context = new PublicExecutionContext( + execution, + this.header, + globalVariables, + packedArgs, + sideEffectCounter, + this.stateDb, + this.contractsDb, + this.commitmentsDb, + ); + + try { + return await executeAvmFunction(context, bytecode); + } catch (err) { + throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during public execution')); + } + } +} From fd4b879fa65e4b1ea60d9a648fc702974ca33e2f Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Tue, 6 Feb 2024 02:41:16 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=A4=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/logs/function_l2_logs.ts | 1 + .../src/sequencer/abstract_phase_manager.ts | 15 ++-- .../simulator/src/avm/avm_simulator.ts | 4 +- .../simulator/src/avm/fixtures/index.ts | 2 + .../{executor.ts => temporary_executor.ts} | 80 +---------------- yarn-project/simulator/src/public/executor.ts | 85 ++++++++++++++++++- 6 files changed, 99 insertions(+), 88 deletions(-) rename yarn-project/simulator/src/avm/{executor.ts => temporary_executor.ts} (53%) diff --git a/yarn-project/circuit-types/src/logs/function_l2_logs.ts b/yarn-project/circuit-types/src/logs/function_l2_logs.ts index ae7608b0e07a..1d9bc5f20337 100644 --- a/yarn-project/circuit-types/src/logs/function_l2_logs.ts +++ b/yarn-project/circuit-types/src/logs/function_l2_logs.ts @@ -7,6 +7,7 @@ import { randomBytes } from 'crypto'; import { LogType } from './log_type.js'; import { UnencryptedL2Log } from './unencrypted_l2_log.js'; +// ??????????????????????????????????? /** * Data container of logs emitted in 1 function invocation (corresponds to 1 kernel iteration). */ diff --git a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts index 3ad1b3044588..fd7932f236f9 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -51,6 +51,7 @@ import { getVerificationKeys } from '../mocks/verification_keys.js'; import { PublicProver } from '../prover/index.js'; import { PublicKernelCircuitSimulator } from '../simulator/index.js'; import { FailedTx } from './processed_tx.js'; +import { env } from 'process'; /** * A phase manager is responsible for performing/rolling back a phase of a transaction. @@ -160,15 +161,11 @@ export abstract class AbstractPhaseManager { // TODO: get this from the environment // NOTE: temporary glue to incorporate avm execution calls - const isAvm = true; - let result; - if (isAvm) { - temporaryAvmExecutionGlue(current, this.globalVariables); - } else{ - result = isExecutionRequest ? await this.publicExecutor.simulate(current, this.globalVariables) : current; - } - - const result = isExecutionRequest ? await this.publicExecutor.simulate(current, this.globalVariables) : current; + const isAvm = env.AVM_ENABLED; + const simulator = isAvm ? this.publicExecutor.simulateAvm : this.publicExecutor.simulate; + + const result = isExecutionRequest ? await simulator(current, this.globalVariables) : current; + newUnencryptedFunctionLogs.push(result.unencryptedLogs); const functionSelector = result.execution.functionData.selector.toString(); this.log( diff --git a/yarn-project/simulator/src/avm/avm_simulator.ts b/yarn-project/simulator/src/avm/avm_simulator.ts index a3c35012d003..48b801e78f61 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.ts @@ -1,4 +1,3 @@ -import { FunctionSelector } from '@aztec/circuits.js'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { strict as assert } from 'assert'; @@ -72,7 +71,8 @@ export class AvmSimulator { */ private async fetchAndDecodeBytecode(): Promise { // NOTE: the following is mocked as getPublicBytecode does not exist yet - const selector = new FunctionSelector(0); + + const selector = this.context.environment.temporaryFunctionSelector; const bytecode = await this.context.worldState.hostStorage.contractsDb.getBytecode( this.context.environment.address, selector, diff --git a/yarn-project/simulator/src/avm/fixtures/index.ts b/yarn-project/simulator/src/avm/fixtures/index.ts index bcaf1ff779f8..73e66a9e3ae8 100644 --- a/yarn-project/simulator/src/avm/fixtures/index.ts +++ b/yarn-project/simulator/src/avm/fixtures/index.ts @@ -1,6 +1,7 @@ import { GlobalVariables } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; +import { FunctionSelector } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; import { mock } from 'jest-mock-extended'; @@ -52,6 +53,7 @@ export function initExecutionEnvironment(overrides?: Partial { - const execution = context.execution; - const { contractAddress, functionData } = execution; - const selector = functionData.selector; - log(`Executing public external function ${contractAddress.toString()}:${selector}`); - - const initialWitness = context.getInitialWitness(); - const acvmCallback = new Oracle(context); - const { partialWitness } = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, acvmCallback).catch( - (err: Error) => { - throw new ExecutionError( - err.message, - { - contractAddress, - functionSelector: selector, - }, - extractCallStack(err), - { cause: err }, - ); - }, - ); - - const returnWitness = extractReturnWitness(acir, partialWitness); - const { - returnValues, - newL2ToL1Msgs, - newCommitments: newCommitmentsPadded, - newNullifiers: newNullifiersPadded, - } = PublicCircuitPublicInputs.fromFields(returnWitness); - - const newL2ToL1Messages = newL2ToL1Msgs.filter(v => !v.isZero()); - const newCommitments = newCommitmentsPadded.filter(v => !v.isEmpty()); - const newNullifiers = newNullifiersPadded.filter(v => !v.isEmpty()); - - const { contractStorageReads, contractStorageUpdateRequests } = context.getStorageActionData(); - log( - `Contract storage reads: ${contractStorageReads - .map(r => r.toFriendlyJSON() + ` - sec: ${r.sideEffectCounter}`) - .join(', ')}`, - ); - - const nestedExecutions = context.getNestedExecutions(); - const unencryptedLogs = context.getUnencryptedLogs(); - - return { - execution, - newCommitments, - newL2ToL1Messages, - newNullifiers, - contractStorageReads, - contractStorageUpdateRequests, - returnValues, - nestedExecutions, - unencryptedLogs, - }; -} - -export function temporaryAvmExecutionGlue(current: PublicExecution, globalVariables: GlobalVariables) { - let executionEnv = temporaryMapToExecutionEnvironment(current, globalVariables); - - -} - -function temporaryMapToExecutionEnvironment(current: PublicExecution, globalVariables: GlobalVariables) : AvmExecutionEnvironment{ +export function temporaryMapToExecutionEnvironment(current: PublicExecution, globalVariables: GlobalVariables) : AvmExecutionEnvironment{ // TODO: need to temporarily include functionSelector in here return new AvmExecutionEnvironment( current.contractAddress, @@ -104,6 +31,7 @@ function temporaryMapToExecutionEnvironment(current: PublicExecution, globalVari } + /** * Handles execution of public functions. */ diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index e5d3b935403b..e51e508b3724 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -1,4 +1,4 @@ -import { GlobalVariables, Header, PublicCircuitPublicInputs } from '@aztec/circuits.js'; +import { ContractStorageRead, ContractStorageUpdateRequest, GlobalVariables, Header, PublicCircuitPublicInputs, SideEffect, SideEffectLinkedToNoteHash } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { Oracle, acvm, extractCallStack, extractReturnWitness } from '../acvm/index.js'; @@ -9,6 +9,15 @@ import { AcirSimulator } from '../index.js'; import { CommitmentsDB, PublicContractsDB, PublicStateDB } from './db.js'; import { PublicExecution, PublicExecutionResult } from './execution.js'; import { PublicExecutionContext } from './public_execution_context.js'; +import { temporaryMapToExecutionEnvironment } from '../avm/temporary_executor.js'; +import { HostStorage } from '../avm/journal/host_storage.js'; +import { AvmWorldStateJournal, JournalData } from '../avm/journal/index.js'; +import { AvmMachineState } from '../avm/avm_machine_state.js'; +import { AvmContext } from '../avm/avm_context.js'; +import { AvmSimulator } from '../avm/avm_simulator.js'; +import { Fr } from '@aztec/bb.js'; +import { FunctionL2Logs } from '@aztec/circuit-types'; +import { AvmContractCallResults } from '../avm/avm_message_call_result.js'; /** * Execute a public function and return the execution result. @@ -121,4 +130,78 @@ export class PublicExecutor { throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during public execution')); } } + + /** + * Executes a public execution request in the avm. + * @param execution - The execution to run. + * @param globalVariables - The global variables to use. + * @returns The result of the run plus all nested runs. + */ + public async simulateAvm(execution: PublicExecution, globalVariables: GlobalVariables): Promise { + const hostStorage = new HostStorage(this.stateDb, this.contractsDb, this.commitmentsDb); + const worldStateJournal = new AvmWorldStateJournal(hostStorage); + const executionEnv = temporaryMapToExecutionEnvironment(execution, globalVariables); + const machineState = new AvmMachineState(0, 0, 0); + + const context = new AvmContext(worldStateJournal, executionEnv, machineState); + const simulator = new AvmSimulator(context); + + + // TODO: deal with the return result + const result = await simulator.execute(); + console.log('result', result); + + const newWorldState = context.worldState.flush(); + + return temporaryMapAvmReturnTypes(execution, newWorldState, result); + } } + + +function temporaryMapAvmReturnTypes(execution: PublicExecution, newWorldState: JournalData, result: AvmContractCallResults): PublicExecutionResult{ + const newCommitments = newWorldState.newNoteHashes.map(noteHash => new SideEffect(noteHash, Fr.zero())); + + // TODO: do the hashing to compress the new messages correctly + const newL2ToL1Messages = newWorldState.newL1Messages.map(() => Fr.zero()); + + // TODO: HAHAHAHAHAHAHAHAHAHAHAHAHAHA - THEY ARE SORTED HAHAH + const contractStorageReads: ContractStorageRead[] = []; + const reduceStorageReadRequests = (contractAddress: bigint, storageReads: Map) => { + return storageReads.forEach((innerArray, key) => { + innerArray.forEach(value => { + contractStorageReads.push(new ContractStorageRead(new Fr(key), new Fr(value), 0)); + }) + }) + }; + newWorldState.storageReads.forEach((storageMap: Map, address: bigint) => reduceStorageReadRequests(address, storageMap)); + + const contractStorageUpdateRequests: ContractStorageUpdateRequest[] = []; + const reduceStorageUpdateRequests = (contractAddress: bigint, storageUpdateRequests: Map) => { + return storageUpdateRequests.forEach((innerArray, key) => { + innerArray.forEach(value => { + contractStorageUpdateRequests.push(new ContractStorageUpdateRequest(new Fr(key),/*TODO: old value not supported */ Fr.zero(), new Fr(value), 0)); + }) + }) + } + newWorldState.storageWrites.forEach((storageMap: Map, address: bigint) => reduceStorageUpdateRequests(address, storageMap)); + + const returnValues = result.output; + + // TODO: NOT SUPPORTED YET + // Disabled. + const nestedExecutions: PublicExecutionResult[] = []; + const newNullifiers: SideEffectLinkedToNoteHash[] = []; + const unencryptedLogs = FunctionL2Logs.empty(); + + return { + execution, + newCommitments, + newL2ToL1Messages, + newNullifiers, + contractStorageReads, + contractStorageUpdateRequests, + returnValues, + nestedExecutions, + unencryptedLogs, + }; +} \ No newline at end of file From b395acfa44b46c2d06d56d39f4c7659d6f794542 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:20:33 +0000 Subject: [PATCH 3/8] feat: e2e --- .../end-to-end/src/e2e_avm_simulator.test.ts | 33 +++++++++ yarn-project/noir-compiler/src/cli/codegen.ts | 1 + .../src/sequencer/abstract_phase_manager.ts | 5 +- .../simulator/src/avm/temporary_executor.ts | 67 +------------------ yarn-project/simulator/src/public/executor.ts | 3 +- .../types/src/abi/contract_artifact.ts | 10 ++- 6 files changed, 50 insertions(+), 69 deletions(-) create mode 100644 yarn-project/end-to-end/src/e2e_avm_simulator.test.ts diff --git a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts new file mode 100644 index 000000000000..aae03c3d12c2 --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts @@ -0,0 +1,33 @@ +import { DebugLogger, Fr, Wallet } from '@aztec/aztec.js'; +import { AvmTestContract } from '@aztec/noir-contracts'; + +describe('e2e_nested_contract', () => { + let wallet: Wallet; + let logger: DebugLogger; + let teardown: () => Promise; + + beforeEach(async () => { + process.env.AVM_ENABLED = 'absofrigginlutely'; + ({ teardown, pxe, wallet, logger } = await setup()); + }, 100_000); + + afterEach(() => teardown()); + + describe('Call succeeds through AVM', () => { + let avmContact: AvmTestContract; + + beforeEach(async () => { + avmContact = await AvmTestContract.deploy(wallet).send().deployed(); + }, 50_000); + + it('Calls an avm contract', async () => { + const a = new Fr(1); + const b = new Fr(2); + // const expectedResult = a.add(b); + + // TODO: fix type gen for avm_addArgsReturn - incorrect number of args + logger('Calling avm_addArgsReturn...'); + await avmContact.methods.avm_addArgsReturn(a, b).send().wait(); + }); + }); +}); diff --git a/yarn-project/noir-compiler/src/cli/codegen.ts b/yarn-project/noir-compiler/src/cli/codegen.ts index 19c90f0a551b..54a9c6e1c859 100644 --- a/yarn-project/noir-compiler/src/cli/codegen.ts +++ b/yarn-project/noir-compiler/src/cli/codegen.ts @@ -31,6 +31,7 @@ export function generateCode(outputPath: string, fileOrDirPath: string, opts: Ge */ function generateFromNoirAbi(outputPath: string, noirAbiPath: string, opts: GenerateCodeOptions = {}) { const contract = JSON.parse(readFileSync(noirAbiPath, 'utf8')); + const aztecAbi = loadContractArtifact(contract); const { nr, ts } = opts; diff --git a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts index fd7932f236f9..20db563cbb19 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -161,8 +161,9 @@ export abstract class AbstractPhaseManager { // TODO: get this from the environment // NOTE: temporary glue to incorporate avm execution calls - const isAvm = env.AVM_ENABLED; - const simulator = isAvm ? this.publicExecutor.simulateAvm : this.publicExecutor.simulate; + const simulator = (env.AVM_ENABLED + ? (execution: PublicExecution, globalVariables: any) => this.publicExecutor.simulateAvm(execution, globalVariables) + : (execution: PublicExecution, globalVariables: any) => this.publicExecutor.simulate(execution, globalVariables)); const result = isExecutionRequest ? await simulator(current, this.globalVariables) : current; diff --git a/yarn-project/simulator/src/avm/temporary_executor.ts b/yarn-project/simulator/src/avm/temporary_executor.ts index 3e4c129ec111..7e8e17c8a67d 100644 --- a/yarn-project/simulator/src/avm/temporary_executor.ts +++ b/yarn-project/simulator/src/avm/temporary_executor.ts @@ -1,13 +1,8 @@ -import { GlobalVariables, Header } from '@aztec/circuits.js'; +import { GlobalVariables } from '@aztec/circuits.js'; import {Fr} from "@aztec/foundation/fields"; -import { createSimulationError } from '../common/errors.js'; -import { SideEffectCounter } from '../common/index.js'; -import { PackedArgsCache } from '../common/packed_args_cache.js'; -import { CommitmentsDB, PublicContractsDB, PublicStateDB } from '../public/db.js'; -import { PublicExecution, PublicExecutionResult } from '../public/execution.js'; -import { PublicExecutionContext } from '../public/public_execution_context.js'; +import { PublicExecution } from '../public/execution.js'; import { AvmExecutionEnvironment } from './avm_execution_environment.js'; export function temporaryMapToExecutionEnvironment(current: PublicExecution, globalVariables: GlobalVariables) : AvmExecutionEnvironment{ @@ -31,61 +26,3 @@ export function temporaryMapToExecutionEnvironment(current: PublicExecution, glo } - -/** - * Handles execution of public functions. - */ -export class PublicExecutor { - constructor( - private readonly stateDb: PublicStateDB, - private readonly contractsDb: PublicContractsDB, - private readonly commitmentsDb: CommitmentsDB, - private readonly header: Header, - ) {} - - /** - * Executes a public execution request. - * @param execution - The execution to run. - * @param globalVariables - The global variables to use. - * @returns The result of the run plus all nested runs. - */ - public async simulate(execution: PublicExecution, globalVariables: GlobalVariables): Promise { - // TODO currently using the existing public function infrastructure to get this over the line - - // TODO: create context from public execution -> then trigger the simulator ( function selector is required here ) - // - trigger execution of the thing - // - only execute things that DO NOT HAVE A SIDE EFFECTS AT THIS POINT IN TIME - // - this means that we can use the public kernel without much effort - - // const simulator = new AvmSimulator - - const selector = execution.functionData.selector; - const bytecode = await this.contractsDb.getBytecode(execution.contractAddress, selector); - if (!bytecode) { - throw new Error(`Bytecode not found for ${execution.contractAddress}:${selector}`); - } - - // Functions can request to pack arguments before calling other functions. - // We use this cache to hold the packed arguments. - const packedArgs = PackedArgsCache.create([]); - - const sideEffectCounter = new SideEffectCounter(); - - const context = new PublicExecutionContext( - execution, - this.header, - globalVariables, - packedArgs, - sideEffectCounter, - this.stateDb, - this.contractsDb, - this.commitmentsDb, - ); - - try { - return await executeAvmFunction(context, bytecode); - } catch (err) { - throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during public execution')); - } - } -} diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index e51e508b3724..6968c2a5c6a5 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -1,6 +1,7 @@ import { ContractStorageRead, ContractStorageUpdateRequest, GlobalVariables, Header, PublicCircuitPublicInputs, SideEffect, SideEffectLinkedToNoteHash } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; +import {Fr} from "@aztec/foundation/fields"; import { Oracle, acvm, extractCallStack, extractReturnWitness } from '../acvm/index.js'; import { ExecutionError, createSimulationError } from '../common/errors.js'; import { SideEffectCounter } from '../common/index.js'; @@ -15,7 +16,6 @@ import { AvmWorldStateJournal, JournalData } from '../avm/journal/index.js'; import { AvmMachineState } from '../avm/avm_machine_state.js'; import { AvmContext } from '../avm/avm_context.js'; import { AvmSimulator } from '../avm/avm_simulator.js'; -import { Fr } from '@aztec/bb.js'; import { FunctionL2Logs } from '@aztec/circuit-types'; import { AvmContractCallResults } from '../avm/avm_message_call_result.js'; @@ -138,6 +138,7 @@ export class PublicExecutor { * @returns The result of the run plus all nested runs. */ public async simulateAvm(execution: PublicExecution, globalVariables: GlobalVariables): Promise { + console.log(this.contractsDb); const hostStorage = new HostStorage(this.stateDb, this.contractsDb, this.commitmentsDb); const worldStateJournal = new AvmWorldStateJournal(hostStorage); const executionEnv = temporaryMapToExecutionEnvironment(execution, globalVariables); diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index 221fb7c80c47..a96fb5129930 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -103,7 +103,7 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArt // If the function is not unconstrained, the first item is inputs or CallContext which we should omit let parameters = fn.abi.parameters.map(generateFunctionParameter); - if (functionType !== 'unconstrained') { + if (hasKernelFunctionInputs(parameters)) { parameters = parameters.slice(1); } @@ -125,6 +125,14 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArt }; } +function hasKernelFunctionInputs(params: ABIParameter[]): boolean { + const firstParam = params[0]; + if (firstParam?.type.kind === 'struct') { + return firstParam.type.path.includes('ContextInputs'); + } + return false; +} + /** Validates contract artifact instance, throwing on error. */ function validateContractArtifact(contract: ContractArtifact) { const constructorArtifact = contract.functions.find(({ name }) => name === 'constructor'); From 909b4f826f697c2273839562da43ba066a681155 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:06:03 +0000 Subject: [PATCH 4/8] fix: minor cleanup --- .circleci/config.yml | 13 +++ .../src/logs/function_l2_logs.ts | 1 - .../end-to-end/scripts/docker-compose.yml | 1 + .../end-to-end/src/e2e_avm_simulator.test.ts | 10 +- .../src/sequencer/abstract_phase_manager.ts | 11 +- .../src/avm/avm_execution_environment.ts | 8 +- .../simulator/src/avm/fixtures/index.ts | 2 +- .../simulator/src/avm/journal/host_storage.ts | 2 +- .../simulator/src/avm/temporary_executor.ts | 28 ----- .../src/avm/temporary_executor_migration.ts | 110 ++++++++++++++++++ .../src/client/unconstrained_execution.ts | 2 +- yarn-project/simulator/src/public/executor.ts | 79 +++---------- .../types/src/abi/contract_artifact.ts | 8 +- 13 files changed, 160 insertions(+), 115 deletions(-) delete mode 100644 yarn-project/simulator/src/avm/temporary_executor.ts create mode 100644 yarn-project/simulator/src/avm/temporary_executor_migration.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index b036b70684a8..b7f5bffcb173 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -830,6 +830,17 @@ jobs: name: "Test" command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=e2e_card_game.test.ts + e2e-avm-simulator: + docker: + - image: aztecprotocol/alpine-build-image + resource_class: small + steps: + - *checkout + - *setup_env + - run: + name: "Test" + command: AVM_ENABLED=1 cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=e2e_avm_simulator.test.ts + pxe: docker: - image: aztecprotocol/alpine-build-image @@ -1275,6 +1286,7 @@ workflows: - e2e-persistence: *e2e_test - e2e-browser: *e2e_test - e2e-card-game: *e2e_test + - e2e-avm-simulator: *e2e_test - pxe: *e2e_test - cli-docs-sandbox: *e2e_test - guides-writing-an-account-contract: *e2e_test @@ -1313,6 +1325,7 @@ workflows: - e2e-persistence - e2e-browser - e2e-card-game + - e2e-avm-simulator - pxe - boxes-blank - boxes-blank-react diff --git a/yarn-project/circuit-types/src/logs/function_l2_logs.ts b/yarn-project/circuit-types/src/logs/function_l2_logs.ts index 1d9bc5f20337..ae7608b0e07a 100644 --- a/yarn-project/circuit-types/src/logs/function_l2_logs.ts +++ b/yarn-project/circuit-types/src/logs/function_l2_logs.ts @@ -7,7 +7,6 @@ import { randomBytes } from 'crypto'; import { LogType } from './log_type.js'; import { UnencryptedL2Log } from './unencrypted_l2_log.js'; -// ??????????????????????????????????? /** * Data container of logs emitted in 1 function invocation (corresponds to 1 kernel iteration). */ diff --git a/yarn-project/end-to-end/scripts/docker-compose.yml b/yarn-project/end-to-end/scripts/docker-compose.yml index 6a05e652777f..58feb709bc2d 100644 --- a/yarn-project/end-to-end/scripts/docker-compose.yml +++ b/yarn-project/end-to-end/scripts/docker-compose.yml @@ -25,6 +25,7 @@ services: WS_BLOCK_CHECK_INTERVAL_MS: 50 PXE_BLOCK_POLLING_INTERVAL_MS: 50 ARCHIVER_VIEM_POLLING_INTERVAL_MS: 500 + AVM_ENABLED: ${AVM_ENABLED:-} ports: - '8080:8080' diff --git a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts index aae03c3d12c2..299994d2ae70 100644 --- a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts +++ b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts @@ -1,14 +1,17 @@ import { DebugLogger, Fr, Wallet } from '@aztec/aztec.js'; import { AvmTestContract } from '@aztec/noir-contracts'; +import { setup } from './fixtures/utils.js'; + +process.env.AVM_ENABLED = 'absofrigginlutely'; + describe('e2e_nested_contract', () => { let wallet: Wallet; let logger: DebugLogger; let teardown: () => Promise; beforeEach(async () => { - process.env.AVM_ENABLED = 'absofrigginlutely'; - ({ teardown, pxe, wallet, logger } = await setup()); + ({ teardown, wallet, logger } = await setup()); }, 100_000); afterEach(() => teardown()); @@ -23,11 +26,10 @@ describe('e2e_nested_contract', () => { it('Calls an avm contract', async () => { const a = new Fr(1); const b = new Fr(2); - // const expectedResult = a.add(b); - // TODO: fix type gen for avm_addArgsReturn - incorrect number of args logger('Calling avm_addArgsReturn...'); await avmContact.methods.avm_addArgsReturn(a, b).send().wait(); + logger('Success'); }); }); }); diff --git a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts index 20db563cbb19..548337abd5a0 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -47,11 +47,12 @@ import { } from '@aztec/simulator'; import { MerkleTreeOperations } from '@aztec/world-state'; +import { env } from 'process'; + import { getVerificationKeys } from '../mocks/verification_keys.js'; import { PublicProver } from '../prover/index.js'; import { PublicKernelCircuitSimulator } from '../simulator/index.js'; import { FailedTx } from './processed_tx.js'; -import { env } from 'process'; /** * A phase manager is responsible for performing/rolling back a phase of a transaction. @@ -159,11 +160,11 @@ export abstract class AbstractPhaseManager { const current = executionStack.pop()!; const isExecutionRequest = !isPublicExecutionResult(current); - // TODO: get this from the environment // NOTE: temporary glue to incorporate avm execution calls - const simulator = (env.AVM_ENABLED - ? (execution: PublicExecution, globalVariables: any) => this.publicExecutor.simulateAvm(execution, globalVariables) - : (execution: PublicExecution, globalVariables: any) => this.publicExecutor.simulate(execution, globalVariables)); + const simulator = (execution: PublicExecution, globalVariables: GlobalVariables) => + env.AVM_ENABLED + ? this.publicExecutor.simulateAvm(execution, globalVariables) + : this.publicExecutor.simulate(execution, globalVariables); const result = isExecutionRequest ? await simulator(current, this.globalVariables) : current; diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.ts b/yarn-project/simulator/src/avm/avm_execution_environment.ts index 805369620a86..1317cc71fdd8 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.ts @@ -36,7 +36,7 @@ export class AvmExecutionEnvironment { public readonly calldata: Fr[], - public readonly temporaryFunctionSelector: FunctionSelector + public readonly temporaryFunctionSelector: FunctionSelector, ) {} public deriveEnvironmentForNestedCall(address: AztecAddress, calldata: Fr[]): AvmExecutionEnvironment { @@ -54,7 +54,7 @@ export class AvmExecutionEnvironment { this.isStaticCall, this.isDelegateCall, /*calldata=*/ calldata, - this.temporaryFunctionSelector + this.temporaryFunctionSelector, ); } @@ -73,7 +73,7 @@ export class AvmExecutionEnvironment { /*isStaticCall=*/ true, this.isDelegateCall, /*calldata=*/ calldata, - this.temporaryFunctionSelector + this.temporaryFunctionSelector, ); } @@ -92,7 +92,7 @@ export class AvmExecutionEnvironment { this.isStaticCall, /*isDelegateCall=*/ true, /*calldata=*/ calldata, - this.temporaryFunctionSelector + this.temporaryFunctionSelector, ); } } diff --git a/yarn-project/simulator/src/avm/fixtures/index.ts b/yarn-project/simulator/src/avm/fixtures/index.ts index 73e66a9e3ae8..15dc2206acf0 100644 --- a/yarn-project/simulator/src/avm/fixtures/index.ts +++ b/yarn-project/simulator/src/avm/fixtures/index.ts @@ -1,7 +1,7 @@ import { GlobalVariables } from '@aztec/circuits.js'; +import { FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; -import { FunctionSelector } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; import { mock } from 'jest-mock-extended'; diff --git a/yarn-project/simulator/src/avm/journal/host_storage.ts b/yarn-project/simulator/src/avm/journal/host_storage.ts index b12e14f9c20f..330f8bf0189a 100644 --- a/yarn-project/simulator/src/avm/journal/host_storage.ts +++ b/yarn-project/simulator/src/avm/journal/host_storage.ts @@ -1,4 +1,4 @@ -import { CommitmentsDB, PublicContractsDB, PublicStateDB } from '../../index.js'; +import { CommitmentsDB, PublicContractsDB, PublicStateDB } from '../../public/db.js'; /** * Host storage diff --git a/yarn-project/simulator/src/avm/temporary_executor.ts b/yarn-project/simulator/src/avm/temporary_executor.ts deleted file mode 100644 index 7e8e17c8a67d..000000000000 --- a/yarn-project/simulator/src/avm/temporary_executor.ts +++ /dev/null @@ -1,28 +0,0 @@ - -import { GlobalVariables } from '@aztec/circuits.js'; -import {Fr} from "@aztec/foundation/fields"; - -import { PublicExecution } from '../public/execution.js'; -import { AvmExecutionEnvironment } from './avm_execution_environment.js'; - -export function temporaryMapToExecutionEnvironment(current: PublicExecution, globalVariables: GlobalVariables) : AvmExecutionEnvironment{ - // TODO: need to temporarily include functionSelector in here - return new AvmExecutionEnvironment( - current.contractAddress, - current.callContext.storageContractAddress, - current.callContext.msgSender, // TODO: origin is not available - current.callContext.msgSender, - current.callContext.portalContractAddress, - /*feePerL1Gas=*/Fr.zero(), - /*feePerL2Gas=*/Fr.zero(), - /*feePerDaGas=*/Fr.zero(), - /*contractCallDepth=*/Fr.zero(), - globalVariables, - current.callContext.isStaticCall, - current.callContext.isDelegateCall, - current.args, - current.functionData.selector - ) -} - - diff --git a/yarn-project/simulator/src/avm/temporary_executor_migration.ts b/yarn-project/simulator/src/avm/temporary_executor_migration.ts new file mode 100644 index 000000000000..60cc50fc33e1 --- /dev/null +++ b/yarn-project/simulator/src/avm/temporary_executor_migration.ts @@ -0,0 +1,110 @@ +// All code in this file needs to die once the public executor is phased out. +import { FunctionL2Logs } from '@aztec/circuit-types'; +import { + ContractStorageRead, + ContractStorageUpdateRequest, + GlobalVariables, + SideEffect, + SideEffectLinkedToNoteHash, +} from '@aztec/circuits.js'; +import { Fr } from '@aztec/foundation/fields'; + +import { PublicExecution, PublicExecutionResult } from '../public/execution.js'; +import { AvmExecutionEnvironment } from './avm_execution_environment.js'; +import { AvmContractCallResults } from './avm_message_call_result.js'; +import { JournalData } from './journal/journal.js'; + +/** Temporary Method + * + * Convert a PublicExecution(Environment) object to an AvmExecutionEnvironment + * + * @param current + * @param globalVariables + * @returns + */ +export function temporaryMapToExecutionEnvironment( + current: PublicExecution, + globalVariables: GlobalVariables, +): AvmExecutionEnvironment { + // Function selector is included temporarily until noir codegens public contract bytecode in a single blob + return new AvmExecutionEnvironment( + current.contractAddress, + current.callContext.storageContractAddress, + current.callContext.msgSender, // TODO: origin is not available + current.callContext.msgSender, + current.callContext.portalContractAddress, + /*feePerL1Gas=*/ Fr.zero(), + /*feePerL2Gas=*/ Fr.zero(), + /*feePerDaGas=*/ Fr.zero(), + /*contractCallDepth=*/ Fr.zero(), + globalVariables, + current.callContext.isStaticCall, + current.callContext.isDelegateCall, + current.args, + current.functionData.selector, + ); +} + +/** Temporary Method + * + * Convert the result of an AVM contract call to a PublicExecutionResult for the public kernel + * + * @param execution + * @param newWorldState + * @param result + * @returns + */ +export function temporaryMapAvmReturnTypes( + execution: PublicExecution, + newWorldState: JournalData, + result: AvmContractCallResults, +): PublicExecutionResult { + const newCommitments = newWorldState.newNoteHashes.map(noteHash => new SideEffect(noteHash, Fr.zero())); + + const contractStorageReads: ContractStorageRead[] = []; + const reduceStorageReadRequests = (contractAddress: bigint, storageReads: Map) => { + return storageReads.forEach((innerArray, key) => { + innerArray.forEach(value => { + contractStorageReads.push(new ContractStorageRead(new Fr(key), new Fr(value), 0)); + }); + }); + }; + newWorldState.storageReads.forEach((storageMap: Map, address: bigint) => + reduceStorageReadRequests(address, storageMap), + ); + + const contractStorageUpdateRequests: ContractStorageUpdateRequest[] = []; + const reduceStorageUpdateRequests = (contractAddress: bigint, storageUpdateRequests: Map) => { + return storageUpdateRequests.forEach((innerArray, key) => { + innerArray.forEach(value => { + contractStorageUpdateRequests.push( + new ContractStorageUpdateRequest(new Fr(key), /*TODO: old value not supported */ Fr.zero(), new Fr(value), 0), + ); + }); + }); + }; + newWorldState.storageWrites.forEach((storageMap: Map, address: bigint) => + reduceStorageUpdateRequests(address, storageMap), + ); + + const returnValues = result.output; + + // TODO(follow up in pr tree): NOT SUPPORTED YET, make sure hashing and log resolution is done correctly + // Disabled. + const nestedExecutions: PublicExecutionResult[] = []; + const newNullifiers: SideEffectLinkedToNoteHash[] = []; + const unencryptedLogs = FunctionL2Logs.empty(); + const newL2ToL1Messages = newWorldState.newL1Messages.map(() => Fr.zero()); + + return { + execution, + newCommitments, + newL2ToL1Messages, + newNullifiers, + contractStorageReads, + contractStorageUpdateRequests, + returnValues, + nestedExecutions, + unencryptedLogs, + }; +} diff --git a/yarn-project/simulator/src/client/unconstrained_execution.ts b/yarn-project/simulator/src/client/unconstrained_execution.ts index 62f934d41ebb..0ecfb7e55382 100644 --- a/yarn-project/simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/simulator/src/client/unconstrained_execution.ts @@ -7,7 +7,7 @@ import { createDebugLogger } from '@aztec/foundation/log'; import { extractReturnWitness } from '../acvm/deserialize.js'; import { Oracle, acvm, extractCallStack, toACVMWitness } from '../acvm/index.js'; import { ExecutionError } from '../common/errors.js'; -import { AcirSimulator } from '../index.js'; +import { AcirSimulator } from './simulator.js'; import { ViewDataOracle } from './view_data_oracle.js'; // docs:start:execute_unconstrained_function diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index 6968c2a5c6a5..cba1f69830b8 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -1,8 +1,13 @@ -import { ContractStorageRead, ContractStorageUpdateRequest, GlobalVariables, Header, PublicCircuitPublicInputs, SideEffect, SideEffectLinkedToNoteHash } from '@aztec/circuits.js'; +import { GlobalVariables, Header, PublicCircuitPublicInputs } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; -import {Fr} from "@aztec/foundation/fields"; import { Oracle, acvm, extractCallStack, extractReturnWitness } from '../acvm/index.js'; +import { AvmContext } from '../avm/avm_context.js'; +import { AvmMachineState } from '../avm/avm_machine_state.js'; +import { AvmSimulator } from '../avm/avm_simulator.js'; +import { HostStorage } from '../avm/journal/host_storage.js'; +import { AvmWorldStateJournal } from '../avm/journal/index.js'; +import { temporaryMapAvmReturnTypes, temporaryMapToExecutionEnvironment } from '../avm/temporary_executor_migration.js'; import { ExecutionError, createSimulationError } from '../common/errors.js'; import { SideEffectCounter } from '../common/index.js'; import { PackedArgsCache } from '../common/packed_args_cache.js'; @@ -10,14 +15,6 @@ import { AcirSimulator } from '../index.js'; import { CommitmentsDB, PublicContractsDB, PublicStateDB } from './db.js'; import { PublicExecution, PublicExecutionResult } from './execution.js'; import { PublicExecutionContext } from './public_execution_context.js'; -import { temporaryMapToExecutionEnvironment } from '../avm/temporary_executor.js'; -import { HostStorage } from '../avm/journal/host_storage.js'; -import { AvmWorldStateJournal, JournalData } from '../avm/journal/index.js'; -import { AvmMachineState } from '../avm/avm_machine_state.js'; -import { AvmContext } from '../avm/avm_context.js'; -import { AvmSimulator } from '../avm/avm_simulator.js'; -import { FunctionL2Logs } from '@aztec/circuit-types'; -import { AvmContractCallResults } from '../avm/avm_message_call_result.js'; /** * Execute a public function and return the execution result. @@ -137,8 +134,12 @@ export class PublicExecutor { * @param globalVariables - The global variables to use. * @returns The result of the run plus all nested runs. */ - public async simulateAvm(execution: PublicExecution, globalVariables: GlobalVariables): Promise { - console.log(this.contractsDb); + public async simulateAvm( + execution: PublicExecution, + globalVariables: GlobalVariables, + ): Promise { + // Temporary code to construct the AVM context + // These data structures will permiate across the simulator when the public executor is phased out const hostStorage = new HostStorage(this.stateDb, this.contractsDb, this.commitmentsDb); const worldStateJournal = new AvmWorldStateJournal(hostStorage); const executionEnv = temporaryMapToExecutionEnvironment(execution, globalVariables); @@ -147,62 +148,8 @@ export class PublicExecutor { const context = new AvmContext(worldStateJournal, executionEnv, machineState); const simulator = new AvmSimulator(context); - - // TODO: deal with the return result const result = await simulator.execute(); - console.log('result', result); - const newWorldState = context.worldState.flush(); - return temporaryMapAvmReturnTypes(execution, newWorldState, result); } } - - -function temporaryMapAvmReturnTypes(execution: PublicExecution, newWorldState: JournalData, result: AvmContractCallResults): PublicExecutionResult{ - const newCommitments = newWorldState.newNoteHashes.map(noteHash => new SideEffect(noteHash, Fr.zero())); - - // TODO: do the hashing to compress the new messages correctly - const newL2ToL1Messages = newWorldState.newL1Messages.map(() => Fr.zero()); - - // TODO: HAHAHAHAHAHAHAHAHAHAHAHAHAHA - THEY ARE SORTED HAHAH - const contractStorageReads: ContractStorageRead[] = []; - const reduceStorageReadRequests = (contractAddress: bigint, storageReads: Map) => { - return storageReads.forEach((innerArray, key) => { - innerArray.forEach(value => { - contractStorageReads.push(new ContractStorageRead(new Fr(key), new Fr(value), 0)); - }) - }) - }; - newWorldState.storageReads.forEach((storageMap: Map, address: bigint) => reduceStorageReadRequests(address, storageMap)); - - const contractStorageUpdateRequests: ContractStorageUpdateRequest[] = []; - const reduceStorageUpdateRequests = (contractAddress: bigint, storageUpdateRequests: Map) => { - return storageUpdateRequests.forEach((innerArray, key) => { - innerArray.forEach(value => { - contractStorageUpdateRequests.push(new ContractStorageUpdateRequest(new Fr(key),/*TODO: old value not supported */ Fr.zero(), new Fr(value), 0)); - }) - }) - } - newWorldState.storageWrites.forEach((storageMap: Map, address: bigint) => reduceStorageUpdateRequests(address, storageMap)); - - const returnValues = result.output; - - // TODO: NOT SUPPORTED YET - // Disabled. - const nestedExecutions: PublicExecutionResult[] = []; - const newNullifiers: SideEffectLinkedToNoteHash[] = []; - const unencryptedLogs = FunctionL2Logs.empty(); - - return { - execution, - newCommitments, - newL2ToL1Messages, - newNullifiers, - contractStorageReads, - contractStorageUpdateRequests, - returnValues, - nestedExecutions, - unencryptedLogs, - }; -} \ No newline at end of file diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index a96fb5129930..f63e4dcd96a3 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -125,12 +125,12 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArt }; } +/** + * Returns true if the first parameter is kernel function inputs. + */ function hasKernelFunctionInputs(params: ABIParameter[]): boolean { const firstParam = params[0]; - if (firstParam?.type.kind === 'struct') { - return firstParam.type.path.includes('ContextInputs'); - } - return false; + return firstParam?.type.kind === 'struct' && firstParam.type.path.includes('ContextInputs'); } /** Validates contract artifact instance, throwing on error. */ From 8ec7f21dd93f9674f6e6849a962ba70aeb71f135 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Thu, 8 Feb 2024 23:38:34 +0000 Subject: [PATCH 5/8] fix --- build-system/scripts/remote_run_script | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build-system/scripts/remote_run_script b/build-system/scripts/remote_run_script index 8e1d8adf38c2..44d976a502b2 100755 --- a/build-system/scripts/remote_run_script +++ b/build-system/scripts/remote_run_script @@ -31,5 +31,8 @@ ssh -A -F $SSH_CONFIG_PATH $IP " export ECR_DEPLOY_URL=$ECR_DEPLOY_URL export ECR_URL=$ECR_URL export BUILD_SYSTEM_DEBUG=${BUILD_SYSTEM_DEBUG:-} + + # temp while we transitioning to avm + AVM_ENABLED=${AVM_ENABLED:-} ./remote_runner $@ " From 1297a983b4d5b0c65f241b64d42e98d08319e465 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Thu, 8 Feb 2024 23:54:43 +0000 Subject: [PATCH 6/8] fix --- build-system/scripts/remote_run_script | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-system/scripts/remote_run_script b/build-system/scripts/remote_run_script index 44d976a502b2..059417cced00 100755 --- a/build-system/scripts/remote_run_script +++ b/build-system/scripts/remote_run_script @@ -33,6 +33,6 @@ ssh -A -F $SSH_CONFIG_PATH $IP " export BUILD_SYSTEM_DEBUG=${BUILD_SYSTEM_DEBUG:-} # temp while we transitioning to avm - AVM_ENABLED=${AVM_ENABLED:-} + export AVM_ENABLED=${AVM_ENABLED:-} ./remote_runner $@ " From cae3239a26fbdd8edd209138061b2f14aec0c179 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:58:11 +0000 Subject: [PATCH 7/8] review --- yarn-project/noir-compiler/src/cli/codegen.ts | 1 - .../simulator/src/avm/temporary_executor_migration.ts | 4 ++-- yarn-project/simulator/src/public/executor.ts | 9 ++++++--- yarn-project/types/src/abi/contract_artifact.ts | 5 +++++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/yarn-project/noir-compiler/src/cli/codegen.ts b/yarn-project/noir-compiler/src/cli/codegen.ts index 54a9c6e1c859..19c90f0a551b 100644 --- a/yarn-project/noir-compiler/src/cli/codegen.ts +++ b/yarn-project/noir-compiler/src/cli/codegen.ts @@ -31,7 +31,6 @@ export function generateCode(outputPath: string, fileOrDirPath: string, opts: Ge */ function generateFromNoirAbi(outputPath: string, noirAbiPath: string, opts: GenerateCodeOptions = {}) { const contract = JSON.parse(readFileSync(noirAbiPath, 'utf8')); - const aztecAbi = loadContractArtifact(contract); const { nr, ts } = opts; diff --git a/yarn-project/simulator/src/avm/temporary_executor_migration.ts b/yarn-project/simulator/src/avm/temporary_executor_migration.ts index 60cc50fc33e1..80b84669dd62 100644 --- a/yarn-project/simulator/src/avm/temporary_executor_migration.ts +++ b/yarn-project/simulator/src/avm/temporary_executor_migration.ts @@ -22,7 +22,7 @@ import { JournalData } from './journal/journal.js'; * @param globalVariables * @returns */ -export function temporaryMapToExecutionEnvironment( +export function temporaryCreateAvmExecutionEnvironment( current: PublicExecution, globalVariables: GlobalVariables, ): AvmExecutionEnvironment { @@ -54,7 +54,7 @@ export function temporaryMapToExecutionEnvironment( * @param result * @returns */ -export function temporaryMapAvmReturnTypes( +export function temporaryConvertAvmResults( execution: PublicExecution, newWorldState: JournalData, result: AvmContractCallResults, diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index cba1f69830b8..e678e8c06282 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -7,7 +7,10 @@ import { AvmMachineState } from '../avm/avm_machine_state.js'; import { AvmSimulator } from '../avm/avm_simulator.js'; import { HostStorage } from '../avm/journal/host_storage.js'; import { AvmWorldStateJournal } from '../avm/journal/index.js'; -import { temporaryMapAvmReturnTypes, temporaryMapToExecutionEnvironment } from '../avm/temporary_executor_migration.js'; +import { + temporaryConvertAvmResults, + temporaryCreateAvmExecutionEnvironment, +} from '../avm/temporary_executor_migration.js'; import { ExecutionError, createSimulationError } from '../common/errors.js'; import { SideEffectCounter } from '../common/index.js'; import { PackedArgsCache } from '../common/packed_args_cache.js'; @@ -142,7 +145,7 @@ export class PublicExecutor { // These data structures will permiate across the simulator when the public executor is phased out const hostStorage = new HostStorage(this.stateDb, this.contractsDb, this.commitmentsDb); const worldStateJournal = new AvmWorldStateJournal(hostStorage); - const executionEnv = temporaryMapToExecutionEnvironment(execution, globalVariables); + const executionEnv = temporaryCreateAvmExecutionEnvironment(execution, globalVariables); const machineState = new AvmMachineState(0, 0, 0); const context = new AvmContext(worldStateJournal, executionEnv, machineState); @@ -150,6 +153,6 @@ export class PublicExecutor { const result = await simulator.execute(); const newWorldState = context.worldState.flush(); - return temporaryMapAvmReturnTypes(execution, newWorldState, result); + return temporaryConvertAvmResults(execution, newWorldState, result); } } diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index f63e4dcd96a3..3f4845e1c10f 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -127,6 +127,11 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArt /** * Returns true if the first parameter is kernel function inputs. + * + * Noir macros #[aztec(private|public)] inject the following code + * fn (inputs: ContextInputs, ...otherparams) {} + * + * Return true if this injected parameter is found */ function hasKernelFunctionInputs(params: ABIParameter[]): boolean { const firstParam = params[0]; From 664515c2863ecdb314b53dc2d7b490c316e8bb2b Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:48:48 +0000 Subject: [PATCH 8/8] fmt --- yarn-project/types/src/abi/contract_artifact.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index 3f4845e1c10f..8faf80a682ba 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -127,10 +127,10 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArt /** * Returns true if the first parameter is kernel function inputs. - * - * Noir macros #[aztec(private|public)] inject the following code + * + * Noir macros #[aztec(private|public)] inject the following code * fn (inputs: ContextInputs, ...otherparams) {} - * + * * Return true if this injected parameter is found */ function hasKernelFunctionInputs(params: ABIParameter[]): boolean {