Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/ci3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Run Backwards Compatibility E2E Tests
timeout-minutes: 330
timeout-minutes: 60
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand All @@ -489,7 +489,7 @@ jobs:
CI3_INSTANCE_PROFILE_NAME: ${{ secrets.CI3_INSTANCE_PROFILE_NAME }}
CI3_SECURITY_GROUP_ID: ${{ secrets.CI3_SECURITY_GROUP_ID }}
RUN_ID: ${{ github.run_id }}
AWS_SHUTDOWN_TIME: 300
AWS_SHUTDOWN_TIME: 60
run: ./.github/ci3.sh compat-e2e

# Publishes the release (npm, Docker, GitHub release, aztec-up scripts, etc.).
Expand Down
14 changes: 13 additions & 1 deletion aztec-up/bin/0.0.1/install
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,21 @@ function echo_yellow {
}

function timeout {
if [ "${CI:-0}" = "1" ] || [ "${CI:-0}" = "true" ]; then
if [ "${CI:-0}" != "1" ] && [ "${CI:-0}" != "true" ]; then
shift
"$@"
return
fi
if [ -x /usr/bin/timeout ]; then
# Prefer coreutils `timeout` when available. Absolute path avoids re-entering this function.
/usr/bin/timeout "$@"
elif perl -e1 2>/dev/null; then
# Fall back to perl's `alarm` when /usr/bin/timeout is missing.
local duration=$1
shift
perl -e "alarm $duration; exec @ARGV" -- "$@"
else
# No timeout backend available -- run unguarded rather than fail the install.
shift
"$@"
fi
Expand Down
2 changes: 1 addition & 1 deletion ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ case "$cmd" in
# against contract artifacts from prior stable releases.
export CI_DASHBOARD="releases"
export JOB_ID="x-compat-e2e"
export AWS_SHUTDOWN_TIME=300
export AWS_SHUTDOWN_TIME=60
rc=0
bootstrap_ec2 "./bootstrap.sh ci-compat-e2e" || rc=$?
# On nightly tags compat-e2e is non-blocking (continue-on-error in ci3.yml), so
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn derive_ecdh_shared_secret(secret: Scalar, public_key: Point) -> Point {
/// Computes an app-siloed shared secret from a raw ECDH shared secret point and a contract address.
///
/// `s_app = h(DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, S.x, S.y, contract_address)`
pub(crate) fn compute_app_siloed_shared_secret(shared_secret: Point, contract_address: AztecAddress) -> Field {
pub fn compute_app_siloed_shared_secret(shared_secret: Point, contract_address: AztecAddress) -> Field {
poseidon2_hash_with_separator(
[shared_secret.x, shared_secret.y, contract_address.to_field()],
DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,36 @@ use crate::macros::{
},
};

/// Emits a per-contract helper that creates the `self` value from a `PublicContext` already in scope.
///
/// This is the shared helper used by both:
/// - public external functions, via [`generate_public_self_creator`], which constructs a fresh `PublicContext` from
/// `calldata_copy` and then delegates to this helper; and
/// - public internal functions and `#[contract_library_method]` bodies, which already receive `context` as a
/// parameter and call this helper directly to skip the `calldata_copy` step.
pub(crate) comptime fn generate_public_self_creator_from_context(m: Module) -> Quoted {
let (storage_type, storage_init) = if module_has_storage(m) {
(quote { Storage<aztec::context::PublicContext> }, quote { let storage = Storage::init(context); })
} else {
// Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelfPublic requires
// a storage struct in its constructor. Using an Option type would lead to worse developer experience and
// higher constraint counts so we use the unit type `()` instead.
(quote { () }, quote { let storage = (); })
};

quote {
#[contract_library_method]
unconstrained fn __aztec_nr_internals__create_public_self_from_context(context: aztec::context::PublicContext) -> aztec::contract_self::ContractSelfPublic<$storage_type, CallSelf<aztec::context::PublicContext>, CallSelfStatic<aztec::context::PublicContext>, CallInternal<aztec::context::PublicContext>> {
$storage_init
let self_address = context.this_address();
let call_self: CallSelf<aztec::context::PublicContext> = CallSelf { address: self_address, context };
let call_self_static: CallSelfStatic<aztec::context::PublicContext> = CallSelfStatic { address: self_address, context };
let internal: CallInternal<aztec::context::PublicContext> = CallInternal { context };
aztec::contract_self::ContractSelfPublic::new(context, storage, call_self, call_self_static, internal)
}
}
}

/// Generates the per-contract helper that builds public `self`.
///
/// Each public external function calls this helper instead of inlining the construction, so the same preamble does not
Expand All @@ -16,36 +46,23 @@ use crate::macros::{
/// fields from calldata. Noir monomorphizes one copy per distinct `N`, so public functions with the same number of
/// serialized args reuse the same compiled code.
pub(crate) comptime fn generate_public_self_creator(m: Module) -> Quoted {
let (storage_type, storage_init) = if module_has_storage(m) {
(quote { Storage<aztec::context::PublicContext> }, quote { let storage = Storage::init(context); })
let storage_type = if module_has_storage(m) {
quote { Storage<aztec::context::PublicContext> }
} else {
// Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelfPublic requires
// a storage struct in its constructor. Using an Option type would lead to worse developer experience and
// higher constraint counts so we use the unit type `()` instead.
(quote { () }, quote { let storage = (); })
quote { () }
};

quote {
#[contract_library_method]
unconstrained fn __aztec_nr_internals__create_public_self<let N: u32>() -> aztec::contract_self::ContractSelfPublic<
$storage_type,
CallSelf<aztec::context::PublicContext>,
CallSelfStatic<aztec::context::PublicContext>,
CallInternal<aztec::context::PublicContext>,
> {
unconstrained fn __aztec_nr_internals__create_public_self<let N: u32>() -> aztec::contract_self::ContractSelfPublic<$storage_type, CallSelf<aztec::context::PublicContext>, CallSelfStatic<aztec::context::PublicContext>, CallInternal<aztec::context::PublicContext>> {
// Unlike in the private case, in public the `context` does not need to receive the hash of the original
// params.
let context = aztec::context::PublicContext::new(|| {
// We start from 1 because we skip the selector for the dispatch function.
let serialized_args : [Field; N] = aztec::oracle::avm::calldata_copy(1, N);
aztec::hash::hash_args(serialized_args)
});
$storage_init
let self_address = context.this_address();
let call_self: CallSelf<aztec::context::PublicContext> = CallSelf { address: self_address, context };
let call_self_static: CallSelfStatic<aztec::context::PublicContext> = CallSelfStatic { address: self_address, context };
let internal: CallInternal<aztec::context::PublicContext> = CallInternal { context };
aztec::contract_self::ContractSelfPublic::new(context, storage, call_self, call_self_static, internal)
__aztec_nr_internals__create_public_self_from_context(context)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
use crate::macros::utils::{fn_has_noinitcheck, module_has_initializer, module_has_storage};

pub(crate) comptime fn generate_utility_external(f: FunctionDefinition) -> Quoted {
let module_has_initializer = module_has_initializer(f.module());

// Initialize Storage if module has storage
let storage_init = if module_has_storage(f.module()) {
quote {
let storage = Storage::init(context);
}
/// Emits a per-contract helper that builds the `self` value used by every utility external function.
///
/// Each utility external function calls this helper instead of inlining the construction, so the
/// `UtilityContext::new`/`Storage::init`/`CallSelfUtility`/`ContractSelfUtility::new` chain does not appear duplicated
/// in every utility function body. We let Noir's inliner decide whether to inline the helper at each call site rather
/// than forcing it via macro expansion.
///
/// Unlike the public counterpart, this helper takes no arguments because `UtilityContext::new` does not need calldata.
pub(crate) comptime fn generate_utility_self_creator(m: Module) -> Quoted {
let (storage_type, storage_init) = if module_has_storage(m) {
(quote { Storage<aztec::context::UtilityContext> }, quote { let storage = Storage::init(context); })
} else {
// Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelfUtility
// requires a
// storage struct in its constructor. Using an Option type would lead to worse developer experience and higher
// Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelfUtility requires
// a storage struct in its constructor. Using an Option type would lead to worse developer experience and higher
// constraint counts so we use the unit type `()` instead.
quote {
let storage = ();
}
(quote { () }, quote { let storage = (); })
};

// Create utility context
let contract_self_creation = quote {
#[allow(unused_variables)]
let mut self = {
quote {
#[contract_library_method]
unconstrained fn __aztec_nr_internals__create_utility_self() -> aztec::contract_self::ContractSelfUtility<$storage_type, CallSelfUtility> {
let context = aztec::context::UtilityContext::new();
$storage_init
let self_address = context.this_address();
let call_self = CallSelfUtility { address: self_address };
aztec::contract_self::ContractSelfUtility::new(context, storage, call_self)
};
}
}
}

pub(crate) comptime fn generate_utility_external(f: FunctionDefinition) -> Quoted {
let module_has_initializer = module_has_initializer(f.module());

let contract_self_creation = quote {
#[allow(unused_variables)]
let mut self = __aztec_nr_internals__create_utility_self();
};

// Initialization checks are not included in contracts that don't have initializers.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,6 @@ pub(crate) comptime fn generate_public_internal(f: FunctionDefinition) -> Quoted
$original_params
};

let storage_init = if module_has_storage(f.module()) {
quote {
let storage = Storage::init(context);
}
} else {
quote {
let storage = ();
}
};

let body = f.body();

// Internal public functions are marked as unconstrained because they are inlined within external public functions,
Expand All @@ -88,14 +78,7 @@ pub(crate) comptime fn generate_public_internal(f: FunctionDefinition) -> Quoted
#[contract_library_method]
unconstrained fn $fn_name($params) -> $return_type {
#[allow(unused_variables)]
let mut self = {
$storage_init
let self_address = context.this_address();
let call_self: CallSelf<aztec::context::PublicContext> = CallSelf { address: self_address, context };
let call_self_static: CallSelfStatic<aztec::context::PublicContext> = CallSelfStatic { address: self_address, context };
let internal: CallInternal<aztec::context::PublicContext> = CallInternal { context };
aztec::contract_self::ContractSelfPublic::new(context, storage, call_self, call_self_static, internal)
};
let mut self = __aztec_nr_internals__create_public_self_from_context(context);

$body
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ pub(crate) mod internal;
use abi_export::create_fn_abi_export;
use external::{
private::generate_private_external,
public::{generate_public_external, generate_public_self_creator},
utility::generate_utility_external,
public::{generate_public_external, generate_public_self_creator, generate_public_self_creator_from_context},
utility::{generate_utility_external, generate_utility_self_creator},
};
use internal::{generate_private_internal, generate_public_internal};

Expand Down Expand Up @@ -49,15 +49,35 @@ pub(crate) comptime fn process_functions(m: Module) -> Quoted {
let transformed_utility_functions =
utility_functions.map(|function| generate_utility_external(function)).join(quote {});

// Emit a contract-level helper that constructs `self` for public functions. Each transformed public function calls
// this helper rather than inlining the preamble. The helper is only useful for public external functions, so we
// skip emitting it when the contract has none.
// INTERNAL FUNCTIONS
let private_internal_functions = internal_functions_registry::get_private_functions(m);
let public_internal_functions = internal_functions_registry::get_public_functions(m);

// Emit per-contract helpers that construct `self` for public functions, so the preamble is not duplicated into
// every public function body. The creator takes a `PublicContext` and is shared by both public external functions
// (via `__aztec_nr_internals__create_public_self`) and public internal functions, which receive the context as a
// parameter. We only emit each helper if there is a caller for it.
let any_public_function = public_functions.len() > 0 | public_internal_functions.len() > 0;
let public_self_creator_from_context = if any_public_function {
generate_public_self_creator_from_context(m)
} else {
quote {}
};
let public_self_creator = if public_functions.len() > 0 {
generate_public_self_creator(m)
} else {
quote {}
};

// Same idea for utility functions: emit a per-contract helper that builds the `self` value, so the construction is
// not duplicated into every utility body. UtilityContext takes no calldata, so a single helper is enough; there is
// no internal/external split to share with.
let utility_self_creator = if utility_functions.len() > 0 {
generate_utility_self_creator(m)
} else {
quote {}
};

// Now that we have generated quotes of the new functions based on the original function definitions, we replace
// the original functions' bodies with `static_assert(false, ...)` to prevent them from being called directly from
// within the contract. We also need to set the return type to `()` to avoid compilation errors.
Expand All @@ -74,10 +94,6 @@ pub(crate) comptime fn process_functions(m: Module) -> Quoted {
"Direct invocation of utility functions is not supported. You attempted to call ",
);

// INTERNAL FUNCTIONS
let private_internal_functions = internal_functions_registry::get_private_functions(m);
let public_internal_functions = internal_functions_registry::get_public_functions(m);

let generated_private_internal_functions =
private_internal_functions.map(|function| generate_private_internal(function)).join(quote {});
let generated_public_internal_functions =
Expand All @@ -95,7 +111,9 @@ pub(crate) comptime fn process_functions(m: Module) -> Quoted {

// We return the new functions' quotes to be injected into the contract.
quote {
$public_self_creator_from_context
$public_self_creator
$utility_self_creator
$transformed_private_functions
$transformed_public_functions
$transformed_utility_functions
Expand Down
3 changes: 1 addition & 2 deletions noir-projects/aztec-nr/aztec/src/note/note_getter/test.nr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
note_getter_options::{NoteGetterOptions, PropertySelector, Sort, SortOrder},
},
oracle::random::random,
protocol::{address::AztecAddress, traits::FromField},
test::{helpers::test_environment::TestEnvironment, mocks::mock_note::MockNote},
utils::comparison::Comparator,
};
Expand All @@ -18,8 +19,6 @@ fn sort_criterion(index: u8, order: u8) -> Option<Sort> {
)
}

use crate::protocol::{address::AztecAddress, traits::FromField};

global storage_slot: Field = 42;
global owner: AztecAddress = AztecAddress::from_field(50);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ error: Argument from in function foo must be of type AztecAddress, but is of typ
5: process_functions
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41
6: generate_public_external
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:114:9
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:134:9
7: create_authorize_once_check
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:72:9

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ error: Function foo does not have a from parameter. Please specify which one to
5: process_functions
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41
6: generate_public_external
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:114:9
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:134:9
7: create_authorize_once_check
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:67:9

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ error: Function foo does not have a authwit_nonce. Please specify which one to u
5: process_functions
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41
6: generate_public_external
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:114:9
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:134:9
7: create_authorize_once_check
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:81:9

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ error: Argument authwit_nonce in function foo must be of type Field, but is of t
5: process_functions
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:48:41
6: generate_public_external
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:114:9
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:134:9
7: create_authorize_once_check
at <repo>/noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:86:9

Expand Down
Loading
Loading