From 9eeb7e6a6b1523e1dfe639028cbea4236ef5b403 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] 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. */