Skip to content

Commit

Permalink
chore: introduce execution oracle (#7521)
Browse files Browse the repository at this point in the history
Discussing this and related topics with @Thunkar we realized that the
`getContractAddress` and similar oracles were duplicated: they existed
both in `UnconstrainedContext` and in `cheatcodes`. In my mind,
`cheatcodes` are oracles that only exist on TXE and that should not be
relied on for regular applications (i.e. they are not part of the PXE
API), whereas `UnconstrainedContext` _does_ use the regular PXE API.

These are clearly sort of standard, as can be seen in the fact that
we're using them outside of `UnconstrainedContext`, so I removed them
from both the context and cheatcodes, and created a new
`oracle::execution` mod with these four oracles.
  • Loading branch information
nventuro authored Jul 18, 2024
1 parent 3da86cb commit 645aec1
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 78 deletions.
8 changes: 4 additions & 4 deletions noir-projects/aztec-nr/authwit/src/cheatcodes.nr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use dep::aztec::{
protocol_types::address::AztecAddress,
context::{public_context::PublicContext, call_interfaces::CallInterface}, test::helpers::cheatcodes,
hash::hash_args
oracle::execution::{get_block_number, get_contract_address}, hash::hash_args
};

use crate::auth::{compute_inner_authwit_hash, compute_authwit_message_hash, set_authorized};
Expand All @@ -12,7 +12,7 @@ pub fn add_private_authwit_from_call_interface<C, M, T, P, Env>(
call_interface: C
) where C: CallInterface<M, T, P, Env> {
let target = call_interface.get_contract_address();
let inputs = cheatcodes::get_private_context_inputs(cheatcodes::get_block_number());
let inputs = cheatcodes::get_private_context_inputs(get_block_number());
let chain_id = inputs.tx_context.chain_id;
let version = inputs.tx_context.version;
let args_hash = hash_args(call_interface.get_args());
Expand All @@ -27,10 +27,10 @@ pub fn add_public_authwit_from_call_interface<C, M, T, P, Env>(
caller: AztecAddress,
call_interface: C
) where C: CallInterface<M, T, P, Env> {
let current_contract = cheatcodes::get_contract_address();
let current_contract = get_contract_address();
cheatcodes::set_contract_address(on_behalf_of);
let target = call_interface.get_contract_address();
let inputs = cheatcodes::get_private_context_inputs(cheatcodes::get_block_number());
let inputs = cheatcodes::get_private_context_inputs(get_block_number());
let chain_id = inputs.tx_context.chain_id;
let version = inputs.tx_context.version;
let args_hash = hash_args(call_interface.get_args());
Expand Down
32 changes: 15 additions & 17 deletions noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use dep::protocol_types::{address::AztecAddress, traits::Deserialize};
use crate::oracle::storage::{raw_storage_read, storage_read};
use crate::oracle::{
execution::{get_chain_id, get_version, get_contract_address, get_block_number},
storage::{raw_storage_read, storage_read}
};

struct UnconstrainedContext {
block_number: u32,
Expand All @@ -14,10 +17,17 @@ impl UnconstrainedContext {
// not even be accessed. However any performance gains are minimal, and we'd rather fail early if a user
// incorrectly attempts to create an UnconstrainedContext in an environment in which these oracles are not
// available.
let block_number = block_number_oracle();
let contract_address = contract_address_oracle();
let chain_id = chain_id_oracle();
let version = version_oracle();
let block_number = get_block_number();
let contract_address = get_contract_address();
let chain_id = get_chain_id();
let version = get_version();
Self { block_number, contract_address, version, chain_id }
}

unconstrained fn at(contract_address: AztecAddress) -> Self {
let block_number = get_block_number();
let chain_id = get_chain_id();
let version = get_version();
Self { block_number, contract_address, version, chain_id }
}

Expand Down Expand Up @@ -48,15 +58,3 @@ impl UnconstrainedContext {
T::deserialize(self.raw_storage_read(storage_slot))
}
}

#[oracle(getContractAddress)]
unconstrained fn contract_address_oracle() -> AztecAddress {}

#[oracle(getBlockNumber)]
unconstrained fn block_number_oracle() -> u32 {}

#[oracle(getChainId)]
unconstrained fn chain_id_oracle() -> Field {}

#[oracle(getVersion)]
unconstrained fn version_oracle() -> Field {}
9 changes: 5 additions & 4 deletions noir-projects/aztec-nr/aztec/src/note/note_getter/test.nr
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ use crate::{
note_header::NoteHeader,
note_getter_options::{NoteGetterOptions, Sort, SortOrder, Comparator, PropertySelector},
note_getter::constrain_get_notes_internal
}
},
oracle::execution::get_contract_address
};
use dep::protocol_types::address::AztecAddress;

use crate::test::{helpers::{test_environment::TestEnvironment, cheatcodes}, mocks::mock_note::MockNote};
use crate::test::{helpers::test_environment::TestEnvironment, mocks::mock_note::MockNote};

global storage_slot: Field = 42;

Expand All @@ -18,7 +19,7 @@ fn setup() -> TestEnvironment {
}

fn build_valid_note(value: Field) -> MockNote {
MockNote::new(value).contract_address(cheatcodes::get_contract_address()).storage_slot(storage_slot).build()
MockNote::new(value).contract_address(get_contract_address()).storage_slot(storage_slot).build()
}

fn assert_equivalent_vec_and_array<T, let N: u32>(
Expand Down Expand Up @@ -174,7 +175,7 @@ fn rejects_mismatched_storage_slot() {
let mut env = setup();
let mut context = env.private();

let note = MockNote::new(1).contract_address(cheatcodes::get_contract_address()).build(); // We're not setting the right storage slot
let note = MockNote::new(1).contract_address(get_contract_address()).build(); // We're not setting the right storage slot

let mut opt_notes = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
opt_notes[0] = Option::some(note);
Expand Down
29 changes: 29 additions & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/execution.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use dep::protocol_types::address::AztecAddress;

#[oracle(getContractAddress)]
unconstrained fn get_contract_address_oracle() -> AztecAddress {}

#[oracle(getBlockNumber)]
unconstrained fn get_block_number_oracle() -> u32 {}

#[oracle(getChainId)]
unconstrained fn get_chain_id_oracle() -> Field {}

#[oracle(getVersion)]
unconstrained fn get_version_oracle() -> Field {}

unconstrained pub fn get_contract_address() -> AztecAddress {
get_contract_address_oracle()
}

unconstrained pub fn get_block_number() -> u32 {
get_block_number_oracle()
}

unconstrained pub fn get_chain_id() -> Field {
get_chain_id_oracle()
}

unconstrained pub fn get_version() -> Field {
get_version_oracle()
}
1 change: 1 addition & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
mod arguments;
mod call_private_function;
mod encryption;
mod execution;
mod get_contract_instance;
mod get_l1_to_l2_membership_witness;
mod get_nullifier_membership_witness;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use dep::protocol_types::{address::AztecAddress, point::Point};
use crate::{context::PrivateContext, state_vars::private_mutable::PrivateMutable};
use crate::{
context::PrivateContext, state_vars::private_mutable::PrivateMutable,
oracle::execution::get_contract_address
};
use crate::test::{mocks::mock_note::MockNote, helpers::{cheatcodes, test_environment::TestEnvironment}};
use std::test::OracleMock;

Expand All @@ -24,7 +27,7 @@ fn test_initialize_or_replace_without_nullifier() {
let state_var = in_private(&mut env);

let value = 42;
let mut note = MockNote::new(value).contract_address(cheatcodes::get_contract_address()).storage_slot(storage_slot).build();
let mut note = MockNote::new(value).contract_address(get_contract_address()).storage_slot(storage_slot).build();

let _ = OracleMock::mock("checkNullifierExists").returns(0);
state_var.initialize_or_replace(&mut note).discard();
Expand Down
28 changes: 0 additions & 28 deletions noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,10 @@ unconstrained pub fn reset() {
oracle_reset();
}

unconstrained pub fn get_chain_id() -> Field {
oracle_get_chain_id()
}

unconstrained pub fn get_version() -> Field {
oracle_get_version()
}

unconstrained pub fn get_contract_address() -> AztecAddress {
oracle_get_contract_address()
}

unconstrained pub fn set_contract_address(address: AztecAddress) {
oracle_set_contract_address(address);
}

unconstrained pub fn get_block_number() -> u32 {
oracle_get_block_number()
}

unconstrained pub fn advance_blocks_by(blocks: u32) {
oracle_advance_blocks_by(blocks);
}
Expand Down Expand Up @@ -125,21 +109,9 @@ unconstrained pub fn set_fn_selector(selector: FunctionSelector) {
#[oracle(reset)]
unconstrained fn oracle_reset() {}

#[oracle(getChainId)]
unconstrained fn oracle_get_chain_id() -> Field {}

#[oracle(getVersion)]
unconstrained fn oracle_get_version() -> Field {}

#[oracle(getContractAddress)]
unconstrained fn oracle_get_contract_address() -> AztecAddress {}

#[oracle(setContractAddress)]
unconstrained fn oracle_set_contract_address(address: AztecAddress) {}

#[oracle(getBlockNumber)]
unconstrained fn oracle_get_block_number() -> u32 {}

#[oracle(advanceBlocksBy)]
unconstrained fn oracle_advance_blocks_by(blocks: u32) {}

Expand Down
26 changes: 13 additions & 13 deletions noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::note::{
note_header::NoteHeader, note_interface::NoteInterface,
utils::{compute_inner_note_hash, compute_note_hash_for_consumption}
};
use crate::oracle::notes::notify_created_note;
use crate::oracle::{execution::{get_block_number, get_contract_address}, notes::notify_created_note};

struct TestEnvironment {}

Expand All @@ -27,19 +27,19 @@ impl TestEnvironment {
}

fn block_number(_self: Self) -> u32 {
cheatcodes::get_block_number()
get_block_number()
}

fn contract_address(_self: Self) -> AztecAddress {
cheatcodes::get_contract_address()
get_contract_address()
}

fn impersonate(_self: Self, address: AztecAddress) {
cheatcodes::set_contract_address(address)
}

fn advance_block_to(&mut self, block_number: u32) {
let difference = block_number - cheatcodes::get_block_number();
let difference = block_number - get_block_number();
self.advance_block_by(difference);
}

Expand All @@ -53,7 +53,7 @@ impl TestEnvironment {
}

fn private(&mut self) -> PrivateContext {
self.private_at(cheatcodes::get_block_number())
self.private_at(get_block_number())
}

// unconstrained is a key word, so we mis-spell purposefully here, like we do with contrakt
Expand All @@ -62,7 +62,7 @@ impl TestEnvironment {
}

fn private_at(&mut self, historical_block_number: u32) -> PrivateContext {
if historical_block_number >= cheatcodes::get_block_number() {
if historical_block_number >= get_block_number() {
self.advance_block_to(historical_block_number + 1);
}

Expand Down Expand Up @@ -114,7 +114,7 @@ impl TestEnvironment {

let selector = FunctionSelector::from_signature("constructor(Field,Field)");

let mut context = self.private_at(cheatcodes::get_block_number());
let mut context = self.private_at(get_block_number());

let _ = context.call_private_function(address, selector, args);

Expand All @@ -131,12 +131,12 @@ impl TestEnvironment {
) -> T where C: CallInterface<M, PrivateContextInputs, PrivateCircuitPublicInputs, Env>, T: Deserialize<N> {
let original_fn = call_interface.get_original();
let original_msg_sender = cheatcodes::get_msg_sender();
let original_contract_address = cheatcodes::get_contract_address();
let original_contract_address = get_contract_address();
let target_address = call_interface.get_contract_address();

cheatcodes::set_contract_address(target_address);
cheatcodes::set_msg_sender(original_contract_address);
let mut inputs = cheatcodes::get_private_context_inputs(cheatcodes::get_block_number() - 1);
let mut inputs = cheatcodes::get_private_context_inputs(get_block_number() - 1);
inputs.call_context.function_selector = call_interface.get_selector();
inputs.call_context.is_static_call = call_interface.get_is_static();
let public_inputs = original_fn(inputs);
Expand All @@ -153,12 +153,12 @@ impl TestEnvironment {
) where C: CallInterface<M, PrivateContextInputs, PrivateCircuitPublicInputs, Env> {
let original_fn = call_interface.get_original();
let original_msg_sender = cheatcodes::get_msg_sender();
let original_contract_address = cheatcodes::get_contract_address();
let original_contract_address = get_contract_address();
let target_address = call_interface.get_contract_address();

cheatcodes::set_contract_address(target_address);
cheatcodes::set_msg_sender(original_contract_address);
let mut inputs = cheatcodes::get_private_context_inputs(cheatcodes::get_block_number() - 1);
let mut inputs = cheatcodes::get_private_context_inputs(get_block_number() - 1);
inputs.call_context.function_selector = call_interface.get_selector();
inputs.call_context.is_static_call = call_interface.get_is_static();
let public_inputs = original_fn(inputs);
Expand All @@ -175,7 +175,7 @@ impl TestEnvironment {
) -> T where C: CallInterface<M, PublicContextInputs, T, Env> {
let original_fn = call_interface.get_original();
let original_msg_sender = cheatcodes::get_msg_sender();
let original_contract_address = cheatcodes::get_contract_address();
let original_contract_address = get_contract_address();
let original_fn_selector = cheatcodes::get_function_selector();
let target_address = call_interface.get_contract_address();
let fn_selector = call_interface.get_selector();
Expand Down Expand Up @@ -225,7 +225,7 @@ impl TestEnvironment {
storage_slot: Field,
contract_address: AztecAddress
) where Note: NoteInterface<N, M> {
let original_contract_address = cheatcodes::get_contract_address();
let original_contract_address = get_contract_address();
cheatcodes::set_contract_address(contract_address);
let note_hash_counter = cheatcodes::get_side_effects_counter();

Expand Down
8 changes: 4 additions & 4 deletions noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::test::helpers::cheatcodes;
use crate::keys::public_keys::{PUBLIC_KEYS_LENGTH, PublicKeys};
use crate::hash::hash_args;

use crate::oracle::notes::notify_nullified_note;
use crate::oracle::{execution::{get_block_number, get_contract_address}, notes::notify_nullified_note};

pub fn apply_side_effects_private(contract_address: AztecAddress, public_inputs: PrivateCircuitPublicInputs) {
let mut nullifiers = &[];
Expand Down Expand Up @@ -47,10 +47,10 @@ impl<let N: u32> Deployer<N> {
);
let address = instance.to_address();
cheatcodes::advance_blocks_by(1);
let block_number = cheatcodes::get_block_number();
let block_number = get_block_number();
let original_fn = call_interface.get_original();
let original_msg_sender = cheatcodes::get_msg_sender();
let original_contract_address = cheatcodes::get_contract_address();
let original_contract_address = get_contract_address();

cheatcodes::set_contract_address(address);
cheatcodes::set_msg_sender(original_contract_address);
Expand All @@ -77,7 +77,7 @@ impl<let N: u32> Deployer<N> {
cheatcodes::advance_blocks_by(1);
let original_fn = call_interface.get_original();
let original_msg_sender = cheatcodes::get_msg_sender();
let original_contract_address = cheatcodes::get_contract_address();
let original_contract_address = get_contract_address();
let original_fn_selector = cheatcodes::get_function_selector();

cheatcodes::set_fn_selector(call_interface.get_selector());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use dep::aztec::{
test::helpers::{cheatcodes, test_environment::TestEnvironment},
protocol_types::storage::map::derive_storage_slot_in_map,
note::{note_getter::{MAX_NOTES_PER_PAGE, view_notes}, note_viewer_options::NoteViewerOptions},
oracle::{unsafe_rand::unsafe_rand, storage::storage_read}, context::PrivateContext
oracle::{execution::get_contract_address, unsafe_rand::unsafe_rand, storage::storage_read},
context::PrivateContext
};

use crate::{types::{token_note::TokenNote}, PrivateToken};
Expand Down Expand Up @@ -58,7 +59,7 @@ pub fn check_private_balance(
address: AztecAddress,
address_amount: Field
) {
let current_contract_address = cheatcodes::get_contract_address();
let current_contract_address = get_contract_address();
cheatcodes::set_contract_address(token_contract_address);

let header = context.get_header();
Expand Down
Loading

0 comments on commit 645aec1

Please sign in to comment.