From 62c6a6e5d187afe67b61fd8635394054db725a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 30 May 2025 19:52:58 +0000 Subject: [PATCH] feat: validate notes in a single node roundtrip --- .../pxe_oracle_interface/pxe_oracle_interface.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/yarn-project/pxe/src/pxe_oracle_interface/pxe_oracle_interface.ts b/yarn-project/pxe/src/pxe_oracle_interface/pxe_oracle_interface.ts index ea729ad43f3a..2eb162805408 100644 --- a/yarn-project/pxe/src/pxe_oracle_interface/pxe_oracle_interface.ts +++ b/yarn-project/pxe/src/pxe_oracle_interface/pxe_oracle_interface.ts @@ -640,12 +640,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})`, @@ -675,9 +676,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);