Skip to content

Commit

Permalink
refactor!: remove PublicContextInputs (#8770)
Browse files Browse the repository at this point in the history
As per discussion with @Thunkar, I'm replacing `PublicContextInputs`
with `()` in the interfaces, because the `CallInterface` trait requires
an input type.
  • Loading branch information
fcarreiro authored Sep 25, 2024
1 parent 420dd64 commit 1507762
Show file tree
Hide file tree
Showing 22 changed files with 101 additions and 227 deletions.
22 changes: 9 additions & 13 deletions docs/docs/aztec/smart_contracts/functions/inner_workings.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,22 +122,19 @@ To create a public function you can annotate it with the `#[aztec(public)]` attr
Under the hood:

- Context Creation: The macro inserts code at the beginning of the function to create a`PublicContext` object:

```rust
let mut context = PublicContext::new(inputs);
let mut context = PublicContext::new(args_hasher);
```

This context provides access to public state and transaction information
- Function Signature Modification: The macro modifies the function signature to include a `PublicContextInputs` parameter:
```rust
fn function_name(inputs: PublicContextInputs, ...other_params) -> ReturnType
```
- Return Type Transformation: For functions that return a value, the macro wraps the return type in a `PublicCircuitPublicInputs` struct:
```rust
-> protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs
```

- Storage Access: If the contract has a storage struct defined, the macro inserts code to initialize the storage:

```rust
let storage = Storage::init(&mut context);
```

- Function Body Wrapping: The original function body is wrapped in a new scope that handles the context and return value
- Visibility Control: The function is marked as pub, making it accessible from outside the contract.
- Unconstrained Execution: Public functions are marked as unconstrained, meaning they don't generate proofs and are executed directly by the sequencer.
Expand Down Expand Up @@ -206,7 +203,6 @@ When a struct is annotated with `#[aztec(note)]`, the Aztec macro applies a seri

6. **Export Information**: The note type and its ID are automatically exported


### Before expansion

Here is how you could define a custom note:
Expand Down Expand Up @@ -250,7 +246,7 @@ impl CustomNote {

fn compute_note_hiding_point(self: CustomNote) -> Point {
aztec::hash::pedersen_commitment(
self.serialize_content(),
self.serialize_content(),
aztec::protocol_types::constants::GENERATOR_INDEX__NOTE_HIDING_POINT
)
}
Expand Down Expand Up @@ -291,6 +287,7 @@ struct CustomNoteProperties {
owner: aztec::note::note_getter_options::PropertySelector,
}
```

Key things to keep in mind:

- Developers can override any of the auto-generated methods by specifying a note interface
Expand Down Expand Up @@ -360,7 +357,6 @@ Key things to keep in mind:
- `Map` types and private `Note` types always occupy a single storage slot

## Further reading

- [How do macros work](./inner_workings.md)
- [Macros reference](../../../reference/developer_references/smart_contract_reference/macros.md)


3 changes: 1 addition & 2 deletions noir-projects/aztec-nr/authwit/src/cheatcodes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ pub fn add_public_authwit_from_call_interface<C, let M: u32, T, P, Env>(
let selector = call_interface.get_selector();
let inner_hash = compute_inner_authwit_hash([caller.to_field(), selector.to_field(), args_hash]);
let message_hash = compute_authwit_message_hash(target, chain_id, version, inner_hash);
let mut inputs = cheatcodes::get_public_context_inputs();
let mut context = PublicContext::new(inputs, || {panic( f"Provide args hash manually")});
let mut context = PublicContext::new(|| {panic( f"Provide args hash manually")});
context.args_hash = Option::some(args_hash);
set_authorized(&mut context, message_hash, true);
cheatcodes::set_contract_address(current_contract);
Expand Down
26 changes: 13 additions & 13 deletions noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use dep::protocol_types::{

use crate::context::{
private_context::PrivateContext, public_context::PublicContext, gas::GasOpts,
inputs::{PrivateContextInputs, PublicContextInputs}
inputs::PrivateContextInputs
};

use crate::oracle::arguments::pack_arguments;
Expand Down Expand Up @@ -164,8 +164,8 @@ impl<let N: u32, Env> PrivateStaticVoidCallInterface<N, Env> {
}
}

impl<let N: u32, T, P, Env> CallInterface<N, PublicContextInputs, T, Env> for PublicCallInterface<N, T, Env> {
fn get_original(self) -> fn[Env](PublicContextInputs) -> T {
impl<let N: u32, T, P, Env> CallInterface<N, (), T, Env> for PublicCallInterface<N, T, Env> {
fn get_original(self) -> fn[Env](()) -> T {
self.original
}
}
Expand All @@ -176,7 +176,7 @@ pub struct PublicCallInterface<let N: u32, T, Env> {
name: str<N>,
args: [Field],
gas_opts: GasOpts,
original: fn[Env](PublicContextInputs) -> T,
original: fn[Env](()) -> T,
is_static: bool
}

Expand Down Expand Up @@ -238,8 +238,8 @@ impl<let N: u32, T, Env> PublicCallInterface<N, T, Env> {
}
}

impl<let N: u32, T, P, Env> CallInterface<N, PublicContextInputs, (), Env> for PublicVoidCallInterface<N, Env> {
fn get_original(self) -> fn[Env](PublicContextInputs) -> () {
impl<let N: u32, T, P, Env> CallInterface<N, (), (), Env> for PublicVoidCallInterface<N, Env> {
fn get_original(self) -> fn[Env](()) -> () {
self.original
}
}
Expand All @@ -249,7 +249,7 @@ pub struct PublicVoidCallInterface<let N: u32, Env> {
selector: FunctionSelector,
name: str<N>,
args: [Field],
original: fn[Env](PublicContextInputs) -> (),
original: fn[Env](()) -> (),
is_static: bool,
gas_opts: GasOpts
}
Expand Down Expand Up @@ -312,8 +312,8 @@ impl<let N: u32, Env> PublicVoidCallInterface<N, Env> {
}
}

impl<let N: u32, T, P, Env> CallInterface<N, PublicContextInputs, T, Env> for PublicStaticCallInterface<N, T, Env> {
fn get_original(self) -> fn[Env](PublicContextInputs) -> T {
impl<let N: u32, T, P, Env> CallInterface<N, (), T, Env> for PublicStaticCallInterface<N, T, Env> {
fn get_original(self) -> fn[Env](()) -> T {
self.original
}
}
Expand All @@ -323,7 +323,7 @@ pub struct PublicStaticCallInterface<let N: u32, T, Env> {
selector: FunctionSelector,
name: str<N>,
args: [Field],
original: fn[Env](PublicContextInputs) -> T,
original: fn[Env](()) -> T,
is_static: bool,
gas_opts: GasOpts
}
Expand Down Expand Up @@ -353,8 +353,8 @@ impl<let N: u32, T, Env> PublicStaticCallInterface<N, T, Env> {
}
}

impl<let N: u32, T, P, Env> CallInterface<N, PublicContextInputs, (), Env> for PublicStaticVoidCallInterface<N, Env> {
fn get_original(self) -> fn[Env](PublicContextInputs) -> () {
impl<let N: u32, T, P, Env> CallInterface<N, (), (), Env> for PublicStaticVoidCallInterface<N, Env> {
fn get_original(self) -> fn[Env](()) -> () {
self.original
}
}
Expand All @@ -364,7 +364,7 @@ pub struct PublicStaticVoidCallInterface<let N: u32, Env> {
selector: FunctionSelector,
name: str<N>,
args: [Field],
original: fn[Env](PublicContextInputs) -> (),
original: fn[Env](()) -> (),
is_static: bool,
gas_opts: GasOpts
}
Expand Down
2 changes: 0 additions & 2 deletions noir-projects/aztec-nr/aztec/src/context/inputs/mod.nr
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
mod private_context_inputs;
mod public_context_inputs;

pub use crate::context::inputs::private_context_inputs::PrivateContextInputs;
pub use crate::context::inputs::public_context_inputs::PublicContextInputs;

This file was deleted.

8 changes: 3 additions & 5 deletions noir-projects/aztec-nr/aztec/src/context/public_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@ use dep::protocol_types::address::{AztecAddress, EthAddress};
use dep::protocol_types::constants::MAX_FIELD_VALUE;
use dep::protocol_types::traits::{Serialize, Deserialize, Empty};
use dep::protocol_types::abis::function_selector::FunctionSelector;
use crate::context::inputs::public_context_inputs::PublicContextInputs;
use crate::context::gas::GasOpts;
use crate::hash::ArgsHasher;

pub struct PublicContext {
inputs: PublicContextInputs,
args_hash: Option<Field>,
compute_args_hash: fn () -> Field,
}

impl PublicContext {
pub fn new(inputs: PublicContextInputs, compute_args_hash: fn() -> Field) -> Self {
PublicContext { inputs, args_hash: Option::none(), compute_args_hash }
pub fn new(compute_args_hash: fn() -> Field) -> Self {
PublicContext { args_hash: Option::none(), compute_args_hash }
}

pub fn emit_unencrypted_log<T, let N: u32>(_self: &mut Self, log: T) where T: Serialize<N> {
Expand Down Expand Up @@ -308,7 +306,7 @@ unconstrained fn storage_write(storage_slot: Field, value: Field) {

impl Empty for PublicContext {
fn empty() -> Self {
PublicContext::new(PublicContextInputs::empty(), || 0)
PublicContext::new(|| 0)
}
}

Expand Down
16 changes: 9 additions & 7 deletions noir-projects/aztec-nr/aztec/src/macros/functions/interfaces.nr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ comptime mut global STUBS: UHashMap<Module, [Quoted], BuildHasherDefault<Poseido

pub(crate) comptime fn create_fn_abi_export(f: FunctionDefinition) -> Quoted {
let name = f.name();
// Remove first arg (inputs)
let mut parameters = f.parameters().map(
| (name, typ): (Quoted, Type) | {
quote { $name: $typ }
Expand Down Expand Up @@ -129,21 +128,24 @@ pub comptime fn stub_fn(f: FunctionDefinition) -> Quoted {
quote {}
};

let input_type = f"crate::context::inputs::{fn_visibility_capitalized}ContextInputs".quoted_contents().as_type();
let input_type = if is_fn_private(f) {
quote { crate::context::inputs::PrivateContextInputs }.as_type()
} else {
quote { () }.as_type()
};

let return_type_hint = if is_fn_private(f) {
quote { protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs }.as_type()
} else {
fn_return_type
};

let parameter_names = if fn_parameters.len() > 0 {
let params = fn_parameters.map(|(name, _): (Quoted, _)| name).join(quote {,});
quote { inputs, $params }
let mut parameter_names_list = fn_parameters.map(|(name, _): (Quoted, _)| name);
let parameter_names = if is_fn_private(f) {
&[quote {inputs}].append(parameter_names_list).join(quote{,})
} else {
quote {inputs}
parameter_names_list.join(quote {,})
};

let original = quote {
| inputs: $input_type | -> $return_type_hint {
$fn_name($parameter_names)
Expand Down
22 changes: 4 additions & 18 deletions noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ comptime fn create_view_check(f: FunctionDefinition) -> Quoted {
quote { assert(context.inputs.call_context.is_static_call == true, $assertion_message); }
} else {
// Here `context` is of type context::PublicContext
quote { assert(context.inputs.is_static_call == true, $assertion_message); }
quote { assert(context.is_static_call(), $assertion_message); }
}
}

Expand Down Expand Up @@ -232,31 +232,17 @@ pub comptime fn public(f: FunctionDefinition) -> Quoted {
let module_has_initializer = module_has_initializer(f.module());
let module_has_storage = module_has_storage(f.module());

// Public functions undergo a lot of transformations from their Aztec.nr form into a circuit that can be fed to the
// Public Kernel Circuit.

// First we change the function signature so that it also receives `PublicContextInputs`, which contain information
// about the execution context (e.g. the caller).

// Public functions undergo a lot of transformations from their Aztec.nr form.
let original_params = f.parameters();
f.set_parameters(
&[
(
quote { inputs }, quote { crate::context::inputs::public_context_inputs::PublicContextInputs }.as_type()
)
].append(original_params)
);

let args_len = original_params.map(|(name, typ): (Quoted, Type)| flatten_to_fields(name, typ, &[]).0.len()).fold(0, |acc: u32, val: u32| acc + val);

// Unlike in the private case, in public the `context` does not need to receive the hash of the original params.
let context_creation = quote { let mut context = dep::aztec::context::public_context::PublicContext::new(inputs, || {
let serialized_args : [Field; $args_len] = dep::aztec::context::public_context::calldata_copy(2, $args_len);
let context_creation = quote { let mut context = dep::aztec::context::public_context::PublicContext::new(|| {
let serialized_args : [Field; $args_len] = dep::aztec::context::public_context::calldata_copy(0, $args_len);
dep::aztec::hash::hash_args_array(serialized_args)
}); };

// Modifications introduced by the different marker attributes.

let internal_check = if is_fn_internal(f) {
create_internal_check(f)
} else {
Expand Down
9 changes: 1 addition & 8 deletions noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use dep::protocol_types::{
abis::function_selector::FunctionSelector, address::AztecAddress,
constants::CONTRACT_INSTANCE_LENGTH, contract_instance::ContractInstance
};
use crate::context::inputs::{PublicContextInputs, PrivateContextInputs};
use crate::context::inputs::PrivateContextInputs;
use crate::test::helpers::utils::TestAccount;
use crate::keys::public_keys::PublicKeys;

Expand All @@ -22,10 +22,6 @@ unconstrained pub fn get_private_context_inputs(historical_block_number: u32) ->
oracle_get_private_context_inputs(historical_block_number)
}

unconstrained pub fn get_public_context_inputs() -> PublicContextInputs {
oracle_get_public_context_inputs()
}

unconstrained pub fn deploy<let N: u32, let M: u32, let P: u32>(
path: str<N>,
name: str<M>,
Expand Down Expand Up @@ -127,9 +123,6 @@ unconstrained fn oracle_advance_blocks_by(blocks: u32) {}
#[oracle(getPrivateContextInputs)]
unconstrained fn oracle_get_private_context_inputs(historical_block_number: u32) -> PrivateContextInputs {}

#[oracle(getPublicContextInputs)]
unconstrained fn oracle_get_public_context_inputs() -> PublicContextInputs {}

#[oracle(deploy)]
unconstrained fn oracle_deploy<let N: u32, let M: u32, let P: u32>(
path: str<N>,
Expand Down
17 changes: 5 additions & 12 deletions noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use dep::protocol_types::{
address::AztecAddress, traits::Deserialize
};

use crate::context::inputs::{PublicContextInputs, PrivateContextInputs};
use crate::context::inputs::PrivateContextInputs;
use crate::context::{packed_returns::PackedReturns, call_interfaces::CallInterface};

use crate::context::{PrivateContext, PublicContext, UnconstrainedContext};
Expand Down Expand Up @@ -43,8 +43,7 @@ impl TestEnvironment {
}

unconstrained fn public(_self: Self) -> PublicContext {
let mut inputs = cheatcodes::get_public_context_inputs();
PublicContext::new(inputs, || 0)
PublicContext::new(|| 0)
}

unconstrained fn private(&mut self) -> PrivateContext {
Expand Down Expand Up @@ -137,10 +136,7 @@ impl TestEnvironment {
PackedReturns::new(public_inputs.returns_hash).assert_empty();
}

unconstrained fn call_public<C, let M: u32, T, Env>(
_self: Self,
call_interface: C
) -> T where C: CallInterface<M, PublicContextInputs, T, Env> {
unconstrained fn call_public<C, let M: u32, T, Env>(_self: Self, call_interface: C) -> T where C: CallInterface<M, (), T, Env> {
let original_fn = call_interface.get_original();
let original_msg_sender = cheatcodes::get_msg_sender();
let original_contract_address = get_contract_address();
Expand All @@ -153,12 +149,9 @@ impl TestEnvironment {
cheatcodes::set_contract_address(target_address);
cheatcodes::set_msg_sender(original_contract_address);
cheatcodes::set_is_static_call(call_interface.get_is_static());
let mut inputs = cheatcodes::get_public_context_inputs();
inputs.calldata_length = call_interface.get_args().len() as Field;
inputs.is_static_call = call_interface.get_is_static();
cheatcodes::set_calldata(calldata);

let result = original_fn(inputs);
let result = original_fn(());

cheatcodes::set_fn_selector(original_fn_selector);
cheatcodes::set_contract_address(original_contract_address);
Expand All @@ -171,7 +164,7 @@ impl TestEnvironment {
unconstrained fn assert_public_call_fails<C, let M: u32, T, Env>(
_self: Self,
call_interface: C
) where C: CallInterface<M, PublicContextInputs, T, Env> {
) where C: CallInterface<M, (), T, Env> {
cheatcodes::assert_public_call_fails(
call_interface.get_contract_address(),
call_interface.get_selector(),
Expand Down
Loading

0 comments on commit 1507762

Please sign in to comment.