Skip to content

Commit

Permalink
feat: static call support in aztec.nr and acir-simulator (#4106)
Browse files Browse the repository at this point in the history
Closes AztecProtocol/aztec-packages#4036,
AztecProtocol/aztec-packages#2872

Added support for static calls, making sure callcontext is properly
forwarded and checked in the simulator before reaching the kernel
circuits.
  • Loading branch information
superstar0402 committed Mar 19, 2024
1 parent 1c212a2 commit 76396d0
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 26 deletions.
14 changes: 12 additions & 2 deletions authwit/src/entrypoint/app.nr
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,19 @@ impl AppPayload {
for call in self.function_calls {
if !call.target_address.is_zero() {
if call.is_public {
context.call_public_function_with_packed_args(call.target_address, call.function_selector, call.args_hash);
context.call_public_function_with_packed_args(
call.target_address,
call.function_selector,
call.args_hash,
false
);
} else {
let _result = context.call_private_function_with_packed_args(call.target_address, call.function_selector, call.args_hash);
let _result = context.call_private_function_with_packed_args(
call.target_address,
call.function_selector,
call.args_hash,
false
);
}
}
}
Expand Down
14 changes: 12 additions & 2 deletions authwit/src/entrypoint/fee.nr
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,19 @@ impl FeePayload {
for call in self.function_calls {
if !call.target_address.is_zero() {
if call.is_public {
context.call_public_function_with_packed_args(call.target_address, call.function_selector, call.args_hash);
context.call_public_function_with_packed_args(
call.target_address,
call.function_selector,
call.args_hash,
false
);
} else {
let _result = context.call_private_function_with_packed_args(call.target_address, call.function_selector, call.args_hash);
let _result = context.call_private_function_with_packed_args(
call.target_address,
call.function_selector,
call.args_hash,
false
);
}
}
}
Expand Down
64 changes: 53 additions & 11 deletions aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -249,28 +249,49 @@ impl PrivateContext {
) -> [Field; RETURN_VALUES_LENGTH] {
let args_hash = hash_args(args);
assert(args_hash == arguments::pack_arguments(args));
self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)
self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, false)
}

pub fn call_private_function_static<ARGS_COUNT>(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args: [Field; ARGS_COUNT]
) -> [Field; RETURN_VALUES_LENGTH] {
let args_hash = hash_args(args);
assert(args_hash == arguments::pack_arguments(args));
self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, true)
}

pub fn call_private_function_no_args(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector
) -> [Field; RETURN_VALUES_LENGTH] {
self.call_private_function_with_packed_args(contract_address, function_selector, 0)
self.call_private_function_with_packed_args(contract_address, function_selector, 0, false)
}

pub fn call_private_function_no_args_static(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector
) -> [Field; RETURN_VALUES_LENGTH] {
self.call_private_function_with_packed_args(contract_address, function_selector, 0, true)
}

pub fn call_private_function_with_packed_args(
fn call_private_function_with_packed_args(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field
args_hash: Field,
is_static_call: bool
) -> [Field; RETURN_VALUES_LENGTH] {
let item = call_private_function_internal(
contract_address,
function_selector,
args_hash,
self.side_effect_counter
self.side_effect_counter,
is_static_call
);

assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);
Expand All @@ -286,7 +307,7 @@ impl PrivateContext {
// the msg_sender in the nested call to be equal to our address, and the execution context address
// for the nested call to be equal to the address we actually called.
assert(item.public_inputs.call_context.is_delegate_call == false);
assert(item.public_inputs.call_context.is_static_call == false);
assert(item.public_inputs.call_context.is_static_call == is_static_call);
assert(item.public_inputs.call_context.is_contract_deployment == false);
assert(
item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)
Expand All @@ -306,28 +327,49 @@ impl PrivateContext {
) {
let args_hash = hash_args(args);
assert(args_hash == arguments::pack_arguments(args));
self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)
self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false)
}

pub fn call_public_function_static<ARGS_COUNT>(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args: [Field; ARGS_COUNT]
) {
let args_hash = hash_args(args);
assert(args_hash == arguments::pack_arguments(args));
self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, true)
}

pub fn call_public_function_no_args(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector
) {
self.call_public_function_with_packed_args(contract_address, function_selector, 0)
self.call_public_function_with_packed_args(contract_address, function_selector, 0, false)
}

pub fn call_public_function_no_args_static(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector
) {
self.call_public_function_with_packed_args(contract_address, function_selector, 0, true)
}

