Skip to content

Commit

Permalink
feat(aztec-nr): add 'with_gas()' function to avm call interface (#6256)
Browse files Browse the repository at this point in the history
The default/simple case is
`Token::at(address).transfer_public(...).call(&mut context)`, and now if
you want to specify gas you'd do
`Token::at(address).transfer_public(...).with_gas(GasOpts::new(l2_gas,
da_gas)).call(&mut context)`.

This gives us the following:
1. Clean base case when all you want to do is `call()`
2. A way to specify gas without resorting to the lower level interface
(`context.call_public_function`)
3. `PublicCallInterface` doesn't need to change at all, and users just
won't be able to specify gas on it
  • Loading branch information
dbanks12 authored May 8, 2024
1 parent 4b4f3c6 commit 0aedd23
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 18 deletions.
32 changes: 20 additions & 12 deletions noir-projects/aztec-nr/aztec/src/context/interface.nr
Original file line number Diff line number Diff line change
Expand Up @@ -206,20 +206,22 @@ struct AvmCallInterface<T> {
target_contract: AztecAddress,
selector: FunctionSelector,
args: [Field],
gas_opts: GasOpts,
}

impl<T> AvmCallInterface<T> {
pub fn call<N>(self, context: &mut AvmContext, gas_opts: GasOpts) -> T where T: Deserialize<N> {
let returns = context.call_public_function(self.target_contract, self.selector, self.args, gas_opts);
pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {
self.gas_opts = gas_opts;
self
}

pub fn call<N>(self, context: &mut AvmContext) -> T where T: Deserialize<N> {
let returns = context.call_public_function(self.target_contract, self.selector, self.args, self.gas_opts);
returns.deserialize_into()
}

pub fn static_call<N>(
self,
context: &mut AvmContext,
gas_opts: GasOpts
) -> T where T: Deserialize<N> {
let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, gas_opts);
pub fn static_call<N>(self, context: &mut AvmContext) -> T where T: Deserialize<N> {
let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts);
returns.deserialize_into()
}

Expand All @@ -233,16 +235,22 @@ struct AvmVoidCallInterface {
target_contract: AztecAddress,
selector: FunctionSelector,
args: [Field],
gas_opts: GasOpts,
}

impl AvmVoidCallInterface {
pub fn call<N>(self, context: &mut AvmContext, gas_opts: GasOpts) {
let returns = context.call_public_function(self.target_contract, self.selector, self.args, gas_opts);
pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {
self.gas_opts = gas_opts;
self
}

pub fn call<N>(self, context: &mut AvmContext) {
let returns = context.call_public_function(self.target_contract, self.selector, self.args, self.gas_opts);
returns.assert_empty()
}

pub fn static_call<N>(self, context: &mut AvmContext, gas_opts: GasOpts) {
let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, gas_opts);
pub fn static_call<N>(self, context: &mut AvmContext) {
let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts);
returns.assert_empty()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,36 +40,36 @@ contract AvmNestedCallsTest {
l2_gas: Field,
da_gas: Field
) -> pub Field {
AvmNestedCallsTest::at(context.this_address()).add_args_return(arg_a, arg_b).call(&mut context, GasOpts::new(l2_gas, da_gas))
AvmNestedCallsTest::at(context.this_address()).add_args_return(arg_a, arg_b).with_gas(GasOpts::new(l2_gas, da_gas)).call(&mut context)
}

// Use the `call_public_function` wrapper to initiate a nested call to the add function
#[aztec(public-vm)]
fn nested_call_to_add(arg_a: Field, arg_b: Field) -> pub Field {
AvmNestedCallsTest::at(context.this_address()).add_args_return(arg_a, arg_b).call(&mut context, GasOpts::default())
AvmNestedCallsTest::at(context.this_address()).add_args_return(arg_a, arg_b).call(&mut context)
}

// Indirectly call_static the external call opcode to initiate a nested call to the add function
#[aztec(public-vm)]
fn nested_static_call_to_add(arg_a: Field, arg_b: Field) -> pub Field {
AvmNestedCallsTest::at(context.this_address()).add_args_return(arg_a, arg_b).static_call(&mut context, GasOpts::default())
AvmNestedCallsTest::at(context.this_address()).add_args_return(arg_a, arg_b).static_call(&mut context)
}

// Indirectly call_static `set_storage_single`. Should revert since it's accessing storage.
#[aztec(public-vm)]
fn nested_static_call_to_set_storage() {
AvmNestedCallsTest::at(context.this_address()).set_storage_single(20).static_call(&mut context, GasOpts::default());
AvmNestedCallsTest::at(context.this_address()).set_storage_single(20).static_call(&mut context);
}

#[aztec(public-vm)]
fn create_same_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) {
context.push_new_nullifier(nullifier, 0);
AvmNestedCallsTest::at(nestedAddress).new_nullifier(nullifier).call(&mut context, GasOpts::default());
AvmNestedCallsTest::at(nestedAddress).new_nullifier(nullifier).call(&mut context);
}

#[aztec(public-vm)]
fn create_different_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) {
context.push_new_nullifier(nullifier, 0);
AvmNestedCallsTest::at(nestedAddress).new_nullifier(nullifier + 1).call(&mut context, GasOpts::default());
AvmNestedCallsTest::at(nestedAddress).new_nullifier(nullifier + 1).call(&mut context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction) -> String {
target_contract: self.target_contract,
selector: {},
args: args_acc,
gas_opts: dep::aztec::context::gas::GasOpts::default(),
}}",
args, is_void, fn_selector,
);
Expand Down

0 comments on commit 0aedd23

Please sign in to comment.