When the macros for return values are applied they will current "copy" the node into the return_values of the context.
This means that for functions like:
#[aztec(private)]
fn is_valid(message_hash: Field) -> Field {
let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl);
actions.is_valid(message_hash)
}
We will really be executing something along the lines of:
#[aztec(private)]
fn is_valid(message_hash: Field) -> Field {
let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl);
actions.is_valid(message_hash);
context.return_values.push(actions.is_valid(message_hash));
}
This executes the function is_valid twice. Which can be "fatal" in some cases where the function is emitting nullifiers as it would create an instant double-spend, (two nullifiers in the same tx).
Point of interest:
|
// Abstract return types such that they get added to the kernel's return_values |
|
if let Some(return_values) = abstract_return_values(func) { |
|
func.def.body.0.push(return_values); |
|
} |
When the macros for return values are applied they will current "copy" the node into the
return_valuesof thecontext.This means that for functions like:
We will really be executing something along the lines of:
This executes the function
is_validtwice. Which can be "fatal" in some cases where the function is emitting nullifiers as it would create an instant double-spend, (two nullifiers in the same tx).Point of interest:
aztec-packages/noir/aztec_macros/src/lib.rs
Lines 637 to 640 in 811d767