pub fn call_public_function_with_packed_args(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field
args_hash: Field,
is_static_call: bool
) {
let fields = enqueue_public_function_call_internal(
contract_address,
function_selector,
args_hash,
self.side_effect_counter
self.side_effect_counter,
is_static_call
);

let mut reader = Reader::new(fields);
Expand Down Expand Up @@ -370,7 +412,7 @@ impl PrivateContext {
// the msg_sender in the nested call to be equal to our address, and the execution context address
// for the nested call to be equal to the address we actually called.
assert(item.public_inputs.call_context.is_delegate_call == false);
assert(item.public_inputs.call_context.is_static_call == false);
assert(item.public_inputs.call_context.is_static_call == is_static_call);
assert(item.public_inputs.call_context.is_contract_deployment == false);
assert(
item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)
Expand Down
43 changes: 41 additions & 2 deletions aztec/src/context/public_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,53 @@ impl PublicContext {
) -> [Field; RETURN_VALUES_LENGTH] {
let args_hash = hash_args(args);
assert(args_hash == arguments::pack_arguments(args));
call_public_function_internal(contract_address, function_selector, args_hash)
call_public_function_internal(
contract_address,
function_selector,
args_hash,
false
)
}

pub fn call_public_function_static<ARGS_COUNT>(
_self: Self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args: [Field; ARGS_COUNT],
) -> [Field; RETURN_VALUES_LENGTH] {
let args_hash = hash_args(args);
assert(args_hash == arguments::pack_arguments(args));
call_public_function_internal(
contract_address,
function_selector,
args_hash,
true
)
}

pub fn call_public_function_no_args(
_self: Self,
contract_address: AztecAddress,
function_selector: FunctionSelector
) -> [Field; RETURN_VALUES_LENGTH] {
call_public_function_internal(contract_address, function_selector, 0)
call_public_function_internal(
contract_address,
function_selector,
0,
false,
)
}

pub fn call_public_function_no_args_static(
_self: Self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
) -> [Field; RETURN_VALUES_LENGTH] {
call_public_function_internal(
contract_address,
function_selector,
0,
true,
)
}
}
9 changes: 6 additions & 3 deletions aztec/src/oracle/call_private_function.nr
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ fn call_private_function_oracle(
_contract_address: AztecAddress,
_function_selector: FunctionSelector,
_args_hash: Field,
_start_side_effect_counter: u32
_start_side_effect_counter: u32,
_is_static_call: bool
) -> [Field; PRIVATE_CALL_STACK_ITEM_LENGTH] {}

unconstrained pub fn call_private_function_internal(
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field,
start_side_effect_counter: u32
start_side_effect_counter: u32,
is_static_call: bool
) -> PrivateCallStackItem {
let fields = call_private_function_oracle(
contract_address,
function_selector,
args_hash,
start_side_effect_counter
start_side_effect_counter,
is_static_call
);

PrivateCallStackItem::deserialize(fields)
Expand Down
9 changes: 6 additions & 3 deletions aztec/src/oracle/enqueue_public_function_call.nr
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,22 @@ fn enqueue_public_function_call_oracle(
_contract_address: AztecAddress,
_function_selector: FunctionSelector,
_args_hash: Field,
_side_effect_counter: u32
_side_effect_counter: u32,
_is_static_call: bool
) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {}

unconstrained pub fn enqueue_public_function_call_internal(
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field,
side_effect_counter: u32
side_effect_counter: u32,
is_static_call: bool
) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {
enqueue_public_function_call_oracle(
contract_address,
function_selector,
args_hash,
side_effect_counter
side_effect_counter,
is_static_call
)
}
8 changes: 5 additions & 3 deletions aztec/src/oracle/public_call.nr
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ use dep::protocol_types::{abis::function_selector::FunctionSelector, address::Az
fn call_public_function_oracle(
_contract_address: AztecAddress,
_function_selector: FunctionSelector,
_args_hash: Field
_args_hash: Field,
_is_static_call: bool
) -> [Field; RETURN_VALUES_LENGTH] {}

unconstrained pub fn call_public_function_internal(
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field
args_hash: Field,
is_static_call: bool
) -> [Field; RETURN_VALUES_LENGTH] {
call_public_function_oracle(contract_address, function_selector, args_hash)
call_public_function_oracle(contract_address, function_selector, args_hash, is_static_call)
}

0 comments on commit 76396d0

Please sign in to comment.