From a01a0b6f0f78ed61745e2f5a5ceb3fa3569cd8b8 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 9 Aug 2024 17:49:42 +0000 Subject: [PATCH 1/3] init --- .../aztec-nr/aztec/src/oracle/header.nr | 77 ++++++++++++++----- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/header.nr b/noir-projects/aztec-nr/aztec/src/oracle/header.nr index 7f0d9421fd8b..ff027c1a78e9 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/header.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/header.nr @@ -3,6 +3,9 @@ use dep::protocol_types::{constants::HEADER_LENGTH, header::Header}; use crate::{context::PrivateContext, oracle::get_membership_witness::get_archive_membership_witness}; +use crate::test::helpers::test_environment::TestEnvironment; +use dep::std::test::OracleMock; + #[oracle(getHeader)] unconstrained fn get_header_at_oracle(_block_number: u32) -> [Field; HEADER_LENGTH] {} @@ -12,16 +15,17 @@ unconstrained pub fn get_header_at_internal(block_number: u32) -> Header { } pub fn get_header_at(block_number: u32, context: PrivateContext) -> Header { - let historical_header_block_number = context.historical_header.global_variables.block_number as u32; + let historical_header = context.historical_header; + let historical_block_number = historical_header.global_variables.block_number as u32; - if (block_number == historical_header_block_number) { + if (block_number == historical_block_number) { // If the block number we want to prove against is the same as the block number in the historical header we // skip the inclusion proofs and just return the historical header from context. - context.historical_header + historical_header } else { // 1) Get block number corresponding to the last_archive root in the header // Note: We subtract 1 because the last_archive root is the root of the archive after applying the previous block - let last_archive_block_number = historical_header_block_number - 1; + let last_archive_block_number = historical_block_number - 1; // 2) Check that the last archive 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 last archive root from the header would not "contain" @@ -30,22 +34,59 @@ pub fn get_header_at(block_number: u32, context: PrivateContext) -> Header { last_archive_block_number >= block_number, "Last archive block number is smaller than the block number we want to prove against" ); - // 3) Get the header of a given block from oracle - let header = get_header_at_internal(block_number); - - // 4) Compute the block hash from the block header - let block_hash = header.hash(); + // 3) Get the header hint of a given block from an oracle + let header_hint = get_header_at_internal(block_number); - // 5) Get the membership witness of the block in the archive - let witness = get_archive_membership_witness(last_archive_block_number, block_hash); - - // 6) Check that the block is in the archive (i.e. the witness is valid) - assert( - context.historical_header.last_archive.root - == root_from_sibling_path(block_hash, witness.index, witness.path), "Proving membership of a block in archive failed" + // 4) We make sure that the header hint we received from the oracle exists in the state tree and is the actual header + // at the desired block number + constrain_get_header_at_internal( + header_hint, + block_number, + last_archive_block_number, + historical_header.last_archive.root ); - // 7) Return the block header - header + // 8) Return the block header + header_hint } } + +fn constrain_get_header_at_internal( + header_hint: Header, + block_number: u32, + last_archive_block_number: u32, + last_archive_root: Field +) { + // 1) Compute the block hash from the block header + let block_hash = header_hint.hash(); + + // 2) Get the membership witness of the block in the archive tree + let witness = get_archive_membership_witness(last_archive_block_number, block_hash); + + // 3) Check that the block is in the archive (i.e. the witness is valid) + assert( + last_archive_root == root_from_sibling_path(block_hash, witness.index, witness.path), "Proving membership of a block in archive failed" + ); + + // 4) Check that the header hint has the same block number as the block number we are looking for, ensuring we are actually grabbing the header we specify + assert( + header_hint.global_variables.block_number as u32 == block_number, "Block number provided is not the same as the block number from the header hint" + ); +} + +#[test(should_fail_with = "Block number provided is not the same as the block number from the header hint")] +fn fetching_a_valid_but_different_header_should_fail() { + let mut env = TestEnvironment::new(); + + // We get an arbitrary header at block 1 + let old_header = get_header_at_internal(1); + + // The next call to getHeader at block 5 should resolve with this old header. + // This header exists, but we make the call return it at an incorrect block number. + let _ = OracleMock::mock("getHeader").with_params((5)).returns(old_header.serialize()).times(1); + + env.advance_block_to(6); + + // We now try to get the header that our mock sets up. The oracle returns the old, incorrect header and should fail. + let _ = get_header_at(5, env.private()); +} From cfd46ee770796adf4baa375cdcf4af253bf704a9 Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Tue, 13 Aug 2024 10:11:11 +0000 Subject: [PATCH 2/3] addressing comments --- .../aztec-nr/aztec/src/oracle/header.nr | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/header.nr b/noir-projects/aztec-nr/aztec/src/oracle/header.nr index ff027c1a78e9..e3407996dd7d 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/header.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/header.nr @@ -15,17 +15,17 @@ unconstrained pub fn get_header_at_internal(block_number: u32) -> Header { } pub fn get_header_at(block_number: u32, context: PrivateContext) -> Header { - let historical_header = context.historical_header; - let historical_block_number = historical_header.global_variables.block_number as u32; + let header = context.historical_header; + let current_block_number = header.global_variables.block_number as u32; - if (block_number == historical_block_number) { + if (block_number == current_block_number) { // If the block number we want to prove against is the same as the block number in the historical header we // skip the inclusion proofs and just return the historical header from context. - historical_header + header } else { // 1) Get block number corresponding to the last_archive root in the header // Note: We subtract 1 because the last_archive root is the root of the archive after applying the previous block - let last_archive_block_number = historical_block_number - 1; + let last_archive_block_number = current_block_number - 1; // 2) Check that the last archive 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 last archive root from the header would not "contain" @@ -35,19 +35,19 @@ pub fn get_header_at(block_number: u32, context: PrivateContext) -> Header { ); // 3) Get the header hint of a given block from an oracle - let header_hint = get_header_at_internal(block_number); + let historical = get_header_at_internal(block_number); // 4) We make sure that the header hint we received from the oracle exists in the state tree and is the actual header // at the desired block number constrain_get_header_at_internal( - header_hint, + historical, block_number, last_archive_block_number, - historical_header.last_archive.root + header.last_archive.root ); - // 8) Return the block header - header_hint + // 5) Return the block header + historical } } @@ -78,15 +78,18 @@ fn constrain_get_header_at_internal( fn fetching_a_valid_but_different_header_should_fail() { let mut env = TestEnvironment::new(); - // We get an arbitrary header at block 1 - let old_header = get_header_at_internal(1); + env.advance_block_to(3); - // The next call to getHeader at block 5 should resolve with this old header. - // This header exists, but we make the call return it at an incorrect block number. - let _ = OracleMock::mock("getHeader").with_params((5)).returns(old_header.serialize()).times(1); + // We get our current header for the last archive values. + let current_header = env.private().historical_header; - env.advance_block_to(6); + let historical_header = get_header_at_internal(1); - // We now try to get the header that our mock sets up. The oracle returns the old, incorrect header and should fail. - let _ = get_header_at(5, env.private()); + // We pass in a different block number than the header received + constrain_get_header_at_internal( + historical_header, + 2, + current_header.global_variables.block_number as u32 - 1, + current_header.last_archive.root + ); } From 9c064ab1a0f531f8bcdd887ac51452eab73d8bfd Mon Sep 17 00:00:00 2001 From: esau <152162806+sklppy88@users.noreply.github.com> Date: Sun, 18 Aug 2024 03:39:51 -0500 Subject: [PATCH 3/3] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolás Venturo --- noir-projects/aztec-nr/aztec/src/oracle/header.nr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/header.nr b/noir-projects/aztec-nr/aztec/src/oracle/header.nr index e3407996dd7d..da388b948ddc 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/header.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/header.nr @@ -4,7 +4,6 @@ use dep::protocol_types::{constants::HEADER_LENGTH, header::Header}; use crate::{context::PrivateContext, oracle::get_membership_witness::get_archive_membership_witness}; use crate::test::helpers::test_environment::TestEnvironment; -use dep::std::test::OracleMock; #[oracle(getHeader)] unconstrained fn get_header_at_oracle(_block_number: u32) -> [Field; HEADER_LENGTH] {} @@ -83,11 +82,12 @@ fn fetching_a_valid_but_different_header_should_fail() { // We get our current header for the last archive values. let current_header = env.private().historical_header; - let historical_header = get_header_at_internal(1); + let target_block_number = 2; + let bad_header = get_header_at_internal(target_block_number - 1); // We pass in a different block number than the header received constrain_get_header_at_internal( - historical_header, + bad_header, 2, current_header.global_variables.block_number as u32 - 1, current_header.last_archive.root