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!: TXE single execution env #9183

Merged
merged 23 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2900390
removed direct noir calls
Thunkar Oct 11, 2024
67fd3fa
more cleanup
Thunkar Oct 11, 2024
725f2e6
more cleanup
Thunkar Oct 11, 2024
0640f2a
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Oct 11, 2024
eec0c40
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Oct 14, 2024
f0e9846
fixes
Thunkar Oct 15, 2024
9d0d9f0
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Oct 15, 2024
e581fb8
fmt and fixes
Thunkar Oct 15, 2024
aa5c50b
docs
Thunkar Oct 15, 2024
20e91a2
unify simulation error handling
Thunkar Oct 16, 2024
8ed69e6
fmt
Thunkar Oct 16, 2024
2027fba
comments from review
Thunkar Oct 17, 2024
70b1319
Merge branch 'master' into gj/txe_single_execution_env
Thunkar Oct 17, 2024
22da773
removed dep
Thunkar Oct 17, 2024
9e84eca
Merge branch 'gj/txe_single_execution_env' of github.com:AztecProtoco…
Thunkar Oct 17, 2024
e030e09
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Oct 18, 2024
4c2778a
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Oct 18, 2024
d174d0c
Update yarn-project/pxe/src/pxe_service/error_enriching.ts
Thunkar Oct 23, 2024
1439b09
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Oct 23, 2024
75fda87
fix
Thunkar Oct 23, 2024
268ff71
fix
Thunkar Oct 23, 2024
095f2af
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Thunkar Oct 23, 2024
070edb9
fixes
Thunkar Oct 23, 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
10 changes: 3 additions & 7 deletions noir-projects/aztec-nr/authwit/src/cheatcodes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use dep::aztec::{

use crate::auth::{compute_inner_authwit_hash, compute_authwit_message_hash, set_authorized};

pub fn add_private_authwit_from_call_interface<C, let M: u32, T, P, Env>(
pub fn add_private_authwit_from_call_interface<C, let M: u32, T>(
on_behalf_of: AztecAddress,
caller: AztecAddress,
call_interface: C
) where C: CallInterface<M, T, P, Env> {
) where C: CallInterface<M, T> {
let target = call_interface.get_contract_address();
let inputs = cheatcodes::get_private_context_inputs(get_block_number());
let chain_id = inputs.tx_context.chain_id;
Expand All @@ -22,11 +22,7 @@ pub fn add_private_authwit_from_call_interface<C, let M: u32, T, P, Env>(
cheatcodes::add_authwit(on_behalf_of, message_hash);
}

pub fn add_public_authwit_from_call_interface<C, let M: u32, T, P, Env>(
on_behalf_of: AztecAddress,
caller: AztecAddress,
call_interface: C
) where C: CallInterface<M, T, P, Env> {
pub fn add_public_authwit_from_call_interface<C, let M: u32, T>(on_behalf_of: AztecAddress, caller: AztecAddress, call_interface: C) where C: CallInterface<M, T> {
let current_contract = get_contract_address();
cheatcodes::set_contract_address(on_behalf_of);
let target = call_interface.get_contract_address();
Expand Down
100 changes: 33 additions & 67 deletions noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ use crate::context::{
use crate::oracle::arguments::pack_arguments;
use crate::hash::hash_args;

pub trait CallInterface<let N: u32, T, P, Env> {
fn get_original(self) -> fn[Env](T) -> P;

pub trait CallInterface<let N: u32, T> {
fn get_args(self) -> [Field] {
self.args
}
Expand All @@ -35,23 +33,19 @@ pub trait CallInterface<let N: u32, T, P, Env> {
}
}

impl<let N: u32, T, P, Env> CallInterface<N, PrivateContextInputs, PrivateCircuitPublicInputs, Env> for PrivateCallInterface<N, T, Env> {
fn get_original(self) -> fn[Env](PrivateContextInputs) -> PrivateCircuitPublicInputs {
self.original
}
}
impl<let N: u32, T, P> CallInterface<N, T> for PrivateCallInterface<N, T> {}

pub struct PrivateCallInterface<let N: u32, T, Env> {
pub struct PrivateCallInterface<let N: u32, T> {
target_contract: AztecAddress,
selector: FunctionSelector,
name: str<N>,
args_hash: Field,
args: [Field],
original: fn[Env](PrivateContextInputs) -> PrivateCircuitPublicInputs,
return_type: T,
is_static: bool
}

impl<let N: u32, T, Env> PrivateCallInterface<N, T, Env> {
impl<let N: u32, T> PrivateCallInterface<N, T> {
pub fn call<let M: u32>(self, context: &mut PrivateContext) -> T where T: Deserialize<M> {
pack_arguments(self.args);
let returns = context.call_private_function_with_packed_args(
Expand All @@ -78,23 +72,19 @@ impl<let N: u32, T, Env> PrivateCallInterface<N, T, Env> {
}
}

impl<let N: u32, T, P, Env> CallInterface<N, PrivateContextInputs, PrivateCircuitPublicInputs, Env> for PrivateVoidCallInterface<N, Env> {
fn get_original(self) -> fn[Env](PrivateContextInputs) -> PrivateCircuitPublicInputs {
self.original
}
}
impl<let N: u32, T, P> CallInterface<N, ()> for PrivateVoidCallInterface<N> {}

pub struct PrivateVoidCallInterface<let N: u32, Env> {
pub struct PrivateVoidCallInterface<let N: u32> {
target_contract: AztecAddress,
selector: FunctionSelector,
name: str<N>,
args_hash: Field,
args: [Field],
original: fn[Env](PrivateContextInputs) -> PrivateCircuitPublicInputs,
return_type: (),
is_static: bool
}

impl<let N: u32, Env> PrivateVoidCallInterface<N, Env> {
impl<let N: u32> PrivateVoidCallInterface<N> {
pub fn call(self, context: &mut PrivateContext) {
pack_arguments(self.args);
context.call_private_function_with_packed_args(
Expand All @@ -117,70 +107,58 @@ impl<let N: u32, Env> PrivateVoidCallInterface<N, Env> {
}
}

impl<let N: u32, T, P, Env> CallInterface<N, PrivateContextInputs, PrivateCircuitPublicInputs, Env> for PrivateStaticCallInterface<N, T, Env> {
fn get_original(self) -> fn[Env](PrivateContextInputs) -> PrivateCircuitPublicInputs {
self.original
}
}
impl<let N: u32, T, P> CallInterface<N, T> for PrivateStaticCallInterface<N, T> {}

pub struct PrivateStaticCallInterface<let N: u32, T, Env> {
pub struct PrivateStaticCallInterface<let N: u32, T> {
target_contract: AztecAddress,
selector: FunctionSelector,
name: str<N>,
args_hash: Field,
args: [Field],
original: fn[Env](PrivateContextInputs) -> PrivateCircuitPublicInputs,
return_type: T,
is_static: bool
}

impl<let N: u32, T, Env> PrivateStaticCallInterface<N, T, Env> {
impl<let N: u32, T> PrivateStaticCallInterface<N, T> {
pub fn view<let M: u32>(self, context: &mut PrivateContext) -> T where T: Deserialize<M> {
pack_arguments(self.args);
let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false);
returns.unpack_into()
}
}

impl<let N: u32, T, P, Env> CallInterface<N, PrivateContextInputs, PrivateCircuitPublicInputs, Env> for PrivateStaticVoidCallInterface<N, Env> {
fn get_original(self) -> fn[Env](PrivateContextInputs) -> PrivateCircuitPublicInputs {
self.original
}
}
impl<let N: u32, T, P> CallInterface<N, ()> for PrivateStaticVoidCallInterface<N> {}

pub struct PrivateStaticVoidCallInterface<let N: u32, Env> {
pub struct PrivateStaticVoidCallInterface<let N: u32> {
target_contract: AztecAddress,
selector: FunctionSelector,
name: str<N>,
args_hash: Field,
args: [Field],
original: fn[Env](PrivateContextInputs) -> PrivateCircuitPublicInputs,
return_type: (),
is_static: bool
}

impl<let N: u32, Env> PrivateStaticVoidCallInterface<N, Env> {
impl<let N: u32> PrivateStaticVoidCallInterface<N> {
pub fn view(self, context: &mut PrivateContext) {
pack_arguments(self.args);
context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false).assert_empty();
}
}

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
}
}
impl<let N: u32, T, P> CallInterface<N, T> for PublicCallInterface<N, T> {}

pub struct PublicCallInterface<let N: u32, T, Env> {
pub struct PublicCallInterface<let N: u32, T> {
target_contract: AztecAddress,
selector: FunctionSelector,
name: str<N>,
args: [Field],
gas_opts: GasOpts,
original: fn[Env](()) -> T,
return_type: T,
is_static: bool
}

impl<let N: u32, T, Env> PublicCallInterface<N, T, Env> {
impl<let N: u32, T> PublicCallInterface<N, T> {
pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {
self.gas_opts = gas_opts;
self
Expand Down Expand Up @@ -238,23 +216,19 @@ impl<let N: u32, T, Env> PublicCallInterface<N, T, Env> {
}
}

impl<let N: u32, T, P, Env> CallInterface<N, (), (), Env> for PublicVoidCallInterface<N, Env> {
fn get_original(self) -> fn[Env](()) -> () {
self.original
}
}
impl<let N: u32, T, P> CallInterface<N, ()> for PublicVoidCallInterface<N> {}

pub struct PublicVoidCallInterface<let N: u32, Env> {
pub struct PublicVoidCallInterface<let N: u32> {
target_contract: AztecAddress,
selector: FunctionSelector,
name: str<N>,
args: [Field],
original: fn[Env](()) -> (),
return_type: (),
is_static: bool,
gas_opts: GasOpts
}

impl<let N: u32, Env> PublicVoidCallInterface<N, Env> {
impl<let N: u32> PublicVoidCallInterface<N> {
pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {
self.gas_opts = gas_opts;
self
Expand Down Expand Up @@ -312,23 +286,19 @@ impl<let N: u32, Env> PublicVoidCallInterface<N, Env> {
}
}

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
}
}
impl<let N: u32, T, P> CallInterface<N, T> for PublicStaticCallInterface<N, T> {}

pub struct PublicStaticCallInterface<let N: u32, T, Env> {
pub struct PublicStaticCallInterface<let N: u32, T> {
target_contract: AztecAddress,
selector: FunctionSelector,
name: str<N>,
args: [Field],
original: fn[Env](()) -> T,
return_type: T,
is_static: bool,
gas_opts: GasOpts
}

impl<let N: u32, T, Env> PublicStaticCallInterface<N, T, Env> {
impl<let N: u32, T> PublicStaticCallInterface<N, T> {
pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {
self.gas_opts = gas_opts;
self
Expand All @@ -353,23 +323,19 @@ impl<let N: u32, T, Env> PublicStaticCallInterface<N, T, Env> {
}
}

impl<let N: u32, T, P, Env> CallInterface<N, (), (), Env> for PublicStaticVoidCallInterface<N, Env> {
fn get_original(self) -> fn[Env](()) -> () {
self.original
}
}
impl<let N: u32, T, P> CallInterface<N, ()> for PublicStaticVoidCallInterface<N> {}

pub struct PublicStaticVoidCallInterface<let N: u32, Env> {
pub struct PublicStaticVoidCallInterface<let N: u32> {
target_contract: AztecAddress,
selector: FunctionSelector,
name: str<N>,
args: [Field],
original: fn[Env](()) -> (),
return_type: (),
is_static: bool,
gas_opts: GasOpts
}

impl<let N: u32, Env> PublicStaticVoidCallInterface<N, Env> {
impl<let N: u32> PublicStaticVoidCallInterface<N> {
pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {
self.gas_opts = gas_opts;
self
Expand Down
46 changes: 3 additions & 43 deletions noir-projects/aztec-nr/aztec/src/macros/functions/interfaces.nr
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,10 @@ pub comptime fn stub_fn(f: FunctionDefinition) -> Quoted {

let fn_name_len: u32 = unquote!(quote { $fn_name_str.as_bytes().len()});

let arg_types_list: Quoted = fn_parameters.map(|(_, typ): (_, Type)| quote { $typ }).join(quote {,});
let arg_types = if fn_parameters.len() == 1 {
// Extra colon to avoid it being interpreted as a parenthesized expression instead of a tuple
quote { ($arg_types_list,) }
} else {
quote { ($arg_types_list) }
};

let call_interface_generics = if is_void {
quote { $fn_name_len, $arg_types }
quote { $fn_name_len }
} else {
quote { $fn_name_len, $fn_return_type, $arg_types }
quote { $fn_name_len, $fn_return_type }
};

let call_interface_name = f"dep::aztec::context::call_interfaces::{fn_visibility_capitalized}{is_static_call_capitalized}{is_void_capitalized}CallInterface".quoted_contents();
Expand All @@ -128,38 +120,6 @@ pub comptime fn stub_fn(f: FunctionDefinition) -> Quoted {
quote {}
};

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 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 {
parameter_names_list.join(quote {,})
};
let original = if is_fn_private(f) {
quote {
| inputs: $input_type | -> $return_type_hint {
$fn_name($parameter_names)
}
}
} else {
quote {
| _: $input_type | -> $return_type_hint {
unsafe { $fn_name($parameter_names) }
}
}
};

let args_hash = if fn_visibility == quote { private } {
quote { $args_hash_name, }
} else {
Expand All @@ -176,7 +136,7 @@ pub comptime fn stub_fn(f: FunctionDefinition) -> Quoted {
name: $fn_name_str,
$args_hash
args: $args_acc_name,
original: $original,
return_type: std::mem::zeroed(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this

Copy link
Contributor Author

@Thunkar Thunkar Oct 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call interfaces were sort of broken before. Return value types were unbound and that led to weird situations such as:

#[private]
fn my_fn() -> u8 {...}

...

#[test]
fn test_my_fn() {
  let result = MyContract::at(somewhere).my_fn().call(&mut env.private());
  assert(result == 8 // this is a Field, so result is cast to Field);
}

return_value in the call interfaces is essentially rust's PhantomData, so we are able to properly type the return value of the call interface (both in TXE and actual contracts)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I understood this, and did some reading around on PhantomData, but then tried to write down a comment explaining why zeroed needs to be there and failed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's similar to when we needed array hints in methods for length...we need a return_type variable with the correct Type, but we don't know what the actual value is (because we haven't called the function yet)

is_static: $is_static_call,
$gas_opts
}
Expand Down
Loading
Loading