Skip to content
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: introduce max_block_number #5251

Merged
merged 45 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e13108f
Add changes to private context and inputs
nventuro Mar 12, 2024
2185b60
Do private kernel data
nventuro Mar 12, 2024
a0bfd27
Do public kernel data
nventuro Mar 12, 2024
ec6c4de
Update rollup circuits
nventuro Mar 13, 2024
373eeb0
Add private tests
nventuro Mar 13, 2024
ec3f8f5
Add public tests
nventuro Mar 13, 2024
eec3f8a
Add rollup tests
nventuro Mar 13, 2024
1a78d66
Fix circuit tests
nventuro Mar 13, 2024
0dc6dca
Update TS definitions
nventuro Mar 13, 2024
dd2b40d
Migrate max_block_number to use option
nventuro Mar 14, 2024
c104e8c
Add more unit tests
nventuro Mar 14, 2024
79df323
Update ts and tests
nventuro Mar 14, 2024
101f637
Add end to end test
nventuro Mar 14, 2024
2703964
Merge branch 'master' into nv/context-max-block-number
nventuro Mar 15, 2024
a2cfb6f
Merge branch 'master' into nv/context-max-block-number
nventuro Mar 18, 2024
d50f2b8
Merge branch 'master' into nv/context-max-block-number
nventuro Mar 18, 2024
5feac31
Propagating struct changes in TS
nventuro Mar 19, 2024
cf93e0c
Use Option.eq
nventuro Mar 19, 2024
e8f3fa6
Fix typos
nventuro Mar 19, 2024
1f1b9c4
Add sequencer checks
nventuro Mar 19, 2024
1d8eab1
Add some doc notes
nventuro Mar 19, 2024
7d2ef64
Merge branch 'master' into nv/context-max-block-number
nventuro Mar 19, 2024
7445f09
Update snapshot
nventuro Mar 19, 2024
d8fa9f2
Delete hanging function
nventuro Mar 19, 2024
7557791
Clarify comment
nventuro Mar 19, 2024
f83d3cd
Fix tests
nventuro Mar 19, 2024
5c4cfd8
Clarify test names
nventuro Mar 19, 2024
07ccab7
Fix autoformatter error
nventuro Mar 20, 2024
2fbf876
Rename get_lower to min
nventuro Mar 20, 2024
bd8e844
Remove extra import
nventuro Mar 20, 2024
9fd190c
Add todo reference
nventuro Mar 20, 2024
7a40c6c
Merge branch 'master' into nv/context-max-block-number
nventuro Mar 20, 2024
2445060
Merge branch 'master' into nv/context-max-block-number
nventuro Mar 21, 2024
1f79897
Fix slither output
nventuro Mar 21, 2024
85213d3
Merge branch 'master' into nv/context-max-block-number
nventuro Mar 21, 2024
e6c452b
Fix docs
nventuro Mar 21, 2024
b764a0c
Merge branch 'master' into nv/context-max-block-number
nventuro Mar 21, 2024
5a915f2
Fix extra import
nventuro Mar 21, 2024
4327953
update MORE snapshots
nventuro Mar 21, 2024
d9bfa9c
update more snapshots
nventuro Mar 22, 2024
14cf439
make it stop
nventuro Mar 22, 2024
151396b
Merge remote-tracking branch 'upstream/master' into nv/context-max-bl…
nventuro Mar 22, 2024
cb1e2e3
iupdate hex files
nventuro Mar 22, 2024
6f69bb9
Add lost changes
nventuro Mar 22, 2024
e800e35
if i ever have to update one more snapshot i swear i will
nventuro Mar 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,18 @@ jobs:
aztec_manifest_key: end-to-end
<<: *defaults_e2e_test

e2e-max-block-number:
docker:
- image: aztecprotocol/alpine-build-image
resource_class: small
steps:
- *checkout
- *setup_env
- run:
name: "Test"
command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=e2e_max_block_number.test.ts
aztec_manifest_key: end-to-end

e2e-multiple-accounts-1-enc-key:
steps:
- *checkout
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Function Context
## title: Function Context
nventuro marked this conversation as resolved.
Show resolved Hide resolved
---

