diff --git a/yarn-project/pxe/src/contract_function_simulator/pxe_oracle_interface.ts b/yarn-project/pxe/src/contract_function_simulator/pxe_oracle_interface.ts index ac081286b970..f53a5e4f0a04 100644 --- a/yarn-project/pxe/src/contract_function_simulator/pxe_oracle_interface.ts +++ b/yarn-project/pxe/src/contract_function_simulator/pxe_oracle_interface.ts @@ -641,12 +641,13 @@ export class PXEOracleInterface implements ExecutionDataProvider { const siloedNullifier = await siloNullifier(contractAddress, nullifier); // We store notes by their index in the global note hash tree, which has the convenient side effect of validating - // note existence in said tree. - const [uniqueNoteHashTreeIndexInBlock] = await this.aztecNode.findLeavesIndexes( - syncedBlockNumber, - MerkleTreeId.NOTE_HASH_TREE, - [uniqueNoteHash], - ); + // note existence in said tree. We concurrently also check if the note's nullifier exists, performing all node + // queries in a single round-trip. + const [[uniqueNoteHashTreeIndexInBlock], [nullifierIndex]] = await Promise.all([ + this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NOTE_HASH_TREE, [uniqueNoteHash]), + this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NULLIFIER_TREE, [siloedNullifier]), + ]); + if (uniqueNoteHashTreeIndexInBlock === undefined) { throw new Error( `Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present on the tree at block ${syncedBlockNumber} (from tx ${txHash})`, @@ -676,9 +677,6 @@ export class PXEOracleInterface implements ExecutionDataProvider { nullifier: noteDao.siloedNullifier.toString(), }); - const [nullifierIndex] = await this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NULLIFIER_TREE, [ - siloedNullifier, - ]); if (nullifierIndex !== undefined) { const { data: _, ...blockHashAndNum } = nullifierIndex; await this.noteDataProvider.removeNullifiedNotes([{ data: siloedNullifier, ...blockHashAndNum }], recipient);