-
Notifications
You must be signed in to change notification settings - Fork 283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: block header block number oracle #3648
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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'; | ||
|
@@ -113,6 +120,30 @@ export class ViewDataOracle extends TypedOracle { | |
); | ||
} | ||
|
||
/** | ||
* 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 getNullifierRootBlockNumber(nullifierTreeRoot: Fr): Promise<number | undefined> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As before, not clear to me why it should be the nullifier root, but think it was just to have one? |
||
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}`); | ||
} | ||
|
||
/** | ||
* Retrieve the complete address associated to a given address. | ||
* @param address - Address to fetch the complete address for. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,34 +13,44 @@ use crate::{ | |
}, | ||
}; | ||
|
||
// TODO(#3564) - Nuke this oracle and Inject the number directly to context | ||
#[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) -> 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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this function name reads weirdly given the comment in the next line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure how we should do the wording much different. Its ok to me, but I might be stupid and have too much context. |
||
// 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 `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<ARCHIVE_HEIGHT, ARCHIVE_HEIGHT + 1> = get_membership_witness(path_block_number, archive_id, block_hash); | ||
|
||
// 4) Check that the block is in the archive (i.e. the witness is valid) | ||
let witness: MembershipWitness<ARCHIVE_HEIGHT, ARCHIVE_HEIGHT + 1> = get_membership_witness(block_header_block_number, archive_id, block_hash); | ||
|
||
// 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 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come
NullifierRootblockNumber
, would it not be the same for all of them?