From 8c596e5613d78c31dfac5fbf77ab389aadf38618 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 11 Dec 2023 16:05:29 +0000 Subject: [PATCH 1/4] WIP --- .../acir-simulator/src/acvm/oracle/oracle.ts | 10 ++++++++++ .../acir-simulator/src/acvm/oracle/typed_oracle.ts | 4 ++++ .../acir-simulator/src/client/view_data_oracle.ts | 10 ++++++++++ .../aztec-nr/aztec/src/oracle/get_block_header.nr | 12 ++++++------ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts index 87a32f072c0f..9e8e922cefc8 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts @@ -119,6 +119,16 @@ export class Oracle { return blockHeader.toArray().map(toACVMField); } + async getBlockHeaderBlockNumber([nullifierTreeRoot]: ACVMField[]): Promise { + const parsedRoot = fromACVMField(nullifierTreeRoot); + + const blockHeaderBlockNumber = await this.typedOracle.getBlockHeaderBlockNumber(parsedRoot); + if (!blockHeaderBlockNumber) { + throw new Error(`Block header not found for block ${parsedRoot}.`); + } + return [toACVMField(blockHeaderBlockNumber)]; + } + async getAuthWitness([messageHash]: ACVMField[]): Promise { const messageHashField = fromACVMField(messageHash); const witness = await this.typedOracle.getAuthWitness(messageHashField); diff --git a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts index 7013689a8ca3..6759392232cb 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts @@ -106,6 +106,10 @@ export abstract class TypedOracle { throw new Error('Not available.'); } + getBlockHeaderBlockNumber(_nullifierTreeRoot: Fr): Promise { + throw new Error('Not available.'); + } + getCompleteAddress(_address: AztecAddress): Promise { throw new Error('Not available.'); } diff --git a/yarn-project/acir-simulator/src/client/view_data_oracle.ts b/yarn-project/acir-simulator/src/client/view_data_oracle.ts index 8a1c22587379..a6337a3d1297 100644 --- a/yarn-project/acir-simulator/src/client/view_data_oracle.ts +++ b/yarn-project/acir-simulator/src/client/view_data_oracle.ts @@ -113,6 +113,16 @@ export class ViewDataOracle extends TypedOracle { ); } + /** + * Gets number of a given block header based on the nullifier tree root which was contained in it. + * @remarks Using nullifier tree root because that changes in every block (every tx emits a nullifier). + * @param nullifierTreeRoot - The nullifier tree root of block header to get the block number for. + * @returns The block number of the block header. + */ + public async getBlockHeaderBlockNumber(nullifierTreeRoot: Fr): Promise { + // TODO + } + /** * Retrieve the complete address associated to a given address. * @param address - Address to fetch the complete address for. diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr index 9d15d693393c..1baa4239d528 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr @@ -13,6 +13,10 @@ use crate::{ }, }; +// TODO(#3564) - Nuke this oracle and Inject the number directly to context +#[oracle(getBlockHeaderBlockNumber)] +fn get_block_header_block_number(nullifier_tree_root: Field) -> Field {} + #[oracle(getBlockHeader)] fn get_block_header_oracle(_block_number: Field) -> [Field; BLOCK_HEADER_LENGTH] {} @@ -31,12 +35,8 @@ pub fn get_block_header(block_number: Field, context: PrivateContext) -> BlockHe // 3) Get the membership witness of the block in the archive let archive_id = 5; // TODO(#3443) - // Using `block_number` here for path is incorrect and it will break if we pass in an incorrect block number on input. - // Instead here should be the block number corresponding to `context.block_header.blocks_tree_root` - // This is not currently available in private context. See issue #3564 - let path_block_number = block_number; - - let witness: MembershipWitness = get_membership_witness(path_block_number, archive_id, block_hash); + let block_header_block_number = get_block_header_block_number(context.block_header.nullifier_tree_root); + let witness: MembershipWitness = get_membership_witness(block_header_block_number, archive_id, block_hash); // 4) Check that the block is in the archive (i.e. the witness is valid) assert(context.block_header.archive_root == compute_merkle_root(block_hash, witness.index, witness.path), "Proving membership of a block in archive failed"); From 3826f7884602e5ac4138bfef65fd1107776c5536 Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 12 Dec 2023 08:47:41 +0000 Subject: [PATCH 2/4] WIP --- .../acir-simulator/src/acvm/oracle/oracle.ts | 9 ++--- .../src/acvm/oracle/typed_oracle.ts | 3 +- .../acir-simulator/src/client/db_oracle.ts | 6 ++++ .../src/client/view_data_oracle.ts | 35 +++++++++++++++---- .../aztec/src/oracle/get_block_header.nr | 11 ++++-- .../pxe/src/simulator_oracle/index.ts | 8 +++++ .../types/src/interfaces/aztec-node.ts | 6 ---- .../src/interfaces/state_info_provider.ts | 6 ++++ 8 files changed, 63 insertions(+), 21 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts index 9e8e922cefc8..5b93133e4060 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts @@ -119,14 +119,15 @@ export class Oracle { return blockHeader.toArray().map(toACVMField); } - async getBlockHeaderBlockNumber([nullifierTreeRoot]: ACVMField[]): Promise { + // TODO(#3564) - Nuke this oracle and inject the number directly to context + async getNullifierRootBlockNumber([nullifierTreeRoot]: ACVMField[]): Promise { const parsedRoot = fromACVMField(nullifierTreeRoot); - const blockHeaderBlockNumber = await this.typedOracle.getBlockHeaderBlockNumber(parsedRoot); - if (!blockHeaderBlockNumber) { + const blockNumber = await this.typedOracle.getNullifierRootBlockNumber(parsedRoot); + if (!blockNumber) { throw new Error(`Block header not found for block ${parsedRoot}.`); } - return [toACVMField(blockHeaderBlockNumber)]; + return toACVMField(blockNumber); } async getAuthWitness([messageHash]: ACVMField[]): Promise { diff --git a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts index 6759392232cb..556da1bebf8d 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts @@ -106,7 +106,8 @@ export abstract class TypedOracle { throw new Error('Not available.'); } - getBlockHeaderBlockNumber(_nullifierTreeRoot: Fr): Promise { + // TODO(#3564) - Nuke this oracle and inject the number directly to context + getNullifierRootBlockNumber(_nullifierTreeRoot: Fr): Promise { throw new Error('Not available.'); } diff --git a/yarn-project/acir-simulator/src/client/db_oracle.ts b/yarn-project/acir-simulator/src/client/db_oracle.ts index 6ed7a6a8e6a1..5d866dac224b 100644 --- a/yarn-project/acir-simulator/src/client/db_oracle.ts +++ b/yarn-project/acir-simulator/src/client/db_oracle.ts @@ -159,4 +159,10 @@ export interface DBOracle extends CommitmentsDB { * @returns - The block corresponding to the given block number. Undefined if it does not exist. */ getBlock(blockNumber: number): Promise; + + /** + * Fetches the current block number. + * @returns The block number. + */ + getBlockNumber(): Promise; } diff --git a/yarn-project/acir-simulator/src/client/view_data_oracle.ts b/yarn-project/acir-simulator/src/client/view_data_oracle.ts index a6337a3d1297..1edcfe3998b1 100644 --- a/yarn-project/acir-simulator/src/client/view_data_oracle.ts +++ b/yarn-project/acir-simulator/src/client/view_data_oracle.ts @@ -3,7 +3,14 @@ import { computeGlobalsHash, siloNullifier } from '@aztec/circuits.js/abis'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { AuthWitness, AztecNode, CompleteAddress, MerkleTreeId, NullifierMembershipWitness } from '@aztec/types'; +import { + AuthWitness, + AztecNode, + CompleteAddress, + INITIAL_L2_BLOCK_NUM, + MerkleTreeId, + NullifierMembershipWitness, +} from '@aztec/types'; import { NoteData, TypedOracle } from '../acvm/index.js'; import { DBOracle } from './db_oracle.js'; @@ -114,13 +121,27 @@ export class ViewDataOracle extends TypedOracle { } /** - * Gets number of a given block header based on the nullifier tree root which was contained in it. - * @remarks Using nullifier tree root because that changes in every block (every tx emits a nullifier). - * @param nullifierTreeRoot - The nullifier tree root of block header to get the block number for. - * @returns The block number of the block header. + * Gets number of a block in which a given nullifier tree root was included. + * @param nullifierTreeRoot - The nullifier tree root to get the block number for. + * @returns The block number. + * + * TODO(#3564) - Nuke this oracle and inject the number directly to context */ - public async getBlockHeaderBlockNumber(nullifierTreeRoot: Fr): Promise { - // TODO + public async getNullifierRootBlockNumber(nullifierTreeRoot: Fr): Promise { + const currentBlockNumber = await this.db.getBlockNumber(); + for (let i = currentBlockNumber; i >= INITIAL_L2_BLOCK_NUM; i -= 2) { + const block = await this.db.getBlock(i); + if (!block) { + throw new Error(`Block ${i} not found`); + } + if (block.endNullifierTreeSnapshot.root.equals(nullifierTreeRoot)) { + return i; + } + if (block.startNullifierTreeSnapshot.root.equals(nullifierTreeRoot)) { + return i - 1; + } + } + throw new Error(`Failed to find block containing nullifier tree root ${nullifierTreeRoot}`); } /** diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr index 1baa4239d528..a07a4d59a49d 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr @@ -14,8 +14,12 @@ use crate::{ }; // TODO(#3564) - Nuke this oracle and Inject the number directly to context -#[oracle(getBlockHeaderBlockNumber)] -fn get_block_header_block_number(nullifier_tree_root: Field) -> Field {} +#[oracle(getNullifierRootBlockNumber)] +fn get_nullifier_root_block_number_oracle(_nullifier_tree_root: Field) -> Field {} + +unconstrained pub fn get_nullifier_root_block_number(nullifier_tree_root: Field) -> Field { + get_nullifier_root_block_number_oracle(nullifier_tree_root) +} #[oracle(getBlockHeader)] fn get_block_header_oracle(_block_number: Field) -> [Field; BLOCK_HEADER_LENGTH] {} @@ -35,7 +39,8 @@ pub fn get_block_header(block_number: Field, context: PrivateContext) -> BlockHe // 3) Get the membership witness of the block in the archive let archive_id = 5; // TODO(#3443) - let block_header_block_number = get_block_header_block_number(context.block_header.nullifier_tree_root); + // Using nullifier tree root to get the block header block number because that changes in every block (every tx emits a nullifier). + let block_header_block_number = get_nullifier_root_block_number(context.block_header.nullifier_tree_root); let witness: MembershipWitness = get_membership_witness(block_header_block_number, archive_id, block_hash); // 4) Check that the block is in the archive (i.e. the witness is valid) diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 7e495c173eab..2eb485fd287a 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -183,4 +183,12 @@ export class SimulatorOracle implements DBOracle { getBlockHeader(): Promise { return Promise.resolve(this.db.getBlockHeader()); } + + /** + * Fetches the current block number. + * @returns The block number. + */ + public async getBlockNumber(): Promise { + return await this.stateInfoProvider.getBlockNumber(); + } } diff --git a/yarn-project/types/src/interfaces/aztec-node.ts b/yarn-project/types/src/interfaces/aztec-node.ts index 92463e96b0f7..ac57cd2f3a5e 100644 --- a/yarn-project/types/src/interfaces/aztec-node.ts +++ b/yarn-project/types/src/interfaces/aztec-node.ts @@ -38,12 +38,6 @@ export interface AztecNode extends StateInfoProvider { */ getBlocks(from: number, limit: number): Promise; - /** - * Fetches the current block number. - * @returns The block number. - */ - getBlockNumber(): Promise; - /** * Method to fetch the version of the rollup the node is connected to. * @returns The rollup version. diff --git a/yarn-project/types/src/interfaces/state_info_provider.ts b/yarn-project/types/src/interfaces/state_info_provider.ts index 7818f984dab4..97616711fb9f 100644 --- a/yarn-project/types/src/interfaces/state_info_provider.ts +++ b/yarn-project/types/src/interfaces/state_info_provider.ts @@ -138,4 +138,10 @@ export interface StateInfoProvider { * @returns The requested block. */ getBlock(number: number): Promise; + + /** + * Fetches the current block number. + * @returns The block number. + */ + getBlockNumber(): Promise; } From 2aff67d90837e522cb2dfe6a57de0f6aa5552123 Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 12 Dec 2023 09:27:52 +0000 Subject: [PATCH 3/4] improved inclusion test --- .../src/e2e_inclusion_proofs_contract.test.ts | 35 ++++++++++++++----- .../merkle_tree_snapshot_operations_facade.ts | 2 +- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts b/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts index 56807979809d..4240a863566a 100644 --- a/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts @@ -19,12 +19,15 @@ describe('e2e_inclusion_proofs_contract', () => { let accounts: CompleteAddress[]; let contract: InclusionProofsContract; + let deploymentBlockNumber: number; const publicValue = 236n; beforeAll(async () => { ({ pxe, teardown, wallets, accounts } = await setup(1)); - contract = await InclusionProofsContract.deploy(wallets[0], publicValue).send().deployed(); + const receipt = await InclusionProofsContract.deploy(wallets[0], publicValue).send().wait(); + contract = receipt.contract; + deploymentBlockNumber = receipt.blockNumber!; }, 100_000); afterAll(() => teardown()); @@ -32,11 +35,15 @@ describe('e2e_inclusion_proofs_contract', () => { it('proves note existence and its nullifier non-existence and nullifier non-existence failure case', async () => { // Owner of a note const owner = accounts[0].address; + let noteCreationBlockNumber: number; { // Create a note const value = 100n; const receipt = await contract.methods.create_note(owner, value).send().wait({ debug: true }); + + noteCreationBlockNumber = receipt.blockNumber!; const { newCommitments, visibleNotes } = receipt.debugInfo!; + expect(newCommitments.length).toBe(1); expect(visibleNotes.length).toBe(1); const [receivedValue, receivedOwner, _randomness] = visibleNotes[0].note.items; @@ -46,17 +53,14 @@ describe('e2e_inclusion_proofs_contract', () => { { // Prove note inclusion in a given block. - // TODO: Use here note block number from the creation note tx to test archival node. This is currently not - // possible because of issue #3564 - const blockNumber = await pxe.getBlockNumber(); const ignoredCommitment = 0; // Not ignored only when the note doesn't exist - await contract.methods.proveNoteInclusion(owner, blockNumber, ignoredCommitment).send().wait(); + await contract.methods.proveNoteInclusion(owner, noteCreationBlockNumber, ignoredCommitment).send().wait(); } { // Prove that the note has not been nullified - // TODO: Use here note block number from the creation note tx to test archival node. This is currently not - // possible because of issue #3564 + // TODO(#3535): Prove the nullifier non-inclusion at older block to test archival node. This is currently not + // possible because of issue https://github.com/AztecProtocol/aztec-packages/issues/3535 const blockNumber = await pxe.getBlockNumber(); const ignoredNullifier = 0; // Not ignored only when the note doesn't exist await contract.methods.proveNullifierNonInclusion(owner, blockNumber, ignoredNullifier).send().wait(); @@ -93,12 +97,16 @@ describe('e2e_inclusion_proofs_contract', () => { }); it('proves an existence of a public value in private context', async () => { - const blockNumber = await pxe.getBlockNumber(); + // Chose random block number between deployment and current block number to test archival node + const blockNumber = await getRandomBlockNumberSinceDeployment(); + await contract.methods.provePublicValueInclusion(publicValue, blockNumber).send().wait(); }); it('public value existence failure case', async () => { - const blockNumber = await pxe.getBlockNumber(); + // Chose random block number between deployment and current block number to test archival node + const blockNumber = await getRandomBlockNumberSinceDeployment(); + const randomPublicValue = Fr.random(); await expect( contract.methods.provePublicValueInclusion(randomPublicValue, blockNumber).send().wait(), @@ -106,6 +114,8 @@ describe('e2e_inclusion_proofs_contract', () => { }); it('proves existence of a nullifier in private context', async () => { + // TODO(#3535): Test this at "random" block to test archival node. This is currently not possible because of + // issue https://github.com/AztecProtocol/aztec-packages/issues/3535 const blockNumber = await pxe.getBlockNumber(); const block = await pxe.getBlock(blockNumber); const nullifier = block?.newNullifiers[0]; @@ -114,6 +124,8 @@ describe('e2e_inclusion_proofs_contract', () => { }); it('nullifier existence failure case', async () => { + // TODO(#3535): Test this at "random" block to test archival node. This is currently not possible because of + // issue https://github.com/AztecProtocol/aztec-packages/issues/3535 const blockNumber = await pxe.getBlockNumber(); const randomNullifier = Fr.random(); @@ -121,4 +133,9 @@ describe('e2e_inclusion_proofs_contract', () => { /Low nullifier witness not found for nullifier 0x[0-9a-fA-F]+ at block/, ); }); + + const getRandomBlockNumberSinceDeployment = async () => { + const currentBlockNumber = await pxe.getBlockNumber(); + return deploymentBlockNumber + Math.floor(Math.random() * (currentBlockNumber - deploymentBlockNumber)); + }; }); diff --git a/yarn-project/world-state/src/merkle-tree/merkle_tree_snapshot_operations_facade.ts b/yarn-project/world-state/src/merkle-tree/merkle_tree_snapshot_operations_facade.ts index 1fd883b98b5e..450b6c5bca8b 100644 --- a/yarn-project/world-state/src/merkle-tree/merkle_tree_snapshot_operations_facade.ts +++ b/yarn-project/world-state/src/merkle-tree/merkle_tree_snapshot_operations_facade.ts @@ -65,7 +65,7 @@ export class MerkleTreeSnapshotOperationsFacade implements MerkleTreeOperations } | undefined > { - return Promise.reject(new Error('not implemented')); + return Promise.reject(new Error('Snapshots not implemented for nullifier tree')); } async getSiblingPath(treeId: MerkleTreeId, index: bigint): Promise> { From 27642ee687001dd7b095399aa92ce4fce5ec6de5 Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 12 Dec 2023 13:24:22 +0000 Subject: [PATCH 4/4] addressing a TODO --- yarn-project/aztec-nr/aztec/src/context.nr | 2 +- .../aztec/src/oracle/get_block_header.nr | 31 +++++++++++-------- .../src/oracle/get_membership_witness.nr | 4 +-- .../get_nullifier_membership_witness.nr | 8 ++--- .../aztec/src/oracle/get_sibling_path.nr | 4 +-- .../inclusion_proofs_contract/src/main.nr | 28 +++-------------- 6 files changed, 31 insertions(+), 46 deletions(-) diff --git a/yarn-project/aztec-nr/aztec/src/context.nr b/yarn-project/aztec-nr/aztec/src/context.nr index c7609942d4cb..020a9410ce53 100644 --- a/yarn-project/aztec-nr/aztec/src/context.nr +++ b/yarn-project/aztec-nr/aztec/src/context.nr @@ -129,7 +129,7 @@ impl PrivateContext { self.inputs.call_context.function_selector } - pub fn get_block_header(self, block_number: Field) -> BlockHeader { + pub fn get_block_header(self, block_number: u32) -> BlockHeader { get_block_header(block_number, self) } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr index a07a4d59a49d..7d10a8956460 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr @@ -17,35 +17,40 @@ use crate::{ #[oracle(getNullifierRootBlockNumber)] fn get_nullifier_root_block_number_oracle(_nullifier_tree_root: Field) -> Field {} -unconstrained pub fn get_nullifier_root_block_number(nullifier_tree_root: Field) -> Field { - get_nullifier_root_block_number_oracle(nullifier_tree_root) +unconstrained pub fn get_nullifier_root_block_number(nullifier_tree_root: Field) -> u32 { + get_nullifier_root_block_number_oracle(nullifier_tree_root) as u32 } #[oracle(getBlockHeader)] -fn get_block_header_oracle(_block_number: Field) -> [Field; BLOCK_HEADER_LENGTH] {} +fn get_block_header_oracle(_block_number: u32) -> [Field; BLOCK_HEADER_LENGTH] {} -unconstrained pub fn get_block_header_internal(block_number: Field) -> BlockHeader { +unconstrained pub fn get_block_header_internal(block_number: u32) -> BlockHeader { let block_header = get_block_header_oracle(block_number); BlockHeader::deserialize(block_header) } -pub fn get_block_header(block_number: Field, context: PrivateContext) -> BlockHeader { - // 1) Get block header of a given block from oracle +pub fn get_block_header(block_number: u32, context: PrivateContext) -> BlockHeader { + // 1) Get block number corresponding to block header inside context + // Using nullifier tree root to get the block header block number because that changes in every block (every tx emits a nullifier). + let block_header_block_number = get_nullifier_root_block_number(context.block_header.nullifier_tree_root); + + // 2) Check that the block header block number is more than or equal to the block number we want to prove against + // We could not perform the proof otherwise because the archive root from the header would not "contain" the block we want to prove against + assert(block_header_block_number >= block_number, "Block header block number is smaller than the block number we want to prove against"); + + // 3) Get block header of a given block from oracle let block_header = get_block_header_internal(block_number); - // 2) Compute the block hash from the block header + // 4) Compute the block hash from the block header let block_hash = block_header.block_hash(); - // 3) Get the membership witness of the block in the archive + // 5) Get the membership witness of the block in the archive let archive_id = 5; // TODO(#3443) - - // Using nullifier tree root to get the block header block number because that changes in every block (every tx emits a nullifier). - let block_header_block_number = get_nullifier_root_block_number(context.block_header.nullifier_tree_root); let witness: MembershipWitness = get_membership_witness(block_header_block_number, archive_id, block_hash); - // 4) Check that the block is in the archive (i.e. the witness is valid) + // 6) Check that the block is in the archive (i.e. the witness is valid) assert(context.block_header.archive_root == compute_merkle_root(block_hash, witness.index, witness.path), "Proving membership of a block in archive failed"); - // 5) Return the block header + // 7) Return the block header block_header } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_membership_witness.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_membership_witness.nr index 1f43ae52f57b..320b57cedc36 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_membership_witness.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_membership_witness.nr @@ -14,9 +14,9 @@ struct MembershipWitness { } #[oracle(getMembershipWitness)] -fn get_membership_witness_oracle(_block_number: Field, _tree_id: Field, _leaf_value: Field) -> [Field; M] {} +fn get_membership_witness_oracle(_block_number: u32, _tree_id: Field, _leaf_value: Field) -> [Field; M] {} -unconstrained pub fn get_membership_witness(block_number: Field, tree_id: Field, leaf_value: Field) -> MembershipWitness { +unconstrained pub fn get_membership_witness(block_number: u32, tree_id: Field, leaf_value: Field) -> MembershipWitness { let fields: [Field; M] = get_membership_witness_oracle(block_number, tree_id, leaf_value); MembershipWitness { index: fields[0], path: arr_copy_slice(fields, [0; N], 1) } } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr index 2cc493d7966c..204bde2b1c14 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr @@ -32,11 +32,11 @@ struct NullifierMembershipWitness { } #[oracle(getLowNullifierMembershipWitness)] -fn get_low_nullifier_membership_witness_oracle(_block_number: Field, _nullifier: Field) -> [Field; NULLIFIER_MEMBERSHIP_WITNESS] {} +fn get_low_nullifier_membership_witness_oracle(_block_number: u32, _nullifier: Field) -> [Field; NULLIFIER_MEMBERSHIP_WITNESS] {} // Nullifier here refers to the nullifier we are looking to get non-inclusion proof for (by proving that a lower // nullifier's next_value is bigger than the nullifier) -unconstrained pub fn get_low_nullifier_membership_witness(block_number: Field, nullifier: Field) -> NullifierMembershipWitness { +unconstrained pub fn get_low_nullifier_membership_witness(block_number: u32, nullifier: Field) -> NullifierMembershipWitness { let fields = get_low_nullifier_membership_witness_oracle(block_number, nullifier); NullifierMembershipWitness { index: fields[0], @@ -46,11 +46,11 @@ unconstrained pub fn get_low_nullifier_membership_witness(block_number: Field, n } #[oracle(getNullifierMembershipWitness)] -fn get_nullifier_membership_witness_oracle(_block_number: Field, _nullifier: Field) -> [Field; NULLIFIER_MEMBERSHIP_WITNESS] {} +fn get_nullifier_membership_witness_oracle(_block_number: u32, _nullifier: Field) -> [Field; NULLIFIER_MEMBERSHIP_WITNESS] {} // Nullifier here refers to the nullifier we are looking to get non-inclusion proof for (by proving that a lower // nullifier's next_value is bigger than the nullifier) -unconstrained pub fn get_nullifier_membership_witness(block_number: Field, nullifier: Field) -> NullifierMembershipWitness { +unconstrained pub fn get_nullifier_membership_witness(block_number: u32, nullifier: Field) -> NullifierMembershipWitness { let fields = get_nullifier_membership_witness_oracle(block_number, nullifier); NullifierMembershipWitness { index: fields[0], diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_sibling_path.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_sibling_path.nr index 7fbe0936997b..2109767a2117 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_sibling_path.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_sibling_path.nr @@ -2,9 +2,9 @@ use dep::protocol_types::constants::NOTE_HASH_TREE_HEIGHT; use crate::utils::arr_copy_slice; #[oracle(getSiblingPath)] -fn get_sibling_path_oracle(_block_number: Field, _tree_id: Field, _leaf_index: Field) -> [Field; N] {} +fn get_sibling_path_oracle(_block_number: u32, _tree_id: Field, _leaf_index: Field) -> [Field; N] {} -unconstrained pub fn get_sibling_path(block_number: Field, tree_id: Field, leaf_index: Field) -> [Field; N] { +unconstrained pub fn get_sibling_path(block_number: u32, tree_id: Field, leaf_index: Field) -> [Field; N] { let value: [Field; N] = get_sibling_path_oracle(block_number, tree_id, leaf_index); value } diff --git a/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr index d9235ccd6ee8..a06c832cd500 100644 --- a/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr @@ -98,14 +98,9 @@ contract InclusionProofs { #[aztec(private)] fn proveNoteInclusion( owner: AztecAddress, - block_number: Field, // The block at which we'll prove that the note exists + block_number: u32, // The block at which we'll prove that the note exists spare_commitment: Field, // This is only used when the note is not found --> used to test the failure case ) { - // TODO: assert that block number is less than the block number of context.block_header - // --> This will either require a new oracle method that returns block_header.global_variables_hash preimage - // or modifying the private context so that we somehow expose it. - // Blocked by #3564 - // 1) Get block header from oracle and ensure that the block hash is included in the current blocks tree // root. let block_header = context.get_block_header(block_number); @@ -142,14 +137,9 @@ contract InclusionProofs { #[aztec(private)] fn proveNullifierNonInclusion( owner: AztecAddress, - block_number: Field, // The block at which we'll prove that the nullifier does not exists + block_number: u32, // The block at which we'll prove that the nullifier does not exists spare_nullifier: Field, // This is only used when the note is not found --> used to test the failure case ) { - // TODO: assert that block number is less than the block number of context.block_header - // --> This will either require a new oracle method that returns block_header.global_variables_hash preimage - // or modifying the private context so that we somehow expose it. - // Blocked by #3564 - // 1) Get block header from oracle and ensure that the block hash is included in the current blocks tree // root. let block_header = context.get_block_header(block_number); @@ -215,13 +205,8 @@ contract InclusionProofs { #[aztec(private)] fn proveNullifierInclusion( nullifier: Field, - block_number: Field, // The block at which we'll prove that the nullifier not exists in the tree + block_number: u32, // The block at which we'll prove that the nullifier not exists in the tree ) { - // TODO: assert that block number is less than the block number of context.block_header - // --> This will either require a new oracle method that returns block_header.global_variables_hash preimage - // or modifying the private context so that we somehow expose it. - // Blocked by #3564 - // 1) Get block header from oracle and ensure that the block hash is included in the current blocks tree // root. let block_header = context.get_block_header(block_number); @@ -248,13 +233,8 @@ contract InclusionProofs { #[aztec(private)] fn provePublicValueInclusion( public_value: Field, - block_number: Field, // The block at which we'll prove that the public value exists + block_number: u32, // The block at which we'll prove that the public value exists ) { - // TODO: assert that block number is less than the block number of context.block_header - // --> This will either require a new oracle method that returns block_header.global_variables_hash preimage - // or modifying the private context so that we somehow expose it. - // Blocked by #3564 - // 1) Get block header from oracle and ensure that the block hash is included in the current blocks tree // root. let block_header = context.get_block_header(block_number);