diff --git a/yarn-project/simulator/src/common/debug_fn_name.ts b/yarn-project/simulator/src/common/debug_fn_name.ts index 8bc24788f97d..901440b3e2e0 100644 --- a/yarn-project/simulator/src/common/debug_fn_name.ts +++ b/yarn-project/simulator/src/common/debug_fn_name.ts @@ -2,7 +2,7 @@ import type { Fr } from '@aztec/foundation/fields'; import { FunctionSelector } from '@aztec/stdlib/abi'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; -import type { PublicContractsDBInterface } from './db_interfaces.js'; +import type { PublicContractsDBInterface } from '../public/db_interfaces.js'; export async function getPublicFunctionDebugName( db: PublicContractsDBInterface, diff --git a/yarn-project/simulator/src/common/index.ts b/yarn-project/simulator/src/common/index.ts index 90dc13c923e0..32cf7b9de20b 100644 --- a/yarn-project/simulator/src/common/index.ts +++ b/yarn-project/simulator/src/common/index.ts @@ -1,3 +1,2 @@ export * from './errors.js'; export * from './stats/index.js'; -export * from './message_load_oracle_inputs.js'; diff --git a/yarn-project/simulator/src/private/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/private/acvm/oracle/typed_oracle.ts index 5329ed8910da..aa551d8a0f25 100644 --- a/yarn-project/simulator/src/private/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/private/acvm/oracle/typed_oracle.ts @@ -9,7 +9,7 @@ import type { Note, NoteStatus } from '@aztec/stdlib/note'; import { type MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees'; import type { BlockHeader, TxHash } from '@aztec/stdlib/tx'; -import type { MessageLoadOracleInputs } from '../../../common/message_load_oracle_inputs.js'; +import type { MessageLoadOracleInputs } from '../../message_load_oracle_inputs.js'; /** * Information about a note needed during execution. diff --git a/yarn-project/simulator/src/private/execution_data_provider.ts b/yarn-project/simulator/src/private/execution_data_provider.ts index 4c2eaab4a907..791329c90f1b 100644 --- a/yarn-project/simulator/src/private/execution_data_provider.ts +++ b/yarn-project/simulator/src/private/execution_data_provider.ts @@ -1,3 +1,4 @@ +import type { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants'; import type { Fr, Point } from '@aztec/foundation/fields'; import type { EventSelector, @@ -14,8 +15,8 @@ import type { NoteStatus } from '@aztec/stdlib/note'; import { type MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees'; import type { BlockHeader, TxHash } from '@aztec/stdlib/tx'; -import type { CommitmentsDBInterface } from '../common/db_interfaces.js'; import type { NoteData } from './acvm/index.js'; +import type { MessageLoadOracleInputs } from './message_load_oracle_inputs.js'; /** * Error thrown when a contract is not found in the database. @@ -38,7 +39,7 @@ export class ContractClassNotFoundError extends Error { /** * The interface for the data layer required to perform private and utility execution. */ -export interface ExecutionDataProvider extends CommitmentsDBInterface { +export interface ExecutionDataProvider { /** * Returns a contract instance associated with an address, if available. * @param address - Address. @@ -117,6 +118,40 @@ export interface ExecutionDataProvider extends CommitmentsDBInterface { */ getNullifierIndex(nullifier: Fr): Promise; + /** + * Gets the index of a nullifier in the nullifier tree. + * @param nullifier - The nullifier. + * @returns - The index of the nullifier. Undefined if it does not exist in the tree. + */ + getNullifierIndex(nullifier: Fr): Promise; + + /** + * Returns a nullifier membership witness for the given nullifier or undefined if not found. + * REFACTOR: Same as getL1ToL2MembershipWitness, can be combined with aztec-node method that does almost the same thing. + * @param nullifier - Nullifier we're looking for. + */ + getNullifierMembershipWitnessAtLatestBlock(nullifier: Fr): Promise; + + /** + * Fetches a message from the db, given its key. + * @param contractAddress - Address of a contract by which the message was emitted. + * @param messageHash - Hash of the message. + * @param secret - Secret used to compute a nullifier. + * @dev Contract address and secret are only used to compute the nullifier to get non-nullified messages + * @returns The l1 to l2 membership witness (index of message in the tree and sibling path). + */ + getL1ToL2MembershipWitness( + contractAddress: AztecAddress, + messageHash: Fr, + secret: Fr, + ): Promise>; + + /** + * @param leafIndex the leaf to look up + * @returns The l1 to l2 leaf message hash or undefined if not found. + */ + getL1ToL2MessageHash(leafIndex: bigint): Promise; + /** * Retrieve the databases view of the Block Header object. * This structure is fed into the circuits simulator and is used to prove against certain historical roots. @@ -263,6 +298,13 @@ export interface ExecutionDataProvider extends CommitmentsDBInterface { recipient: AztecAddress, ): Promise; + /** + * Gets note hash in the note hash tree at the given leaf index. + * @param leafIndex - the leaf to look up. + * @returns - The note hash at that index. Undefined if leaf index is not found. + */ + getNoteHash(leafIndex: bigint): Promise; + /** * Searches for a log with the corresponding `tag` and returns it along with contextual transaction information. * Returns null if no such log exists, and throws if more than one exists. diff --git a/yarn-project/simulator/src/private/index.ts b/yarn-project/simulator/src/private/index.ts index 09bcc63b7393..ca990ca82283 100644 --- a/yarn-project/simulator/src/private/index.ts +++ b/yarn-project/simulator/src/private/index.ts @@ -13,3 +13,4 @@ export { extractCallStack } from './acvm/acvm.js'; export { type NoteData, TypedOracle } from './acvm/oracle/typed_oracle.js'; export { Oracle } from './acvm/oracle/oracle.js'; export { HashedValuesCache } from './hashed_values_cache.js'; +export { MessageLoadOracleInputs } from './message_load_oracle_inputs.js'; diff --git a/yarn-project/simulator/src/common/message_load_oracle_inputs.ts b/yarn-project/simulator/src/private/message_load_oracle_inputs.ts similarity index 100% rename from yarn-project/simulator/src/common/message_load_oracle_inputs.ts rename to yarn-project/simulator/src/private/message_load_oracle_inputs.ts diff --git a/yarn-project/simulator/src/private/private_execution.test.ts b/yarn-project/simulator/src/private/private_execution.test.ts index 25d4e5658c6f..f38987782dcd 100644 --- a/yarn-project/simulator/src/private/private_execution.test.ts +++ b/yarn-project/simulator/src/private/private_execution.test.ts @@ -64,9 +64,9 @@ import { jest } from '@jest/globals'; import { Matcher, type MatcherCreator, type MockProxy, mock } from 'jest-mock-extended'; import { toFunctionSelector } from 'viem'; -import { MessageLoadOracleInputs } from '../common/message_load_oracle_inputs.js'; import { buildL1ToL2Message } from '../test/utils.js'; import type { ExecutionDataProvider } from './execution_data_provider.js'; +import { MessageLoadOracleInputs } from './message_load_oracle_inputs.js'; import { WASMSimulator } from './providers/acvm_wasm.js'; import { AcirSimulator } from './simulator.js'; diff --git a/yarn-project/simulator/src/public/avm/avm_simulator.test.ts b/yarn-project/simulator/src/public/avm/avm_simulator.test.ts index a50aa55729ab..b5044f151dfe 100644 --- a/yarn-project/simulator/src/public/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/public/avm/avm_simulator.test.ts @@ -75,10 +75,10 @@ import { import { encodeToBytecode } from './serialization/bytecode_serialization.js'; import { Opcode } from './serialization/instruction_serialization.js'; import { + mockCheckNullifierExists, mockGetBytecodeCommitment, mockGetContractClass, mockGetContractInstance, - mockGetNullifierIndex, mockL1ToL2MessageExists, mockNoteHashCount, mockNoteHashExists, @@ -626,7 +626,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const bytecode = getAvmTestContractBytecode('nullifier_exists'); if (exists) { - mockGetNullifierIndex(treesDB, leafIndex, siloedNullifier0); + mockCheckNullifierExists(treesDB, true, siloedNullifier0); } const results = await new AvmSimulator(context).executeBytecode(bytecode); @@ -892,9 +892,9 @@ describe('AVM simulator: transpiled Noir contracts', () => { mockGetContractInstance(contractsDB, contractInstanceWithAddress); mockGetContractInstance(contractsDB, contractInstanceWithAddress); mockGetContractInstance(contractsDB, contractInstanceWithAddress); - mockGetNullifierIndex(treesDB, await siloAddress(contractInstanceWithAddress.address)); - mockGetNullifierIndex(treesDB, await siloAddress(contractInstanceWithAddress.address)); - mockGetNullifierIndex(treesDB, await siloAddress(contractInstanceWithAddress.address)); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstanceWithAddress.address)); const bytecode = getAvmTestContractBytecode('test_get_contract_instance'); @@ -930,7 +930,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { mockGetBytecodeCommitment(contractsDB, await computePublicBytecodeCommitment(contractClass.packedBytecode)); const contractInstance = await makeContractInstanceFromClassId(contractClass.id); mockGetContractInstance(contractsDB, contractInstance); - mockGetNullifierIndex(treesDB, await siloAddress(contractInstance.address)); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstance.address)); const nestedTrace = mock(); mockTraceFork(trace, nestedTrace); @@ -951,7 +951,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const contractInstance = await makeContractInstanceFromClassId(contractClass.id); mockGetContractInstance(contractsDB, contractInstance); mockGetBytecodeCommitment(contractsDB, await computePublicBytecodeCommitment(contractClass.packedBytecode)); - mockGetNullifierIndex(treesDB, await siloAddress(contractInstance.address)); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstance.address)); const nestedTrace = mock(); mockTraceFork(trace, nestedTrace); @@ -975,7 +975,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { mockGetBytecodeCommitment(contractsDB, await computePublicBytecodeCommitment(contractClass.packedBytecode)); const contractInstance = await makeContractInstanceFromClassId(contractClass.id); mockGetContractInstance(contractsDB, contractInstance); - mockGetNullifierIndex(treesDB, await siloAddress(contractInstance.address)); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstance.address)); mockTraceFork(trace); @@ -994,7 +994,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { mockGetBytecodeCommitment(contractsDB, await computePublicBytecodeCommitment(contractClass.packedBytecode)); const contractInstance = await makeContractInstanceFromClassId(contractClass.id); mockGetContractInstance(contractsDB, contractInstance); - mockGetNullifierIndex(treesDB, await siloAddress(contractInstance.address)); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstance.address)); const nestedTrace = mock(); mockTraceFork(trace, nestedTrace); @@ -1021,7 +1021,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { mockGetBytecodeCommitment(contractsDB, await computePublicBytecodeCommitment(contractClass.packedBytecode)); const contractInstance = await makeContractInstanceFromClassId(contractClass.id); mockGetContractInstance(contractsDB, contractInstance); - mockGetNullifierIndex(treesDB, await siloAddress(contractInstance.address)); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstance.address)); mockTraceFork(trace); @@ -1043,7 +1043,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { mockGetBytecodeCommitment(contractsDB, await computePublicBytecodeCommitment(contractClass.packedBytecode)); const contractInstance = await makeContractInstanceFromClassId(contractClass.id); mockGetContractInstance(contractsDB, contractInstance); - mockGetNullifierIndex(treesDB, await siloAddress(contractInstance.address)); + mockCheckNullifierExists(treesDB, true, await siloAddress(contractInstance.address)); mockTraceFork(trace); diff --git a/yarn-project/simulator/src/public/avm/opcodes/accrued_substate.test.ts b/yarn-project/simulator/src/public/avm/opcodes/accrued_substate.test.ts index a1aa53c41eaf..b2e24d127537 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/accrued_substate.test.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/accrued_substate.test.ts @@ -12,7 +12,7 @@ import { Field, Uint8, Uint32 } from '../avm_memory_types.js'; import { InstructionExecutionError, StaticCallAlterationError } from '../errors.js'; import { initContext, initExecutionEnvironment, initPersistableStateManager } from '../fixtures/index.js'; import { - mockGetNullifierIndex, + mockCheckNullifierExists, mockL1ToL2MessageExists, mockNoteHashCount, mockNoteHashExists, @@ -159,7 +159,7 @@ describe('Accrued Substate', () => { const addressOffset = 1; if (exists) { - mockGetNullifierIndex(treesDB, leafIndex, value0); + mockCheckNullifierExists(treesDB, true, value0); } context.machineState.memory.set(value0Offset, new Field(value0)); // nullifier @@ -210,7 +210,7 @@ describe('Accrued Substate', () => { }); it('Nullifier collision reverts (nullifier exists in host state)', async () => { - mockGetNullifierIndex(treesDB, leafIndex); // db will say that nullifier already exists + mockCheckNullifierExists(treesDB, true, leafIndex); context.machineState.memory.set(value0Offset, new Field(value0)); await expect(new EmitNullifier(/*indirect=*/ 0, /*offset=*/ value0Offset).execute(context)).rejects.toThrow( new InstructionExecutionError( diff --git a/yarn-project/simulator/src/public/avm/opcodes/external_calls.test.ts b/yarn-project/simulator/src/public/avm/opcodes/external_calls.test.ts index 4841f4bb4da7..045e71ad5005 100644 --- a/yarn-project/simulator/src/public/avm/opcodes/external_calls.test.ts +++ b/yarn-project/simulator/src/public/avm/opcodes/external_calls.test.ts @@ -13,10 +13,10 @@ import { initContext, initPersistableStateManager } from '../fixtures/index.js'; import { encodeToBytecode } from '../serialization/bytecode_serialization.js'; import { Opcode } from '../serialization/instruction_serialization.js'; import { + mockCheckNullifierExists, mockGetBytecodeCommitment, mockGetContractClass, mockGetContractInstance, - mockGetNullifierIndex, mockTraceFork, } from '../test_utils.js'; import { EnvironmentVariable, GetEnvVar } from './environment_getters.js'; @@ -128,7 +128,7 @@ describe('External Calls', () => { mockGetBytecodeCommitment(contractsDB, await computePublicBytecodeCommitment(contractClass.packedBytecode)); const contractInstance = await makeContractInstanceFromClassId(contractClass.id); mockGetContractInstance(contractsDB, contractInstance); - mockGetNullifierIndex(treesDB, contractInstance.address.toField()); + mockCheckNullifierExists(treesDB, true, contractInstance.address.toField()); const { l2GasLeft: initialL2Gas, daGasLeft: initialDaGas } = context.machineState; @@ -174,14 +174,14 @@ describe('External Calls', () => { new Set(/*indirect=*/ 0, /*dstOffset=*/ 1, TypeTag.UINT32, 1).as(Opcode.SET_8, Set.wireFormat8), new Return(/*indirect=*/ 0, /*retOffset=*/ 0, /*size=*/ 1), ]); - mockGetNullifierIndex(treesDB, addr); + mockCheckNullifierExists(treesDB, true, addr); const contractClass = await makeContractClassPublic(0, otherContextInstructionsBytecode); mockGetContractClass(contractsDB, contractClass); mockGetBytecodeCommitment(contractsDB, await computePublicBytecodeCommitment(contractClass.packedBytecode)); const contractInstance = await makeContractInstanceFromClassId(contractClass.id); mockGetContractInstance(contractsDB, contractInstance); - mockGetNullifierIndex(treesDB, contractInstance.address.toField()); + mockCheckNullifierExists(treesDB, true, contractInstance.address.toField()); const { l2GasLeft: initialL2Gas, daGasLeft: initialDaGas } = context.machineState; @@ -252,7 +252,7 @@ describe('External Calls', () => { ]; const otherContextInstructionsBytecode = encodeToBytecode(otherContextInstructions); - mockGetNullifierIndex(treesDB, addr.toFr()); + mockCheckNullifierExists(treesDB, true, addr.toFr()); const contractClass = await makeContractClassPublic(0, otherContextInstructionsBytecode); mockGetContractClass(contractsDB, contractClass); diff --git a/yarn-project/simulator/src/public/avm/test_utils.ts b/yarn-project/simulator/src/public/avm/test_utils.ts index 1be367d7cab4..fa05a8fedca0 100644 --- a/yarn-project/simulator/src/public/avm/test_utils.ts +++ b/yarn-project/simulator/src/public/avm/test_utils.ts @@ -38,8 +38,8 @@ export function mockNoteHashExists(worldStateDB: PublicTreesDB, _leafIndex: Fr, }); } -export function mockGetNullifierIndex(worldStateDB: PublicTreesDB, leafIndex: Fr, _ignoredValue?: Fr) { - (worldStateDB as jest.Mocked).getNullifierIndex.mockResolvedValue(leafIndex.toBigInt()); +export function mockCheckNullifierExists(worldStateDB: PublicTreesDB, exists: boolean, _ignoredValue?: Fr) { + (worldStateDB as jest.Mocked).checkNullifierExists.mockResolvedValue(exists); } export function mockL1ToL2MessageExists( diff --git a/yarn-project/simulator/src/common/db_interfaces.ts b/yarn-project/simulator/src/public/db_interfaces.ts similarity index 52% rename from yarn-project/simulator/src/common/db_interfaces.ts rename to yarn-project/simulator/src/public/db_interfaces.ts index 862fc5556e14..ee177f472587 100644 --- a/yarn-project/simulator/src/common/db_interfaces.ts +++ b/yarn-project/simulator/src/public/db_interfaces.ts @@ -1,11 +1,7 @@ -import type { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants'; import type { Fr } from '@aztec/foundation/fields'; import type { FunctionSelector } from '@aztec/stdlib/abi'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/stdlib/contract'; -import type { NullifierMembershipWitness } from '@aztec/stdlib/trees'; - -import type { MessageLoadOracleInputs } from './message_load_oracle_inputs.js'; /** * Database interface for providing access to public state. @@ -62,47 +58,3 @@ export interface PublicContractsDBInterface { */ getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector): Promise; } - -/** Database interface for providing access to note hash tree, l1 to l2 message tree, and nullifier tree. */ -export interface CommitmentsDBInterface { - /** - * Fetches a message from the db, given its key. - * @param contractAddress - Address of a contract by which the message was emitted. - * @param messageHash - Hash of the message. - * @param secret - Secret used to compute a nullifier. - * @dev Contract address and secret are only used to compute the nullifier to get non-nullified messages - * @returns The l1 to l2 membership witness (index of message in the tree and sibling path). - */ - getL1ToL2MembershipWitness( - contractAddress: AztecAddress, - messageHash: Fr, - secret: Fr, - ): Promise>; - - /** - * @param leafIndex the leaf to look up - * @returns The l1 to l2 leaf message hash or undefined if not found. - */ - getL1ToL2MessageHash(leafIndex: bigint): Promise; - - /** - * Gets note hash in the note hash tree at the given leaf index. - * @param leafIndex - the leaf to look up. - * @returns - The note hash at that index. Undefined if leaf index is not found. - */ - getNoteHash(leafIndex: bigint): Promise; - - /** - * Gets the index of a nullifier in the nullifier tree. - * @param nullifier - The nullifier. - * @returns - The index of the nullifier. Undefined if it does not exist in the tree. - */ - getNullifierIndex(nullifier: Fr): Promise; - - /** - * Returns a nullifier membership witness for the given nullifier or undefined if not found. - * REFACTOR: Same as getL1ToL2MembershipWitness, can be combined with aztec-node method that does almost the same thing. - * @param nullifier - Nullifier we're looking for. - */ - getNullifierMembershipWitnessAtLatestBlock(nullifier: Fr): Promise; -} diff --git a/yarn-project/simulator/src/public/hinting_db_sources.ts b/yarn-project/simulator/src/public/hinting_db_sources.ts index 4d21fbb4ce67..bab2827a9003 100644 --- a/yarn-project/simulator/src/public/hinting_db_sources.ts +++ b/yarn-project/simulator/src/public/hinting_db_sources.ts @@ -38,7 +38,7 @@ import { import { strict as assert } from 'assert'; -import type { PublicContractsDBInterface } from '../common/db_interfaces.js'; +import type { PublicContractsDBInterface } from './db_interfaces.js'; import { PublicTreesDB } from './public_db_sources.js'; /** diff --git a/yarn-project/simulator/src/public/index.ts b/yarn-project/simulator/src/public/index.ts index 24cf9008f7b1..802b80f80720 100644 --- a/yarn-project/simulator/src/public/index.ts +++ b/yarn-project/simulator/src/public/index.ts @@ -1,4 +1,4 @@ -export * from '../common/db_interfaces.js'; +export * from './db_interfaces.js'; export * from './public_tx_simulator/index.js'; export * from './public_db_sources.js'; export { PublicProcessor, PublicProcessorFactory } from './public_processor/public_processor.js'; diff --git a/yarn-project/simulator/src/public/public_db_sources.ts b/yarn-project/simulator/src/public/public_db_sources.ts index f2ccd0e85de9..9f2578d248e5 100644 --- a/yarn-project/simulator/src/public/public_db_sources.ts +++ b/yarn-project/simulator/src/public/public_db_sources.ts @@ -28,7 +28,7 @@ import type { PublicDBAccessStats } from '@aztec/stdlib/stats'; import { MerkleTreeId, NullifierLeaf, PublicDataTreeLeaf, type PublicDataTreeLeafPreimage } from '@aztec/stdlib/trees'; import type { BlockHeader, StateReference, Tx } from '@aztec/stdlib/tx'; -import type { PublicContractsDBInterface, PublicStateDBInterface } from '../common/db_interfaces.js'; +import type { PublicContractsDBInterface, PublicStateDBInterface } from './db_interfaces.js'; import { TxContractCache } from './tx_contract_cache.js'; /** @@ -463,7 +463,7 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt return leafValue; } - public async getNullifierIndex(nullifier: Fr): Promise { + public async checkNullifierExists(nullifier: Fr): Promise { const timer = new Timer(); const lowLeafResult = await this.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt()); if (!lowLeafResult) { @@ -473,14 +473,14 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt await this.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index); // TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer. await this.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index); - const index = lowLeafResult.alreadyPresent ? lowLeafResult.index : undefined; + const exists = lowLeafResult.alreadyPresent; - this.logger.debug(`[DB] Fetched nullifier index`, { + this.logger.debug(`[DB] Checked nullifier exists`, { eventName: 'public-db-access', duration: timer.ms(), - operation: 'get-nullifier-index', + operation: 'check-nullifier-exists', } satisfies PublicDBAccessStats); - return index; + return exists; } public async padTree(treeId: MerkleTreeId, leavesToInsert: number): Promise { diff --git a/yarn-project/simulator/src/public/state_manager/nullifiers.test.ts b/yarn-project/simulator/src/public/state_manager/nullifiers.test.ts index 8ca8936a94a4..ea9e3b6f77b1 100644 --- a/yarn-project/simulator/src/public/state_manager/nullifiers.test.ts +++ b/yarn-project/simulator/src/public/state_manager/nullifiers.test.ts @@ -18,6 +18,7 @@ describe('avm nullifier caching', () => { it('Reading a non-existent nullifier works (gets zero & DNE)', async () => { const nullifier = new Fr(2); // never written! + worldStateDB.checkNullifierExists.mockResolvedValue(false); const { exists, cacheHit } = await nullifiers.checkExists(nullifier); // doesn't exist, not pending, index is zero (non-existent) expect(exists).toEqual(false); @@ -35,9 +36,8 @@ describe('avm nullifier caching', () => { }); it('Existence check works on fallback to host (gets index, exists, not-pending)', async () => { const nullifier = new Fr(2); - const storedLeafIndex = BigInt(420); - worldStateDB.getNullifierIndex.mockResolvedValue(storedLeafIndex); + worldStateDB.checkNullifierExists.mockResolvedValue(true); const { exists, cacheHit } = await nullifiers.checkExists(nullifier); // exists (in host), not pending, tree index retrieved from host @@ -95,10 +95,9 @@ describe('avm nullifier caching', () => { }); it('Cant append nullifier that already exist in host', async () => { const nullifier = new Fr(2); // same nullifier for both! - const storedLeafIndex = BigInt(420); // Nullifier exists in host - worldStateDB.getNullifierIndex.mockResolvedValue(storedLeafIndex); + worldStateDB.checkNullifierExists.mockResolvedValue(true); // Can't append to cache await expect(nullifiers.append(nullifier)).rejects.toThrow( `Siloed nullifier ${nullifier} already exists in parent cache or host.`, diff --git a/yarn-project/simulator/src/public/state_manager/nullifiers.ts b/yarn-project/simulator/src/public/state_manager/nullifiers.ts index a593d637e07c..7bea704bce23 100644 --- a/yarn-project/simulator/src/public/state_manager/nullifiers.ts +++ b/yarn-project/simulator/src/public/state_manager/nullifiers.ts @@ -64,8 +64,8 @@ export class NullifierManager { // `${MerkleTreeId[MerkleTreeId.NULLIFIER_TREE]} low leaf index should always be found (even if target leaf does not exist)`, //); //existsInTree = leafOrLowLeafIndex.alreadyPresent; - const leafIndex = await this.hostNullifiers.getNullifierIndex(siloedNullifier); - existsInTree = leafIndex !== undefined; + const exists = await this.hostNullifiers.checkNullifierExists(siloedNullifier); + existsInTree = exists; } const exists = cacheHit || existsInTree; return Promise.resolve({ exists, cacheHit }); diff --git a/yarn-project/simulator/src/public/state_manager/public_storage.test.ts b/yarn-project/simulator/src/public/state_manager/public_storage.test.ts index a79017dfd222..b6357c4fe5b5 100644 --- a/yarn-project/simulator/src/public/state_manager/public_storage.test.ts +++ b/yarn-project/simulator/src/public/state_manager/public_storage.test.ts @@ -3,7 +3,7 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { type MockProxy, mock } from 'jest-mock-extended'; -import type { PublicStateDBInterface } from '../../common/db_interfaces.js'; +import type { PublicStateDBInterface } from '../db_interfaces.js'; import { PublicStorage } from './public_storage.js'; describe('avm public storage', () => { diff --git a/yarn-project/simulator/src/public/state_manager/public_storage.ts b/yarn-project/simulator/src/public/state_manager/public_storage.ts index e02f5d3099d5..560c80bf2a47 100644 --- a/yarn-project/simulator/src/public/state_manager/public_storage.ts +++ b/yarn-project/simulator/src/public/state_manager/public_storage.ts @@ -1,7 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; -import type { PublicStateDBInterface } from '../../common/db_interfaces.js'; +import type { PublicStateDBInterface } from '../db_interfaces.js'; type PublicStorageReadResult = { value: Fr; diff --git a/yarn-project/simulator/src/public/state_manager/state_manager.test.ts b/yarn-project/simulator/src/public/state_manager/state_manager.test.ts index 4be91091b729..46040f6ddcae 100644 --- a/yarn-project/simulator/src/public/state_manager/state_manager.test.ts +++ b/yarn-project/simulator/src/public/state_manager/state_manager.test.ts @@ -9,10 +9,10 @@ import { mock } from 'jest-mock-extended'; import { initPersistableStateManager } from '../avm/fixtures/index.js'; import { + mockCheckNullifierExists, mockGetBytecodeCommitment, mockGetContractClass, mockGetContractInstance, - mockGetNullifierIndex, mockL1ToL2MessageExists, mockNoteHashCount, mockNoteHashExists, @@ -86,12 +86,13 @@ describe('state_manager', () => { }); it('checkNullifierExists works for missing nullifiers', async () => { + mockCheckNullifierExists(treesDB, false, leafIndex); const exists = await persistableState.checkNullifierExists(address, utxo); expect(exists).toEqual(false); }); it('checkNullifierExists works for existing nullifiers', async () => { - mockGetNullifierIndex(treesDB, leafIndex, utxo); + mockCheckNullifierExists(treesDB, true, leafIndex); const exists = await persistableState.checkNullifierExists(address, utxo); expect(exists).toEqual(true); }); @@ -128,14 +129,14 @@ describe('state_manager', () => { const siloedNullifier = await siloNullifier(ProtocolContractAddress.ContractInstanceDeployer, address.toField()); mockGetContractInstance(contractsDB, contractInstance.withAddress(address)); - mockGetNullifierIndex(treesDB, leafIndex, utxo); + mockCheckNullifierExists(treesDB, true, leafIndex); await persistableState.getContractInstance(address); expect(contractsDB.getContractInstance).toHaveBeenCalledTimes(1); expect(contractsDB.getContractInstance).toHaveBeenCalledWith(address, /*blockNumber=*/ expect.any(Number)); - expect(treesDB.getNullifierIndex).toHaveBeenCalledTimes(1); - expect(treesDB.getNullifierIndex).toHaveBeenCalledWith(siloedNullifier); + expect(treesDB.checkNullifierExists).toHaveBeenCalledTimes(1); + expect(treesDB.checkNullifierExists).toHaveBeenCalledWith(siloedNullifier); }); it('Can get undefined contract instance', async () => { await persistableState.getContractInstance(address); @@ -150,7 +151,7 @@ describe('state_manager', () => { const contractClass = await makeContractClassPublic(); contractClass.packedBytecode = bytecode; - mockGetNullifierIndex(treesDB, leafIndex); + mockCheckNullifierExists(treesDB, true, leafIndex); mockGetContractInstance(contractsDB, contractInstance.withAddress(address)); mockGetContractClass(contractsDB, contractClass); mockGetBytecodeCommitment(contractsDB, bytecodeCommitment); diff --git a/yarn-project/simulator/src/public/state_manager/state_manager.ts b/yarn-project/simulator/src/public/state_manager/state_manager.ts index e9f74a946eb8..d74043124f7b 100644 --- a/yarn-project/simulator/src/public/state_manager/state_manager.ts +++ b/yarn-project/simulator/src/public/state_manager/state_manager.ts @@ -252,7 +252,7 @@ export class PublicPersistableStateManager { const siloedNullifier = await siloNullifier(contractAddress, nullifier); if (this.doMerkleOperations) { - const exists = (await this.treesDB.getNullifierIndex(siloedNullifier)) !== undefined; + const exists = await this.treesDB.checkNullifierExists(siloedNullifier); this.log.trace(`Checked siloed nullifier ${siloedNullifier} (exists=${exists})`); return Promise.resolve(exists); } else { @@ -282,10 +282,10 @@ export class PublicPersistableStateManager { this.log.trace(`Inserting siloed nullifier=${siloedNullifier}`); if (this.doMerkleOperations) { - const index = await this.treesDB.getNullifierIndex(siloedNullifier); + const exists = await this.treesDB.checkNullifierExists(siloedNullifier); - if (index !== undefined) { - this.log.verbose(`Siloed nullifier ${siloedNullifier} already present in tree at index ${index}!`); + if (exists) { + this.log.verbose(`Siloed nullifier ${siloedNullifier} already present in tree!`); throw new NullifierCollisionError( `Siloed nullifier ${siloedNullifier} already exists in parent cache or host.`, );