# The Function Context
Expand Down Expand Up @@ -94,6 +94,14 @@ The return values are a set of values that are returned from an applications exe

return_values : BoundedVec<Field, RETURN_VALUES_LENGTH>,

## Max Block Number

Some data structures impose time constraints, e.g. they may make it so that a value can only be changed after a certain delay. Interacting with these in private involves creating proofs that are only valid as long as they are included before a certain future point in time. To achieve this, the `request_max_block_number` function can be used to set this property:

#include_code max-block-number /noir-projects/aztec-nr/aztec/src/context/private_context.nr rust

A transaction that requests a maximum block number will never be included in a block with a block number larger than the requested value, since it would be considered invalid. This can also be used to make transactions automatically expire after some time if not included.

### Read Requests

<!-- TODO(maddiaa): leaving as todo until their is further clarification around their implementation in the protocol -->
Expand Down
5 changes: 3 additions & 2 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,12 @@ library Constants {
uint256 internal constant HEADER_LENGTH = 20;
uint256 internal constant L1_TO_L2_MESSAGE_LENGTH = 6;
uint256 internal constant L2_TO_L1_MESSAGE_LENGTH = 2;
uint256 internal constant MAX_BLOCK_NUMBER_LENGTH = 2;
nventuro marked this conversation as resolved.
Show resolved Hide resolved
uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH = 4;
uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_CONTEXT_LENGTH = 5;
uint256 internal constant PARTIAL_STATE_REFERENCE_LENGTH = 6;
uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 208;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 205;
uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 210;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 207;
uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 198;
uint256 internal constant STATE_REFERENCE_LENGTH = 8;
uint256 internal constant TX_CONTEXT_DATA_LENGTH = 4;
Expand Down
12 changes: 11 additions & 1 deletion noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
use dep::protocol_types::{
abis::{
call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector,
nullifier_key_validation_request::NullifierKeyValidationRequest,
max_block_number::MaxBlockNumber, nullifier_key_validation_request::NullifierKeyValidationRequest,
private_call_stack_item::PrivateCallStackItem,
private_circuit_public_inputs::PrivateCircuitPublicInputs,
public_call_stack_item::PublicCallStackItem,
Expand Down Expand Up @@ -46,6 +46,8 @@ struct PrivateContext {
args_hash : Field,
return_values : BoundedVec<Field, RETURN_VALUES_LENGTH>,

max_block_number: MaxBlockNumber,

note_hash_read_requests: BoundedVec<SideEffect, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL>,
nullifier_read_requests: BoundedVec<ReadRequest, MAX_NULLIFIER_READ_REQUESTS_PER_CALL>,
nullifier_key_validation_requests: BoundedVec<NullifierKeyValidationRequest, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL>,
Expand Down Expand Up @@ -129,6 +131,7 @@ impl PrivateContext {
min_revertible_side_effect_counter,
args_hash,
return_values: BoundedVec::new(),
max_block_number: MaxBlockNumber::default(),
note_hash_read_requests: BoundedVec::new(),
nullifier_read_requests: BoundedVec::new(),
nullifier_key_validation_requests: BoundedVec::new(),
Expand Down Expand Up @@ -163,6 +166,7 @@ impl PrivateContext {
args_hash: self.args_hash,
return_values: self.return_values.storage,
min_revertible_side_effect_counter: self.min_revertible_side_effect_counter,
max_block_number: self.max_block_number,
note_hash_read_requests: self.note_hash_read_requests.storage,
nullifier_read_requests: self.nullifier_read_requests.storage,
nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage,
Expand All @@ -188,6 +192,12 @@ impl PrivateContext {
self.min_revertible_side_effect_counter = self.side_effect_counter;
}

// docs:start:max-block-number
pub fn request_max_block_number(&mut self, max_block_number: u32) {
// docs:end:max-block-number
self.max_block_number = MaxBlockNumber::min_with_u32(self.max_block_number, max_block_number);
}

pub fn push_note_hash_read_request(&mut self, note_hash: Field) {
let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter };
self.note_hash_read_requests.push(side_effect);
Expand Down
23 changes: 21 additions & 2 deletions noir-projects/noir-contracts/contracts/test_contract/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// A contract used for testing a random hodgepodge of small features from simulator and end-to-end tests.
contract Test {
use dep::aztec::prelude::{
AztecAddress, EthAddress, NoteHeader, NoteGetterOptions, NoteViewerOptions, PrivateContext,
PrivateImmutable, PrivateSet
AztecAddress, EthAddress, FunctionSelector, NoteHeader, NoteGetterOptions, NoteViewerOptions,
PrivateContext, PrivateImmutable, PrivateSet
};

use dep::aztec::protocol_types::{
Expand Down Expand Up @@ -63,6 +63,25 @@ contract Test {
context.this_address()
}

#[aztec(private)]
fn request_max_block_number(max_block_number: u32, enqueue_public_call: bool) {
// docs:start:request-max-block-number
context.request_max_block_number(max_block_number);
// docs:end:request-max-block-number

if enqueue_public_call {
let _ = context.call_public_function(
context.this_address(),
FunctionSelector::from_signature("dummy_public_call()"),
[]
);
}
}

#[aztec(public)]
#[aztec(internal)]
fn dummy_public_call() {}

#[aztec(private)]
fn call_create_note(value: Field, owner: AztecAddress, storage_slot: Field) {
assert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use dep::types::{
abis::{
call_request::CallRequest, accumulated_data::CombinedAccumulatedData,
kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsBuilder,
membership_witness::NoteHashReadRequestMembershipWitness,
max_block_number::MaxBlockNumber, membership_witness::NoteHashReadRequestMembershipWitness,
private_circuit_public_inputs::PrivateCircuitPublicInputs,
private_kernel::private_call_data::PrivateCallData, kernel_data::{PrivateKernelInnerData},
private_kernel::private_call_data::PrivateCallData, kernel_data::PrivateKernelInnerData,
side_effect::{SideEffect, SideEffectLinkedToNoteHash}
},
address::{AztecAddress, EthAddress, PartialAddress, compute_initialization_hash},
Expand Down Expand Up @@ -92,6 +92,7 @@ pub fn initialize_end_values(
public_inputs.min_revertible_side_effect_counter = previous_kernel.public_inputs.min_revertible_side_effect_counter;

let start = previous_kernel.public_inputs.validation_requests;
public_inputs.validation_requests.max_block_number = start.for_rollup.max_block_number;
public_inputs.validation_requests.note_hash_read_requests = array_to_bounded_vec(start.note_hash_read_requests);
public_inputs.validation_requests.nullifier_read_requests = array_to_bounded_vec(start.nullifier_read_requests);
public_inputs.validation_requests.nullifier_key_validation_requests = array_to_bounded_vec(start.nullifier_key_validation_requests);
Expand Down Expand Up @@ -180,6 +181,9 @@ pub fn update_end_values(

let storage_contract_address = private_call_public_inputs.call_context.storage_contract_address;

// Update the max block number if the private call requested a lower one.
public_inputs.validation_requests.max_block_number = MaxBlockNumber::min(public_inputs.validation_requests.max_block_number, private_call_public_inputs.max_block_number);

// Transient read requests and witnesses are accumulated in public_inputs.end
// We silo the read requests (domain separation per contract address)
let read_requests = private_call_public_inputs.note_hash_read_requests;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,23 @@ mod tests {
builder.failed();
}

#[test]
fn default_max_block_number() {
let mut builder = PrivateKernelInitInputsBuilder::new();
let public_inputs = builder.execute();

assert(public_inputs.validation_requests.for_rollup.max_block_number.is_none());
}

#[test]
fn propagate_max_block_number_request() {
let mut builder = PrivateKernelInitInputsBuilder::new();
builder.private_call.request_max_block_number(42);
let public_inputs = builder.execute();

assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 42);
}

#[test]
fn native_no_note_hash_read_requests_works() {
let mut builder = PrivateKernelInitInputsBuilder::new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ mod tests {
use dep::types::{
abis::{
kernel_circuit_public_inputs::PrivateKernelInnerCircuitPublicInputs,
side_effect::{SideEffect, SideEffectLinkedToNoteHash}
max_block_number::MaxBlockNumber, side_effect::{SideEffect, SideEffectLinkedToNoteHash}
},
address::{AztecAddress, EthAddress}, hash::compute_logs_hash,
messaging::l2_to_l1_message::L2ToL1Message, utils::{arrays::array_length},
Expand Down Expand Up @@ -550,6 +550,36 @@ mod tests {
builder.failed();
}

#[test]
fn propagate_previous_kernel_max_block_number() {
let mut builder = PrivateKernelInnerInputsBuilder::new();
builder.previous_kernel.validation_requests.max_block_number = MaxBlockNumber::new(13);
let public_inputs = builder.execute();

assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 13);
}

#[test]
fn propagate_max_block_number_request() {
let mut builder = PrivateKernelInnerInputsBuilder::new();
builder.private_call.request_max_block_number(42);
let public_inputs = builder.execute();

assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 42);
}

#[test]
fn ignore_larger_max_block_number() {
let mut builder = PrivateKernelInnerInputsBuilder::new();
builder.previous_kernel.validation_requests.max_block_number = MaxBlockNumber::new(13);
// A private call requesting a larger max_block_number should not change the current one as that constraint is
// already satisfied.
builder.private_call.request_max_block_number(42);
let public_inputs = builder.execute();

assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 13);
}

#[test]
fn native_no_note_hash_read_requests_works() {
let mut builder = PrivateKernelInnerInputsBuilder::new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ mod tests {
use dep::types::{
abis::{
kernel_circuit_public_inputs::PrivateKernelTailCircuitPublicInputs,
side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered}
max_block_number::MaxBlockNumber, side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered}
},
hash::compute_unique_siloed_note_hashes, tests::kernel_data_builder::PreviousKernelDataBuilder,
utils::{arrays::{array_eq, array_length}}, traits::{Empty, is_empty, is_empty_array}
Expand Down Expand Up @@ -452,6 +452,15 @@ mod tests {
builder.failed();
}

#[test]
fn propagate_previous_kernel_max_block_number() {
let mut builder = PrivateKernelTailInputsBuilder::new();
builder.previous_kernel.validation_requests.max_block_number = MaxBlockNumber::new(13);
let public_inputs = builder.execute();

assert_eq(public_inputs.rollup_validation_requests.max_block_number.unwrap(), 13);
}

#[test]
unconstrained fn one_pending_nullifier_read_request() {
let mut builder = PrivateKernelTailInputsBuilder::new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ pub fn initialize_emitted_end_values(
circuit_outputs.end_non_revertible.new_nullifiers = array_to_bounded_vec(start_non_revertible.new_nullifiers);
circuit_outputs.end_non_revertible.public_data_update_requests = array_to_bounded_vec(start_non_revertible.public_data_update_requests);

// TODO - should be propagated only in initialize_end_values() and clear them in the tail circuit.
// TODO - should be propagated only in initialize_end_values() and clear them in the tail circuit. The
// max_block_number must be propagated to the rollup however as a RollupValidationRequest.
let start = previous_kernel.public_inputs.validation_requests;
circuit_outputs.validation_requests.max_block_number = start.for_rollup.max_block_number;
circuit_outputs.validation_requests.public_data_reads = array_to_bounded_vec(start.public_data_reads);
}

Expand All @@ -99,6 +101,7 @@ pub fn initialize_end_values(
circuit_outputs.end_non_revertible.public_call_stack = array_to_bounded_vec(start_non_revertible.public_call_stack);

let start = previous_kernel.public_inputs.validation_requests;
circuit_outputs.validation_requests.max_block_number = previous_kernel.public_inputs.validation_requests.for_rollup.max_block_number;
circuit_outputs.validation_requests.nullifier_read_requests = array_to_bounded_vec(start.nullifier_read_requests);
circuit_outputs.validation_requests.nullifier_non_existent_read_requests = array_to_bounded_vec(start.nullifier_non_existent_read_requests);
}
Expand Down Expand Up @@ -158,6 +161,7 @@ fn validate_call_requests<N>(
}

pub fn update_validation_requests(public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder) {
// Note that the public kernel cannot modify the max block number value - it simply forwards it to the rollup
propagate_nullifier_read_requests(public_call, circuit_outputs);
propagate_nullifier_non_existent_read_requests(public_call, circuit_outputs);
propagate_valid_public_data_reads(public_call, circuit_outputs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ mod tests {
use dep::types::{
abis::{
call_request::CallRequest, function_selector::FunctionSelector,
kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, public_data_read::PublicDataRead,
public_data_update_request::PublicDataUpdateRequest, public_call_data::PublicCallData,
read_request::ReadRequest
kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, max_block_number::MaxBlockNumber,
public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest,
public_call_data::PublicCallData, read_request::ReadRequest
},
address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId,
contrakt::storage_read::StorageRead, hash::compute_logs_hash,
Expand Down Expand Up @@ -357,6 +357,8 @@ mod tests {
fn circuit_outputs_should_be_correctly_populated_with_previous_private_kernel() {
let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new();

builder.previous_kernel.validation_requests.max_block_number = MaxBlockNumber::new(13);
nventuro marked this conversation as resolved.
Show resolved Hide resolved

builder.public_call.append_public_call_requests_for_regular_calls(2);
let storage = builder.public_call.public_call_stack.storage;

Expand Down Expand Up @@ -384,6 +386,7 @@ mod tests {

let public_inputs = kernel.public_kernel_setup();

assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 13);
assert_eq_call_requests(public_inputs.end.private_call_stack, []);
assert_eq_call_requests(
public_inputs.end_non_revertible.public_call_stack,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ impl BaseRollupInputs {
== self.constants.global_variables.version, "kernel version does not match the rollup version"
);

let rollup_validation_requests = self.kernel_data.public_inputs.rollup_validation_requests;

// Verify the max block number
// TODO #5345: why is block_number a Field and not u32?
if rollup_validation_requests.max_block_number.is_some() {
assert(
self.constants.global_variables.block_number as u32
<= rollup_validation_requests.max_block_number.unwrap_unchecked(), "kernel max_block_number is smaller than block number"
);
}

let commitments_tree_subroot = self.calculate_commitments_subtree();

let empty_commitments_subtree_root = calculate_empty_tree_root(NOTE_HASH_SUBTREE_HEIGHT);
Expand Down Expand Up @@ -1005,6 +1016,30 @@ mod tests {
builder.fails();
}

#[test(should_fail_with = "kernel max_block_number is smaller than block number")]
unconstrained fn constants_dont_satisfy_smaller_max_block_number() {
let mut builder = BaseRollupInputsBuilder::new();
builder.constants.global_variables.block_number = 42;
builder.kernel_data.set_max_block_number(5);
builder.fails();
}

#[test]
unconstrained fn constants_satisfy_equal_max_block_number() {
let mut builder = BaseRollupInputsBuilder::new();
builder.constants.global_variables.block_number = 42;
builder.kernel_data.set_max_block_number(42);
builder.succeeds();
}

#[test]
unconstrained fn constants_satisfy_larger_max_block_number() {
let mut builder = BaseRollupInputsBuilder::new();
builder.constants.global_variables.block_number = 42;
builder.kernel_data.set_max_block_number(4294967295);
builder.succeeds();
}

#[test]
unconstrained fn subtree_height_is_0() {
let outputs = BaseRollupInputsBuilder::new().execute();
Expand Down
2 changes: 2 additions & 0 deletions noir-projects/noir-protocol-circuits/crates/types/src/abis.nr
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ mod public_data_update_request;
mod accumulated_data;
mod validation_requests;

mod max_block_number;

mod private_kernel;
mod kernel_circuit_public_inputs;
mod kernel_data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl PrivateKernelCircuitPublicInputsBuilder {
end_non_revertible,
end,
constants: self.constants,
rollup_validation_requests: self.validation_requests.to_rollup(),
needs_setup: end_non_revertible.needs_setup(),
needs_app_logic: end.needs_app_logic(),
needs_teardown: end_non_revertible.needs_teardown()
Expand Down
Loading
Loading