From 271b060f2642570f58e38881cbb3477745b84ddf Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Wed, 13 Sep 2023 18:26:44 +0200 Subject: [PATCH] fix: ensure_note_hash_exists (#2256) Closes #1142 #1029 - Rename `oracle.getCommitment` to `oracle.checkNoteHashExists`. - Change `Set.assert_contains_and_remove(note, nonce)` to take a nonce in addition to a note. We calculate the inner note hash from the provided note. And although the nonce can be set to the header of the note, by making it a required parameter of this method makes it clearer that nonce is needed to check the existence of a note hash. (An example will be created in a later PR to show how a recipient can learn about the nonce if they don't have the encrypted data.) - Change the api on CommitmentDb to only return an index of a note hash: the index is all we need to know if a note hash exists, and to use it to get `readRequestMembershipWitnesses` later in the kernel prover. - (A tiny change that is not really related to this PR): We don't have to emit storage slot when notifying the simulator about a new nullifier. # Checklist: Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge. - [ ] If the pull request requires a cryptography review (e.g. cryptographic algorithm implementations) I have added the 'crypto' tag. - [ ] I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code. - [ ] Every change is related to the PR description. - [ ] I have [linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this pull request to relevant issues (if any exist). --------- Co-authored-by: David Banks <47112877+dbanks12@users.noreply.github.com> --- yarn-project/acir-simulator/src/acvm/acvm.ts | 2 +- .../acir-simulator/src/acvm/serialize.ts | 19 +---- .../src/client/client_execution_context.ts | 65 ++++++++------- .../acir-simulator/src/client/db_oracle.ts | 16 ---- .../src/client/execution_note_cache.ts | 68 +++++++--------- .../src/client/private_execution.test.ts | 32 +------- .../src/client/private_execution.ts | 7 +- .../src/client/unconstrained_execution.ts | 3 +- yarn-project/acir-simulator/src/public/db.ts | 11 ++- .../acir-simulator/src/public/executor.ts | 18 +++-- .../aztec-rpc/src/simulator_oracle/index.ts | 30 ++----- .../docs_example_contract/src/actions.nr | 5 +- .../native_token_contract/src/main.nr | 4 +- .../non_native_token_contract/src/main.nr | 4 +- .../src/interface.nr | 8 +- .../src/main.nr | 7 +- .../src/contracts/token_contract/src/main.nr | 4 +- .../noir-libs/aztec-noir/src/messaging.nr | 1 - .../messaging/get_commitment_getter_data.nr | 15 ---- .../aztec-noir/src/note/lifecycle.nr | 3 +- .../aztec-noir/src/note/note_getter.nr | 74 ++++------------- .../noir-libs/aztec-noir/src/oracle.nr | 1 - .../aztec-noir/src/oracle/get_commitment.nr | 11 --- .../noir-libs/aztec-noir/src/oracle/notes.nr | 17 +++- .../aztec-noir/src/state_vars/set.nr | 80 +++++++++++-------- .../aztec-noir/src/state_vars/singleton.nr | 4 +- .../src/simulator/public_executor.ts | 18 +---- 27 files changed, 201 insertions(+), 326 deletions(-) delete mode 100644 yarn-project/noir-libs/aztec-noir/src/messaging/get_commitment_getter_data.nr delete mode 100644 yarn-project/noir-libs/aztec-noir/src/oracle/get_commitment.nr diff --git a/yarn-project/acir-simulator/src/acvm/acvm.ts b/yarn-project/acir-simulator/src/acvm/acvm.ts index e806f22618c..2a9db8fb761 100644 --- a/yarn-project/acir-simulator/src/acvm/acvm.ts +++ b/yarn-project/acir-simulator/src/acvm/acvm.ts @@ -38,6 +38,7 @@ type ORACLE_NAMES = | 'getSecretKey' | 'getNote' | 'getNotes' + | 'checkNoteHashExists' | 'getRandomField' | 'notifyCreatedNote' | 'notifyNullifiedNote' @@ -46,7 +47,6 @@ type ORACLE_NAMES = | 'enqueuePublicFunctionCall' | 'storageRead' | 'storageWrite' - | 'getCommitment' | 'getL1ToL2Message' | 'getPortalContractAddress' | 'emitEncryptedLog' diff --git a/yarn-project/acir-simulator/src/acvm/serialize.ts b/yarn-project/acir-simulator/src/acvm/serialize.ts index 9b8e2640315..8784774486c 100644 --- a/yarn-project/acir-simulator/src/acvm/serialize.ts +++ b/yarn-project/acir-simulator/src/acvm/serialize.ts @@ -9,7 +9,7 @@ import { } from '@aztec/circuits.js'; import { Fr } from '@aztec/foundation/fields'; -import { CommitmentDataOracleInputs, MessageLoadOracleInputs } from '../client/db_oracle.js'; +import { MessageLoadOracleInputs } from '../client/db_oracle.js'; import { ACVMField, toACVMField } from './acvm.js'; // Utilities to write TS classes to ACVM Field arrays @@ -160,23 +160,6 @@ export function toAcvmL1ToL2MessageLoadOracleInputs( ]; } -/** - * Converts the result of loading commitments to ACVM fields. - * @param commitmentLoadOracleInputs - The result of loading messages to convert. - * @param l1ToL2MessagesTreeRoot - The L1 to L2 messages tree root - * @returns The Message Oracle Fields. - */ -export function toAcvmCommitmentLoadOracleInputs( - messageLoadOracleInputs: CommitmentDataOracleInputs, - l1ToL2MessagesTreeRoot: Fr, -): ACVMField[] { - return [ - toACVMField(messageLoadOracleInputs.commitment), - toACVMField(messageLoadOracleInputs.index), - toACVMField(l1ToL2MessagesTreeRoot), - ]; -} - /** * Inserts a list of ACVM fields to a witness. * @param witnessStartIndex - The index where to start inserting the fields. diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 61d1d09c779..550490b48be 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -6,9 +6,10 @@ import { createDebugLogger } from '@aztec/foundation/log'; import { ACVMField, + ONE_ACVM_FIELD, + ZERO_ACVM_FIELD, fromACVMField, toACVMField, - toAcvmCommitmentLoadOracleInputs, toAcvmL1ToL2MessageLoadOracleInputs, } from '../acvm/index.js'; import { PackedArgsCache } from '../common/packed_args_cache.js'; @@ -156,7 +157,7 @@ export class ClientTxExecutionContext { // Nullified pending notes are already removed from the list. const pendingNotes = this.noteCache.getNotes(contractAddress, storageSlotField); - const pendingNullifiers = this.noteCache.getNullifiers(contractAddress, storageSlotField); + const pendingNullifiers = this.noteCache.getNullifiers(contractAddress); const dbNotes = await this.db.getNotes(contractAddress, storageSlotField); const dbNotesFiltered = dbNotes.filter(n => !pendingNullifiers.has((n.siloedNullifier as Fr).value)); @@ -253,23 +254,12 @@ export class ClientTxExecutionContext { * Adding a siloed nullifier into the current set of all pending nullifiers created * within the current transaction/execution. * @param contractAddress - The contract address. - * @param storageSlot - The storage slot. * @param innerNullifier - The pending nullifier to add in the list (not yet siloed by contract address). * @param innerNoteHash - The inner note hash of the new note. * @param contractAddress - The contract address */ - public async handleNullifiedNote( - contractAddress: AztecAddress, - storageSlot: ACVMField, - innerNullifier: ACVMField, - innerNoteHash: ACVMField, - ) { - await this.noteCache.nullifyNote( - contractAddress, - fromACVMField(storageSlot), - fromACVMField(innerNullifier), - fromACVMField(innerNoteHash), - ); + public async handleNullifiedNote(contractAddress: AztecAddress, innerNullifier: ACVMField, innerNoteHash: ACVMField) { + await this.noteCache.nullifyNote(contractAddress, fromACVMField(innerNullifier), fromACVMField(innerNoteHash)); } /** @@ -285,20 +275,39 @@ export class ClientTxExecutionContext { /** * Fetches a path to prove existence of a commitment in the db, given its contract side commitment (before silo). * @param contractAddress - The contract address. - * @param commitment - The commitment. - * @returns The commitment data. + * @param nonce - The nonce of the note. + * @param innerNoteHash - The inner note hash of the note. + * @returns 1 if (persistent or transient) note hash exists, 0 otherwise. Value is in ACVMField form. */ - public async getCommitment(contractAddress: AztecAddress, commitment: ACVMField) { - const innerNoteHash = fromACVMField(commitment); - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): only works - // for noteHashes/commitments created by public functions! Once public kernel or - // base rollup circuit injects nonces, this can be used with commitments created by - // private functions as well. - const commitmentInputs = await this.db.getCommitmentOracle(contractAddress, innerNoteHash); - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1029): support pending commitments here + public async checkNoteHashExists( + contractAddress: AztecAddress, + nonce: ACVMField, + innerNoteHash: ACVMField, + ): Promise { + const nonceField = fromACVMField(nonce); + const innerNoteHashField = fromACVMField(innerNoteHash); + if (nonceField.isZero()) { + // If nonce is 0, we are looking for a new note created in this transaction. + const exists = this.noteCache.checkNoteExists(contractAddress, innerNoteHashField); + if (exists) { + return ONE_ACVM_FIELD; + } + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) + // Currently it can also be a note created from public if nonce is 0. + // If we can't find a matching new note, keep looking for the match from the notes created in previous transactions. + } + + // If nonce is zero, SHOULD only be able to reach this point if note was publicly created const wasm = await CircuitsWasm.get(); - const siloedNoteHash = siloCommitment(wasm, contractAddress, innerNoteHash); - this.gotNotes.set(siloedNoteHash.value, commitmentInputs.index); - return toAcvmCommitmentLoadOracleInputs(commitmentInputs, this.historicBlockData.privateDataTreeRoot); + let noteHashToLookUp = siloCommitment(wasm, contractAddress, innerNoteHashField); + if (!nonceField.isZero()) { + noteHashToLookUp = computeUniqueCommitment(wasm, nonceField, noteHashToLookUp); + } + + const index = await this.db.getCommitmentIndex(noteHashToLookUp); + if (index !== undefined) { + this.gotNotes.set(noteHashToLookUp.value, index); + } + return index !== undefined ? ONE_ACVM_FIELD : ZERO_ACVM_FIELD; } } diff --git a/yarn-project/acir-simulator/src/client/db_oracle.ts b/yarn-project/acir-simulator/src/client/db_oracle.ts index df56338f9fa..2392e382495 100644 --- a/yarn-project/acir-simulator/src/client/db_oracle.ts +++ b/yarn-project/acir-simulator/src/client/db_oracle.ts @@ -45,22 +45,6 @@ export interface MessageLoadOracleInputs { index: bigint; } -/** - * The format noir uses to get commitments. - */ -export interface CommitmentDataOracleInputs { - /** The siloed commitment. */ - commitment: Fr; - /** - * The path in the merkle tree to the commitment. - */ - siblingPath: Fr[]; - /** - * The index of the message commitment in the merkle tree. - */ - index: bigint; -} - /** * A function ABI with optional debug metadata */ diff --git a/yarn-project/acir-simulator/src/client/execution_note_cache.ts b/yarn-project/acir-simulator/src/client/execution_note_cache.ts index 18de0658095..45e883dda6f 100644 --- a/yarn-project/acir-simulator/src/client/execution_note_cache.ts +++ b/yarn-project/acir-simulator/src/client/execution_note_cache.ts @@ -5,41 +5,32 @@ import { Fr } from '@aztec/foundation/fields'; import { NoteData } from './db_oracle.js'; -/** - * Generate a key with the given contract address and storage slot. - * @param contractAddress - Contract address. - * @param storageSlot - Storage slot. - */ -const generateKeyForContractStorageSlot = (contractAddress: AztecAddress, storageSlot: Fr) => - `${contractAddress.toShortString}${storageSlot}`; - /** * Data that's accessible by all the function calls in an execution. */ export class ExecutionNoteCache { /** - * Notes created during execution. - * The key of the mapping is a value representing a contract address and storage slot combination. + * New notes created in this transaction. + * This mapping maps from a contract address to the notes in the contract. */ - private newNotes: Map = new Map(); + private newNotes: Map = new Map(); /** * The list of nullifiers created in this transaction. - * The key of the mapping is a value representing a contract address and storage slot combination. + * This mapping maps from a contract address to the nullifiers emitted from the contract. * The note which is nullified might be new or not (i.e., was generated in a previous transaction). * Note that their value (bigint representation) is used because Frs cannot be looked up in Sets. */ - private nullifiers: Map> = new Map(); + private nullifiers: Map> = new Map(); /** * Add a new note to cache. * @param note - New note created during execution. */ public addNewNote(note: NoteData) { - const key = generateKeyForContractStorageSlot(note.contractAddress, note.storageSlot); - const notes = this.newNotes.get(key) ?? []; + const notes = this.newNotes.get(note.contractAddress.toBigInt()) ?? []; notes.push(note); - this.newNotes.set(key, notes); + this.newNotes.set(note.contractAddress.toBigInt(), notes); } /** @@ -50,32 +41,22 @@ export class ExecutionNoteCache { * @param innerNoteHash - Inner note hash of the note. If this value equals EMPTY_NULLIFIED_COMMITMENT, it means the * note being nullified is from a previous transaction (and thus not a new note). */ - public async nullifyNote(contractAddress: AztecAddress, storageSlot: Fr, innerNullifier: Fr, innerNoteHash: Fr) { + public async nullifyNote(contractAddress: AztecAddress, innerNullifier: Fr, innerNoteHash: Fr) { const wasm = await CircuitsWasm.get(); const siloedNullifier = siloNullifier(wasm, contractAddress, innerNullifier); - const nullifiers = this.getNullifiers(contractAddress, storageSlot); - if (nullifiers.has(siloedNullifier.value)) { - throw new Error('Attemp to nullify the same note twice.'); - } - + const nullifiers = this.getNullifiers(contractAddress); nullifiers.add(siloedNullifier.value); - const key = generateKeyForContractStorageSlot(contractAddress, storageSlot); - this.nullifiers.set(key, nullifiers); + this.nullifiers.set(contractAddress.toBigInt(), nullifiers); // Find and remove the matching new note if the emitted innerNoteHash is not empty. if (!innerNoteHash.equals(new Fr(EMPTY_NULLIFIED_COMMITMENT))) { - const notes = this.newNotes.get(key) ?? []; - /** - * The identifier used to determine matching is the inner note hash value. - * However, we adopt a defensive approach and ensure that the contract address - * and storage slot do match. - */ + const notes = this.newNotes.get(contractAddress.toBigInt()) ?? []; const noteIndexToRemove = notes.findIndex(n => n.innerNoteHash.equals(innerNoteHash)); if (noteIndexToRemove === -1) { throw new Error('Attemp to remove a pending note that does not exist.'); } notes.splice(noteIndexToRemove, 1); - this.newNotes.set(key, notes); + this.newNotes.set(contractAddress.toBigInt(), notes); } } @@ -86,17 +67,26 @@ export class ExecutionNoteCache { * @param storageSlot - Storage slot of the notes. **/ public getNotes(contractAddress: AztecAddress, storageSlot: Fr) { - const key = generateKeyForContractStorageSlot(contractAddress, storageSlot); - return this.newNotes.get(key) ?? []; + const notes = this.newNotes.get(contractAddress.toBigInt()) ?? []; + return notes.filter(n => n.storageSlot.equals(storageSlot)); } /** - * Return all nullifiers of a storage slot. - * @param contractAddress - Contract address of the notes. - * @param storageSlot - Storage slot of the notes. + * Check if a note exists in the newNotes array. + * @param contractAddress - Contract address of the note. + * @param storageSlot - Storage slot of the note. + * @param innerNoteHash - Inner note hash of the note. + **/ + public checkNoteExists(contractAddress: AztecAddress, innerNoteHash: Fr) { + const notes = this.newNotes.get(contractAddress.toBigInt()) ?? []; + return notes.some(n => n.innerNoteHash.equals(innerNoteHash)); + } + + /** + * Return all nullifiers emitted from a contract. + * @param contractAddress - Address of the contract. */ - public getNullifiers(contractAddress: AztecAddress, storageSlot: Fr): Set { - const key = generateKeyForContractStorageSlot(contractAddress, storageSlot); - return this.nullifiers.get(key) || new Set(); + public getNullifiers(contractAddress: AztecAddress): Set { + return this.nullifiers.get(contractAddress.toBigInt()) ?? new Set(); } } diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index e7d769cd235..d45cbddf93b 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -365,7 +365,7 @@ describe('Private Execution test suite', () => { expect(changeNote.preimage[0]).toEqual(new Fr(balance - amountToTransfer)); }); - it('Should be able to claim a note by providing the correct secret', async () => { + it('Should be able to claim a note by providing the correct secret and nonce', async () => { const amount = 100n; const secret = Fr.random(); const abi = getFunctionAbi(PrivateTokenAirdropContractAbi, 'claim'); @@ -374,22 +374,11 @@ describe('Private Execution test suite', () => { const nonce = new Fr(1n); const customNoteHash = hash([toBufferBE(amount, 32), secret.toBuffer()]); const innerNoteHash = Fr.fromBuffer(hash([storageSlot.toBuffer(), customNoteHash])); - - oracle.getNotes.mockResolvedValue([ - { - contractAddress, - storageSlot, - nonce, - preimage: [new Fr(amount), secret], - innerNoteHash, - siloedNullifier: new Fr(0), - index: 1n, - }, - ]); + oracle.getCommitmentIndex.mockResolvedValue(2n); const result = await runSimulator({ abi, - args: [amount, secret, recipient], + args: [amount, secret, recipient, nonce], }); // Check a nullifier has been inserted. @@ -751,20 +740,7 @@ describe('Private Execution test suite', () => { const storageSlot = new Fr(2); const innerNoteHash = hash([storageSlot.toBuffer(), noteHash.toBuffer()]); const siloedNoteHash = siloCommitment(wasm, contractAddress, Fr.fromBuffer(innerNoteHash)); - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should insert - // uniqueSiloedNoteHash in tree and that should be what is expected in Noir - //const uniqueSiloedNoteHash = computeUniqueCommitment(wasm, nonce, Fr.fromBuffer(innerNoteHash)); - - const tree = await insertLeaves([siloedNoteHash]); - - oracle.getCommitmentOracle.mockImplementation(async () => { - // Check the calculated commitment is correct - return Promise.resolve({ - commitment: siloedNoteHash, - siblingPath: (await tree.getSiblingPath(0n, false)).toFieldArray(), - index: 0n, - }); - }); + oracle.getCommitmentIndex.mockResolvedValue(0n); const result = await runSimulator({ abi, diff --git a/yarn-project/acir-simulator/src/client/private_execution.ts b/yarn-project/acir-simulator/src/client/private_execution.ts index 2e058c86852..1ee35591083 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.ts @@ -99,10 +99,12 @@ export class PrivateFunctionExecution { this.context.handleNewNote(this.contractAddress, storageSlot, preimage, innerNoteHash); return Promise.resolve(ZERO_ACVM_FIELD); }, - notifyNullifiedNote: async ([slot], [innerNullifier], [innerNoteHash]) => { - await this.context.handleNullifiedNote(this.contractAddress, slot, innerNullifier, innerNoteHash); + notifyNullifiedNote: async ([innerNullifier], [innerNoteHash]) => { + await this.context.handleNullifiedNote(this.contractAddress, innerNullifier, innerNoteHash); return Promise.resolve(ZERO_ACVM_FIELD); }, + checkNoteHashExists: ([nonce], [innerNoteHash]) => + this.context.checkNoteHashExists(this.contractAddress, nonce, innerNoteHash), callPrivateFunction: async ([acvmContractAddress], [acvmFunctionSelector], [acvmArgsHash]) => { const contractAddress = fromACVMField(acvmContractAddress); const functionSelector = fromACVMField(acvmFunctionSelector); @@ -125,7 +127,6 @@ export class PrivateFunctionExecution { getL1ToL2Message: ([msgKey]) => { return this.context.getL1ToL2Message(fromACVMField(msgKey)); }, - getCommitment: ([commitment]) => this.context.getCommitment(this.contractAddress, commitment), debugLog: (...args) => { this.log(oracleDebugCallToFormattedStr(args)); return Promise.resolve(ZERO_ACVM_FIELD); diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts index f11c95d4c70..4a1d8fc89c3 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts @@ -72,13 +72,14 @@ export class UnconstrainedFunctionExecution { +offset, +returnSize, ), + checkNoteHashExists: ([nonce], [innerNoteHash]) => + this.context.checkNoteHashExists(this.contractAddress, nonce, innerNoteHash), getRandomField: () => Promise.resolve(toACVMField(Fr.random())), debugLog: (...params) => { this.log(oracleDebugCallToFormattedStr(params)); return Promise.resolve(ZERO_ACVM_FIELD); }, getL1ToL2Message: ([msgKey]) => this.context.getL1ToL2Message(fromACVMField(msgKey)), - getCommitment: ([commitment]) => this.context.getCommitment(this.contractAddress, commitment), storageRead: async ([slot], [numberOfElements]) => { if (!aztecNode) { const errMsg = `Aztec node is undefined, cannot read storage`; diff --git a/yarn-project/acir-simulator/src/public/db.ts b/yarn-project/acir-simulator/src/public/db.ts index bc79cb17b76..245c3f103c7 100644 --- a/yarn-project/acir-simulator/src/public/db.ts +++ b/yarn-project/acir-simulator/src/public/db.ts @@ -2,7 +2,7 @@ import { EthAddress, FunctionSelector } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { CommitmentDataOracleInputs, MessageLoadOracleInputs } from '../index.js'; +import { MessageLoadOracleInputs } from '../index.js'; /** * Database interface for providing access to public state. @@ -65,10 +65,9 @@ export interface CommitmentsDB { getL1ToL2Message(msgKey: Fr): Promise; /** - * Gets a message index and sibling path to some commitment in the private data tree. - * @param address - The contract address owning storage. - * @param commitment - The preimage of the siloed data. - * @returns - The Commitment data oracle object + * Gets the index of a commitment in the private data tree. + * @param commitment - The commitment. + * @returns - The index of the commitment. Undefined if it does not exist in the tree. */ - getCommitmentOracle(address: AztecAddress, commitment: Fr): Promise; + getCommitmentIndex(commitment: Fr): Promise; } diff --git a/yarn-project/acir-simulator/src/public/executor.ts b/yarn-project/acir-simulator/src/public/executor.ts index 4d8fe6da158..ca1451771dd 100644 --- a/yarn-project/acir-simulator/src/public/executor.ts +++ b/yarn-project/acir-simulator/src/public/executor.ts @@ -1,6 +1,7 @@ import { AztecAddress, CallContext, + CircuitsWasm, EthAddress, Fr, FunctionData, @@ -9,11 +10,13 @@ import { HistoricBlockData, RETURN_VALUES_LENGTH, } from '@aztec/circuits.js'; +import { siloCommitment } from '@aztec/circuits.js/abis'; import { padArrayEnd } from '@aztec/foundation/collection'; import { createDebugLogger } from '@aztec/foundation/log'; import { FunctionL2Logs } from '@aztec/types'; import { + ONE_ACVM_FIELD, ZERO_ACVM_FIELD, acvm, convertACVMFieldToBuffer, @@ -23,7 +26,6 @@ import { fromACVMField, toACVMField, toACVMWitness, - toAcvmCommitmentLoadOracleInputs, toAcvmL1ToL2MessageLoadOracleInputs, } from '../acvm/index.js'; import { oracleDebugCallToFormattedStr } from '../client/debug.js'; @@ -91,12 +93,14 @@ export class PublicExecutor { const messageInputs = await this.commitmentsDb.getL1ToL2Message(fromACVMField(msgKey)); return toAcvmL1ToL2MessageLoadOracleInputs(messageInputs, this.blockData.l1ToL2MessagesTreeRoot); }, // l1 to l2 messages in public contexts TODO: https://github.com/AztecProtocol/aztec-packages/issues/616 - getCommitment: async ([commitment]) => { - const commitmentInputs = await this.commitmentsDb.getCommitmentOracle( - execution.contractAddress, - fromACVMField(commitment), - ); - return toAcvmCommitmentLoadOracleInputs(commitmentInputs, this.blockData.privateDataTreeRoot); + checkNoteHashExists: async ([_nonce], [innerNoteHash]) => { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) + // Once public kernel or base rollup circuit injects nonces, this can be updated to use uniqueSiloedCommitment. + const wasm = await CircuitsWasm.get(); + const siloedNoteHash = siloCommitment(wasm, execution.contractAddress, fromACVMField(innerNoteHash)); + const index = await this.commitmentsDb.getCommitmentIndex(siloedNoteHash); + // return 0 or 1 for whether note hash exists + return index === undefined ? ZERO_ACVM_FIELD : ONE_ACVM_FIELD; }, storageRead: async ([slot], [numberOfElements]) => { const startStorageSlot = fromACVMField(slot); diff --git a/yarn-project/aztec-rpc/src/simulator_oracle/index.ts b/yarn-project/aztec-rpc/src/simulator_oracle/index.ts index 52737d91a42..68309243747 100644 --- a/yarn-project/aztec-rpc/src/simulator_oracle/index.ts +++ b/yarn-project/aztec-rpc/src/simulator_oracle/index.ts @@ -1,12 +1,6 @@ -import { - CommitmentDataOracleInputs, - DBOracle, - FunctionAbiWithDebugMetadata, - MessageLoadOracleInputs, -} from '@aztec/acir-simulator'; +import { DBOracle, FunctionAbiWithDebugMetadata, MessageLoadOracleInputs } from '@aztec/acir-simulator'; import { AztecAddress, - CircuitsWasm, CompleteAddress, EthAddress, Fr, @@ -15,7 +9,6 @@ import { HistoricBlockData, PublicKey, } from '@aztec/circuits.js'; -import { siloCommitment } from '@aztec/circuits.js/abis'; import { DataCommitmentProvider, KeyStore, L1ToL2MessageProvider } from '@aztec/types'; import { ContractDataOracle } from '../contract_data_oracle/index.js'; @@ -105,23 +98,12 @@ export class SimulatorOracle implements DBOracle { } /** - * Retrieves the noir oracle data required to prove existence of a given commitment. - * @param contractAddress - The contract Address. - * @param innerCommitment - The key of the message being fetched. - * @returns - A promise that resolves to the commitment data, a sibling path and the - * index of the message in the private data tree. + * Gets the index of a commitment in the private data tree. + * @param commitment - The commitment. + * @returns - The index of the commitment. Undefined if it does not exist in the tree. */ - async getCommitmentOracle(contractAddress: AztecAddress, innerCommitment: Fr): Promise { - const siloedCommitment = siloCommitment(await CircuitsWasm.get(), contractAddress, innerCommitment); - const index = await this.dataTreeProvider.findCommitmentIndex(siloedCommitment.toBuffer()); - if (!index) throw new Error(`Commitment not found ${siloedCommitment.toString()}`); - - const siblingPath = await this.dataTreeProvider.getDataTreePath(index); - return await Promise.resolve({ - commitment: siloedCommitment, - siblingPath: siblingPath.toFieldArray(), - index, - }); + async getCommitmentIndex(commitment: Fr) { + return await this.dataTreeProvider.findCommitmentIndex(commitment.toBuffer()); } /** diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/actions.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/actions.nr index ff8e77a10b6..94b5981e1f3 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/actions.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/actions.nr @@ -148,9 +148,10 @@ unconstrained fn get_total_points( // docs:start:state_vars-SetContains fn assert_contains_card( state_var: Set, - card: CardNote, + card: &mut CardNote, + nonce: Field, ) { - state_var.assert_contains_and_remove(card); + state_var.assert_contains_and_remove(card, nonce); } // docs:end:state_vars-SetContains diff --git a/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr index ba2bc64737a..31dc5e610e5 100644 --- a/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr @@ -348,10 +348,10 @@ contract NativeToken { let storage = Storage::init(Context::private(&mut context)); let pending_shields = storage.pending_shields; - let public_note = TransparentNote::new_from_secret(amount, secret); + let mut public_note = TransparentNote::new_from_secret(amount, secret); // Ensure that the note exists in the tree and remove it. - pending_shields.assert_contains_and_remove_publicly_created(public_note); + pending_shields.assert_contains_and_remove_publicly_created(&mut public_note); // Mint the tokens let balance = storage.balances.at(owner); diff --git a/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr index a9fb5b021ba..719f262b505 100644 --- a/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr @@ -248,10 +248,10 @@ contract NonNativeToken { let storage = Storage::init(Context::private(&mut context)); let pending_shields = storage.pending_shields; - let public_note = TransparentNote::new_from_secret(amount, secret); + let mut public_note = TransparentNote::new_from_secret(amount, secret); // Ensure that the note exists in the tree and remove it. - pending_shields.assert_contains_and_remove_publicly_created(public_note); + pending_shields.assert_contains_and_remove_publicly_created(&mut public_note); // Mint the tokens let balance = storage.balances.at(owner); diff --git a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/interface.nr b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/interface.nr index 6c8a95fb33a..ff54645fa31 100644 --- a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/interface.nr +++ b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/interface.nr @@ -59,14 +59,16 @@ impl PrivateTokenAirdropPrivateContextInterface { context: &mut PrivateContext, amount: Field, secret: Field, - owner: Field + owner: Field, + nonce: Field ) -> [Field; RETURN_VALUES_LENGTH] { - let mut serialised_args = [0; 3]; + let mut serialised_args = [0; 4]; serialised_args[0] = amount; serialised_args[1] = secret; serialised_args[2] = owner; + serialised_args[3] = nonce; - context.call_private_function(self.address, 0xd68b55c1, serialised_args) + context.call_private_function(self.address, 0xa9220f0f, serialised_args) } diff --git a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr index 2216e36ecba..c7eac5d9d4b 100644 --- a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr @@ -160,13 +160,14 @@ contract PrivateTokenAirdrop { fn claim( amount: Field, secret: Field, - owner: Field + owner: Field, + nonce: Field, ) { let storage = Storage::init(Context::private(&mut context)); // Remove the claim note if it exists in the set. - let note = ClaimNote::new(amount, secret); - storage.claims.assert_contains_and_remove(note); + let mut note = ClaimNote::new(amount, secret); + storage.claims.assert_contains_and_remove(&mut note, nonce); // Send the value note. let balance = storage.balances.at(owner); diff --git a/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr index 677998e7d1e..b676bea7962 100644 --- a/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr @@ -244,9 +244,9 @@ contract Token { let storage = Storage::init(Context::private(&mut context)); let pending_shields = storage.pending_shields; let balance = storage.balances.at(to.address); - let public_note = TransparentNote::new_from_secret(amount, secret); + let mut public_note = TransparentNote::new_from_secret(amount, secret); - pending_shields.assert_contains_and_remove_publicly_created(public_note); + pending_shields.assert_contains_and_remove_publicly_created(&mut public_note); increment(balance, amount, to.address); 1 diff --git a/yarn-project/noir-libs/aztec-noir/src/messaging.nr b/yarn-project/noir-libs/aztec-noir/src/messaging.nr index c9ee3be0a3e..8f41c29c943 100644 --- a/yarn-project/noir-libs/aztec-noir/src/messaging.nr +++ b/yarn-project/noir-libs/aztec-noir/src/messaging.nr @@ -1,4 +1,3 @@ -mod get_commitment_getter_data; mod l1_to_l2_message; mod l1_to_l2_message_getter_data; diff --git a/yarn-project/noir-libs/aztec-noir/src/messaging/get_commitment_getter_data.nr b/yarn-project/noir-libs/aztec-noir/src/messaging/get_commitment_getter_data.nr deleted file mode 100644 index 07d826d41d7..00000000000 --- a/yarn-project/noir-libs/aztec-noir/src/messaging/get_commitment_getter_data.nr +++ /dev/null @@ -1,15 +0,0 @@ -use crate::oracle::get_commitment::COMMITMENT_GETTER_LENGTH; - -struct CommitmentGetterData { - message: Field, - leaf_index: Field, - root: Field, -} - -fn make_commitment_getter_data(fields: [Field; COMMITMENT_GETTER_LENGTH], start: Field) -> CommitmentGetterData { - CommitmentGetterData { - message: fields[start], - leaf_index: fields[start + 1], - root: fields[start + 2], - } -} \ No newline at end of file diff --git a/yarn-project/noir-libs/aztec-noir/src/note/lifecycle.nr b/yarn-project/noir-libs/aztec-noir/src/note/lifecycle.nr index b6e530ed94f..43ccdfad556 100644 --- a/yarn-project/noir-libs/aztec-noir/src/note/lifecycle.nr +++ b/yarn-project/noir-libs/aztec-noir/src/note/lifecycle.nr @@ -50,7 +50,6 @@ fn create_note_hash_from_public( fn destroy_note( context: &mut PrivateContext, - storage_slot: Field, note: Note, note_interface: NoteInterface, ) { @@ -72,7 +71,7 @@ fn destroy_note( // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`? nullified_commitment = compute_inner_note_hash(note_interface, note); } - assert(notify_nullified_note(storage_slot, nullifier, nullified_commitment) == 0); + assert(notify_nullified_note(nullifier, nullified_commitment) == 0); context.push_new_nullifier(nullifier, nullified_commitment) } \ No newline at end of file diff --git a/yarn-project/noir-libs/aztec-noir/src/note/note_getter.nr b/yarn-project/noir-libs/aztec-noir/src/note/note_getter.nr index ee407657547..808f9389b3a 100644 --- a/yarn-project/noir-libs/aztec-noir/src/note/note_getter.nr +++ b/yarn-project/noir-libs/aztec-noir/src/note/note_getter.nr @@ -13,11 +13,9 @@ use crate::note::{ note_header::NoteHeader, note_viewer_options::NoteViewerOptions, utils::compute_note_hash_for_read_or_nullify, - utils::compute_unique_siloed_note_hash, utils::compute_inner_note_hash, utils::compute_siloed_note_hash, }; -use crate::messaging::get_commitment_getter_data::make_commitment_getter_data; use crate::oracle; use crate::types::vec::BoundedVec; @@ -34,69 +32,29 @@ fn check_note_header( assert(header.storage_slot == storage_slot); } -fn ensure_note_exists( - context: &mut PrivateContext, - storage_slot: Field, - note_interface: NoteInterface, - note: &mut Note, -) { - let saved_note = get_note_internal(storage_slot, note_interface); - - // Only copy over the header to the original note to make sure the preimage is the same. - let get_header = note_interface.get_header; - let set_header = note_interface.set_header; - let note_header = get_header(saved_note); - set_header(note, note_header); - - check_note_header(*context, storage_slot, note_interface, *note); - - let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, *note); - context.push_read_request(note_hash_for_read_request); -} - // Ensure a note's hash exists in the tree without retrieving the entire // notes via the oracle. -// Modifies the note by populating it with header info. fn ensure_note_hash_exists( context: &mut PrivateContext, - storage_slot: Field, note_interface: NoteInterface, - note: &mut Note, + note: Note, + from_public: bool, ) { - // Initialize header of note. Must be done before computing note hashes as it initializes the: - // - storage slot (used in inner note hash) - // - the contract address (used in siloed note hash) - // - and the nonce (used in the unique siloed note hash) - let set_header = note_interface.set_header; - let note_header = NoteHeader { - contract_address: (*context).this_address(), - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should be - // real nonce (once public kernel applies nonces). - nonce: 0, - storage_slot - }; - set_header(note, note_header); - - // Get a note from oracle and early out if it doesn't exist. - let inner_note_hash = compute_inner_note_hash(note_interface, *note); - - let raw_oracle_ret = oracle::get_commitment::get_commitment(inner_note_hash); - let deserialized_oracle_ret = make_commitment_getter_data(raw_oracle_ret, 0); - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should be - // unique_siloed_note_hash once public kernel applies nonces - let saved_siloed_note_hash = deserialized_oracle_ret.message; - - assert(saved_siloed_note_hash != 0); // TODO(dbanks12): necessary? - - check_note_header(*context, storage_slot, note_interface, *note); - - // Ensure that the note hash retrieved from oracle matches the one computed from note. - let computed_siloed_note_hash = compute_siloed_note_hash(note_interface, *note); - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): should be - // compute_note_hash_for_read_or_nullify once public kernel applies nonces - assert(computed_siloed_note_hash == saved_siloed_note_hash); + let get_header = note_interface.get_header; + let header = get_header(note); - context.push_read_request(computed_siloed_note_hash); + // Check the note hash via oracle and early out if it doesn't exist. + let inner_note_hash = compute_inner_note_hash(note_interface, note); + let exists = oracle::notes::check_note_hash_exists(header.nonce, inner_note_hash); + assert(exists, "Note hash does not exist."); + + let mut note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note); + if from_public { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) + // Should remove this once public kernel applies nonces. + note_hash_for_read_request = compute_siloed_note_hash(note_interface, note); + } + context.push_read_request(note_hash_for_read_request); } fn get_note( diff --git a/yarn-project/noir-libs/aztec-noir/src/oracle.nr b/yarn-project/noir-libs/aztec-noir/src/oracle.nr index 056617ed42f..da760abf487 100644 --- a/yarn-project/noir-libs/aztec-noir/src/oracle.nr +++ b/yarn-project/noir-libs/aztec-noir/src/oracle.nr @@ -6,7 +6,6 @@ mod arguments; mod call_private_function; mod context; mod debug_log; -mod get_commitment; mod get_l1_to_l2_message; mod get_public_key; mod get_secret_key; diff --git a/yarn-project/noir-libs/aztec-noir/src/oracle/get_commitment.nr b/yarn-project/noir-libs/aztec-noir/src/oracle/get_commitment.nr deleted file mode 100644 index 2793c003bf6..00000000000 --- a/yarn-project/noir-libs/aztec-noir/src/oracle/get_commitment.nr +++ /dev/null @@ -1,11 +0,0 @@ -// Oracle function to get a commitment, its sibling path and index, without getting its preimage. - -// commitment + index + root; -global COMMITMENT_GETTER_LENGTH = 3; - -#[oracle(getCommitment)] -fn get_commitment_oracle(_commitment: Field) -> [Field; COMMITMENT_GETTER_LENGTH] {} - -unconstrained fn get_commitment(commitment: Field) -> [Field; COMMITMENT_GETTER_LENGTH] { - get_commitment_oracle(commitment) -} diff --git a/yarn-project/noir-libs/aztec-noir/src/oracle/notes.nr b/yarn-project/noir-libs/aztec-noir/src/oracle/notes.nr index 52d4a445389..356cf5de4aa 100644 --- a/yarn-project/noir-libs/aztec-noir/src/oracle/notes.nr +++ b/yarn-project/noir-libs/aztec-noir/src/oracle/notes.nr @@ -22,17 +22,28 @@ unconstrained fn notify_created_note( #[oracle(notifyNullifiedNote)] fn notify_nullified_note_oracle( - _storage_slot: Field, _nullifier: Field, _inner_note_hash: Field, ) -> Field {} unconstrained fn notify_nullified_note( - storage_slot: Field, nullifier: Field, inner_note_hash: Field, ) -> Field { - notify_nullified_note_oracle(storage_slot, nullifier, inner_note_hash) + notify_nullified_note_oracle(nullifier, inner_note_hash) +} + +#[oracle(checkNoteHashExists)] +fn check_note_hash_exists_oracle( + _nonce: Field, + _inner_note_hash: Field, +) -> Field {} + +unconstrained fn check_note_hash_exists( + nonce: Field, + inner_note_hash: Field, +) -> bool { + check_note_hash_exists_oracle(nonce, inner_note_hash) == 1 } #[oracle(getNotes)] diff --git a/yarn-project/noir-libs/aztec-noir/src/state_vars/set.nr b/yarn-project/noir-libs/aztec-noir/src/state_vars/set.nr index c14eebb770d..698af2ef11c 100644 --- a/yarn-project/noir-libs/aztec-noir/src/state_vars/set.nr +++ b/yarn-project/noir-libs/aztec-noir/src/state_vars/set.nr @@ -4,8 +4,9 @@ use crate::constants_gen::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL}; use crate::context::{PrivateContext, PublicContext, Context}; use crate::note::{ lifecycle::{create_note, create_note_hash_from_public, destroy_note}, - note_getter::{ensure_note_exists, ensure_note_hash_exists, get_notes, view_notes}, + note_getter::{ensure_note_hash_exists, get_notes, view_notes}, note_getter_options::NoteGetterOptions, + note_header::NoteHeader, note_interface::NoteInterface, note_viewer_options::NoteViewerOptions, utils::compute_note_hash_for_read_or_nullify, @@ -49,64 +50,79 @@ impl Set { ); } - fn assert_contains_and_remove(self, note: Note) { - let mut note_with_header = note; - // TODO(1386): replace with `ensure_note_hash_exists` - // once `get_commitment` works for privately created note hashes - ensure_note_exists( - self.context.private.unwrap(), - self.storage_slot, + fn assert_contains_and_remove(self, note: &mut Note, nonce: Field) { + // Initialize header of note. Must be done before computing note hashes as it initializes the: + // - storage slot (used in inner note hash) + // - the contract address (used in siloed note hash) + // - and the nonce (used in the unique siloed note hash) + let context = self.context.private.unwrap(); + let set_header = self.note_interface.set_header; + let note_header = NoteHeader{ + contract_address: context.this_address(), + storage_slot: self.storage_slot, + nonce + }; + set_header(note, note_header); + + ensure_note_hash_exists( + context, self.note_interface, - &mut note_with_header, + *note, + false, ); + destroy_note( - self.context.private.unwrap(), - self.storage_slot, - note_with_header, + context, + *note, self.note_interface, ); } // NOTE: this function should ONLY be used for PUBLICLY-CREATED note hashes! - // WARNING: function will be deprecated/removed eventually once `assert_contains_and_remove` - // works for publicly-created note hashes as well. - fn assert_contains_and_remove_publicly_created(self, note: Note) { - let mut note_with_header = note; - // Modifies note with the header which is necessary for the next step (remove). + // WARNING: function will be deprecated/removed eventually once public kernel applies nonces. + fn assert_contains_and_remove_publicly_created(self, note: &mut Note) { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) + // Should be real nonce (once public kernel applies nonces). + let nonce = 0; + let context = self.context.private.unwrap(); + let set_header = self.note_interface.set_header; + let mut note_header = NoteHeader{ + contract_address: context.this_address(), + storage_slot: self.storage_slot, + nonce + }; + set_header(note, note_header); + ensure_note_hash_exists( - self.context.private.unwrap(), - self.storage_slot, + context, self.note_interface, - &mut note_with_header, + *note, + true, ); - let get_header = self.note_interface.get_header; - let set_header = self.note_interface.set_header; - let mut header = get_header(note); // Set the nonce to nonzero so that the nullifier is treated as persistable // (non-transient) and so the private kernel does not attempt to match it to // a pending noteHash/commitment and squash them. // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): remove // this hack once public kernel injects nonces. - header.nonce = 1; - set_header(&mut note_with_header, header); + note_header.nonce = 1; + set_header(note, note_header); + destroy_note( - self.context.private.unwrap(), - self.storage_slot, - note_with_header, + context, + *note, self.note_interface, ); } fn remove(self, note: Note) { + let context = self.context.private.unwrap(); let note_hash = compute_note_hash_for_read_or_nullify(self.note_interface, note); - let read_requests = self.context.private.unwrap_unchecked().read_requests; - let has_been_read = read_requests.any(|r| r == note_hash); + let has_been_read = context.read_requests.any(|r| r == note_hash); assert(has_been_read, "Can only remove a note that has been read from the set."); destroy_note( - self.context.private.unwrap(), - self.storage_slot, + context, note, self.note_interface, ); diff --git a/yarn-project/noir-libs/aztec-noir/src/state_vars/singleton.nr b/yarn-project/noir-libs/aztec-noir/src/state_vars/singleton.nr index e1033604995..6b7afcba2ce 100644 --- a/yarn-project/noir-libs/aztec-noir/src/state_vars/singleton.nr +++ b/yarn-project/noir-libs/aztec-noir/src/state_vars/singleton.nr @@ -56,7 +56,7 @@ impl Singleton { let prev_note = get_note(context, self.storage_slot, self.note_interface); // Nullify previous note. - destroy_note(context, self.storage_slot, prev_note, self.note_interface); + destroy_note(context, prev_note, self.note_interface); // Add replacement note. create_note(context, self.storage_slot, new_note, self.note_interface); @@ -67,7 +67,7 @@ impl Singleton { let mut note = get_note(context, self.storage_slot, self.note_interface); // Nullify current note to make sure it's reading the latest note. - destroy_note(context, self.storage_slot, note, self.note_interface); + destroy_note(context, note, self.note_interface); // Add the same note again. // Because a nonce is added to every note in the kernel, its nullifier will be different. diff --git a/yarn-project/sequencer-client/src/simulator/public_executor.ts b/yarn-project/sequencer-client/src/simulator/public_executor.ts index bef534b6228..1296dcae50a 100644 --- a/yarn-project/sequencer-client/src/simulator/public_executor.ts +++ b/yarn-project/sequencer-client/src/simulator/public_executor.ts @@ -1,5 +1,4 @@ import { - CommitmentDataOracleInputs, CommitmentsDB, MessageLoadOracleInputs, PublicContractsDB, @@ -7,7 +6,6 @@ import { PublicStateDB, } from '@aztec/acir-simulator'; import { AztecAddress, CircuitsWasm, EthAddress, Fr, FunctionSelector, HistoricBlockData } from '@aztec/circuits.js'; -import { siloCommitment } from '@aztec/circuits.js/abis'; import { ContractDataSource, L1ToL2MessageSource, MerkleTreeId } from '@aztec/types'; import { MerkleTreeOperations, computePublicDataTreeLeafIndex } from '@aztec/world-state'; @@ -100,19 +98,7 @@ export class WorldStateDB implements CommitmentsDB { }; } - public async getCommitmentOracle(address: AztecAddress, innerCommitment: Fr): Promise { - const siloedCommitment = siloCommitment(await CircuitsWasm.get(), address, innerCommitment); - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386): shoild be - // unique commitment that exists in tree (should be siloed and then made unique via - // nonce). Once public kernel or base rollup circuit injects nonces, this can be updated - // to use uniqueSiloedCommitment. - const index = (await this.db.findLeafIndex(MerkleTreeId.PRIVATE_DATA_TREE, siloedCommitment.toBuffer()))!; - const siblingPath = await this.db.getSiblingPath(MerkleTreeId.PRIVATE_DATA_TREE, index); - - return { - commitment: siloedCommitment, - siblingPath: siblingPath.toFieldArray(), - index, - }; + public async getCommitmentIndex(commitment: Fr): Promise { + return await this.db.findLeafIndex(MerkleTreeId.PRIVATE_DATA_TREE, commitment.toBuffer()); } }