Skip to content

Commit 3095fff

Browse files
authored
chore: Accumulated backports to v4-next (#22742)
BEGIN_COMMIT_OVERRIDE feat: offchain delivered private transfer (#22574) END_COMMIT_OVERRIDE
2 parents 9b56d55 + 6a6cc3d commit 3095fff

22 files changed

Lines changed: 715 additions & 74 deletions

File tree

aztec-up/bin/0.0.1/aztec-install

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,13 @@ function install_aztec_up {
183183

184184
# Updates appropriate shell script to ensure the paths are in PATH.
185185
function update_path_env_var {
186-
# We need both:
187-
# - $AZTEC_HOME/current/bin and $AZTEC_HOME/current/node_modules/.bin for version-specific tools
186+
# We need:
187+
# - $AZTEC_HOME/current/bin for version-specific tools (nargo, aztec, bb, ...)
188188
# - $AZTEC_HOME/bin for shared tools like aztec-up
189-
local path_line="export PATH=\"\$HOME/.aztec/current/bin:\$HOME/.aztec/current/node_modules/.bin:\$HOME/.aztec/bin:\$PATH\""
189+
# - $AZTEC_HOME/current/node_modules/.bin is intentionally NOT added: the per-version installer
190+
# symlinks the @aztec-owned bins into current/bin, so adding node_modules/.bin
191+
# would only expose transitive npm deps (jest, tsc, ...) and shadow user tools.
192+
local path_line="export PATH=\"\$HOME/.aztec/current/bin:\$HOME/.aztec/bin:\$PATH\""
190193

191194
# Determine the user's shell.
192195
local shell_profile=""

aztec-up/bin/0.0.1/aztec-up

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,10 @@ function cmd_env {
549549

550550
local version_dir="$AZTEC_HOME/versions/$resolved_version"
551551

552-
# Output PATH export with relevant bin directories
553-
echo "export PATH=\"$version_dir/bin:$version_dir/node_modules/.bin:\$PATH\""
552+
# Output PATH export with relevant bin directories.
553+
# node_modules/.bin is intentionally excluded -- the per-version installer
554+
# symlinks @aztec-owned bins into bin/, keeping transitive npm deps off PATH.
555+
echo "export PATH=\"$version_dir/bin:\$PATH\""
554556
}
555557

556558
# Main entry point

aztec-up/bin/0.0.1/install

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,29 @@ function install_aztec_packages {
197197
npm install @aztec/aztec@$VERSION @aztec/cli-wallet@$VERSION @aztec/bb.js@$VERSION --prefix "$version_path"
198198
}
199199

200+
function symlink_aztec_bins {
201+
set -euo pipefail
202+
# Populate version_bin_path with symlinks to @aztec-owned bins only. Adding
203+
# node_modules/.bin wholesale to PATH would shadow user-installed tools
204+
# (jest, tsc, semver, ...) with Aztec's transitive dependencies.
205+
local npm_bin_dir="$version_path/node_modules/.bin"
206+
[ -d "$npm_bin_dir" ] || return 0
207+
208+
local bin_link bin_name target
209+
for bin_link in "$npm_bin_dir"/*; do
210+
[ -L "$bin_link" ] || continue
211+
target=$(readlink "$bin_link")
212+
# npm writes relative symlinks like ../@aztec/aztec/... for scoped packages.
213+
[[ "$target" == ../@aztec/* ]] || continue
214+
bin_name=$(basename "$bin_link")
215+
if [ -e "$version_bin_path/$bin_name" ] && [ ! -L "$version_bin_path/$bin_name" ]; then
216+
echo_yellow "refusing to overwrite non-symlink $bin_name; @aztec package bin collides with a hand-installed toolchain binary" >&2
217+
exit 1
218+
fi
219+
ln -sfn "../node_modules/.bin/$bin_name" "$version_bin_path/$bin_name"
220+
done
221+
}
222+
200223
function main {
201224
# Create version directory
202225
mkdir -p "$version_bin_path"
@@ -228,6 +251,11 @@ function main {
228251
echo -n "Installing aztec packages... "
229252
dump_fail retry install_aztec_packages
230253
echo_green "done."
254+
255+
# Expose only @aztec-owned bins on PATH (drops transitive npm deps).
256+
echo -n "Making aztec commands available... "
257+
dump_fail retry symlink_aztec_bins
258+
echo_green "done."
231259
}
232260

233261
main "$@"

docs/docs-developers/docs/resources/migration_notes.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@ Aztec is in active development. Each version may introduce breaking changes that
99

1010
## TBD
1111

12+
### [CLI] `aztec-up` no longer exposes transitive npm bins on PATH
13+
14+
The `aztec-up` installer used to add `$HOME/.aztec/current/node_modules/.bin` to your shell `PATH`, which put ~40 transitive npm bins (`jest`, `tsc`, `tsserver`, `semver`, `uuid`, `json5`, ...) onto your interactive shell and silently shadowed your own installed versions of those tools. Only the seven `@aztec/*`-owned bins (`aztec`, `aztec-wallet`, `bb`, `bb-cli`, `blob-client`, `noir-codegen`, `txe`) are now exposed.
15+
16+
If you had an Aztec version installed before this release, your shell profile (`~/.bashrc` or `~/.zshrc`) still contains the old `PATH` line. Re-run the installer once (replacing `[VERSION]` with whichever toolchain version you're on, e.g. `4.2.0`) to replace it:
17+
18+
```bash
19+
VERSION=[VERSION] bash -i <(curl -sL https://install.aztec.network)
20+
```
21+
22+
Open a fresh shell and confirm the leak is gone:
23+
24+
```bash
25+
echo $PATH
26+
```
27+
28+
`$HOME/.aztec/current/node_modules/.bin` should no longer appear in the output. You'll also see your own `jest`, `tsc`, etc. again instead of the ones bundled with the Aztec toolchain.
29+
1230
### [Aztec.nr] `emit_private_log_unsafe` / `emit_raw_note_log_unsafe` are deprecated
1331

1432
`emit_private_log_unsafe` and `emit_raw_note_log_unsafe` are deprecated and will be removed in a future release. Migrate to the new `emit_private_log_vec_unsafe` / `emit_raw_note_log_vec_unsafe` functions, which take a `BoundedVec<Field, PRIVATE_LOG_CIPHERTEXT_LEN>` instead of the `(log: [Field; PRIVATE_LOG_CIPHERTEXT_LEN], length: u32)` pair.

noir-projects/aztec-nr/aztec/src/macros/aztec.nr

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ use crate::{
99
dispatch::generate_public_dispatch,
1010
emit_public_init_nullifier::generate_emit_public_init_nullifier,
1111
internals_functions_generation::{create_fn_abi_exports, process_functions},
12+
offchain_receive::{
13+
OFFCHAIN_RECEIVE_FN_NAME, OFFCHAIN_RECEIVE_PARAM_NAME, offchain_receive_param_type,
14+
OFFCHAIN_RECEIVE_RETURN_TYPE,
15+
},
1216
storage::STORAGE_LAYOUT_NAME,
1317
utils::{is_fn_contract_library_method, is_fn_external, is_fn_internal, is_fn_test, module_has_storage},
1418
},
@@ -249,17 +253,18 @@ comptime fn generate_sync_state(process_custom_message_option: Quoted, offchain_
249253
///
250254
/// For more details, see `aztec::messages::processing::offchain::receive`.
251255
comptime fn generate_offchain_receive() -> Quoted {
256+
let param_type = offchain_receive_param_type(quote { aztec });
257+
let parameters_struct_name = f"{OFFCHAIN_RECEIVE_FN_NAME}_parameters".quoted_contents();
258+
let abi_struct_name = f"{OFFCHAIN_RECEIVE_FN_NAME}_abi".quoted_contents();
259+
252260
quote {
253-
pub struct offchain_receive_parameters {
254-
pub messages: BoundedVec<
255-
aztec::messages::processing::offchain::OffchainMessage,
256-
aztec::messages::processing::offchain::MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL,
257-
>,
261+
pub struct $parameters_struct_name {
262+
pub $OFFCHAIN_RECEIVE_PARAM_NAME: $param_type,
258263
}
259264

260265
#[abi(functions)]
261-
pub struct offchain_receive_abi {
262-
parameters: offchain_receive_parameters,
266+
pub struct $abi_struct_name {
267+
parameters: $parameters_struct_name,
263268
}
264269

265270
/// Receives offchain messages into this contract's offchain inbox for subsequent processing.
@@ -270,14 +275,9 @@ comptime fn generate_offchain_receive() -> Quoted {
270275
///
271276
/// This function is automatically injected by the `#[aztec]` macro.
272277
#[aztec::macros::internals_functions_generation::abi_attributes::abi_utility]
273-
unconstrained fn offchain_receive(
274-
messages: BoundedVec<
275-
aztec::messages::processing::offchain::OffchainMessage,
276-
aztec::messages::processing::offchain::MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL,
277-
>,
278-
) {
278+
unconstrained fn $OFFCHAIN_RECEIVE_FN_NAME($OFFCHAIN_RECEIVE_PARAM_NAME: $param_type) -> $OFFCHAIN_RECEIVE_RETURN_TYPE {
279279
let address = aztec::context::UtilityContext::new().this_address();
280-
aztec::messages::processing::offchain::receive(address, messages);
280+
aztec::messages::processing::offchain::receive(address, $OFFCHAIN_RECEIVE_PARAM_NAME);
281281
}
282282
}
283283
}

noir-projects/aztec-nr/aztec/src/macros/calls_generation/external_functions.nr

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ use crate::macros::{
33
create_private_self_call_stub, create_private_static_stub, create_private_stub,
44
create_public_self_call_static_stub, create_public_self_call_stub, create_public_self_enqueue_static_stub,
55
create_public_self_enqueue_stub, create_public_static_stub, create_public_stub, create_utility_stub,
6+
create_utility_stub_from_parts,
67
},
78
internals_functions_generation::external_functions_registry,
9+
offchain_receive::{
10+
OFFCHAIN_RECEIVE_FN_NAME, OFFCHAIN_RECEIVE_PARAM_NAME, offchain_receive_param_type,
11+
OFFCHAIN_RECEIVE_RETURN_TYPE,
12+
},
813
utils::is_fn_view,
914
};
1015

@@ -37,7 +42,12 @@ pub(crate) comptime fn generate_external_function_calls(m: Module) -> Quoted {
3742
})
3843
.join(quote {});
3944

40-
let utility_contract_methods = utility_functions.map(|function| create_utility_stub(function)).join(quote {});
45+
// `offchain_receive` is injected into every contract by `#[aztec]` as quoted code rather than via the
46+
// `#[external("utility")]` attribute that populates `UTILITY_REGISTRY`, so it doesn't appear in
47+
// `utility_functions`. We append its stub so it shows up in the interface like any other utility.
48+
let utility_stubs =
49+
utility_functions.map(|function| create_utility_stub(function)).push_back(create_offchain_receive_stub());
50+
let utility_contract_methods = utility_stubs.join(quote {});
4151

4252
quote {
4353
$private_contract_methods
@@ -46,6 +56,16 @@ pub(crate) comptime fn generate_external_function_calls(m: Module) -> Quoted {
4656
}
4757
}
4858

59+
/// Builds the interface stub for the macro-injected `offchain_receive` utility. Pulls the signature
60+
/// from `crate::macros::offchain_receive` so it stays in lockstep with `generate_offchain_receive`.
61+
comptime fn create_offchain_receive_stub() -> Quoted {
62+
let param_type = offchain_receive_param_type(quote { crate }).as_type();
63+
let fn_parameters = @[(OFFCHAIN_RECEIVE_PARAM_NAME, param_type)];
64+
let fn_return_type = OFFCHAIN_RECEIVE_RETURN_TYPE.as_type();
65+
66+
create_utility_stub_from_parts(OFFCHAIN_RECEIVE_FN_NAME, fn_parameters, fn_return_type)
67+
}
68+
4969
/// Generates helper structs for convenient self-invocation of contract functions:
5070
///
5171
/// - `CallSelf`: Call your own private or public functions, e.g.: `self.call_self.some_private_function(args)`

noir-projects/aztec-nr/aztec/src/macros/calls_generation/external_functions_stubs.nr

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,17 @@ comptime fn create_stub_base(f: FunctionDefinition) -> (Quoted, Quoted, Quoted,
2828
// Unfortunately, the usage of macros makes it a bit of a black box. To actually view the target function, you
2929
// could instead command+click on `MyImportedContract`, or you can just manually search it. If you want to view the
3030
// noir code that gets generated by this macro, you can use `nargo expand` on your contract.
31-
let fn_name = f.name();
32-
let fn_parameters = f.parameters();
31+
create_stub_base_from_parts(f.name(), f.parameters())
32+
}
33+
34+
/// Variant of `create_stub_base` that takes raw `(name, parameters)` instead of a `FunctionDefinition`.
35+
///
36+
/// This lets macro-injected functions (e.g. `offchain_receive`) reuse the stub-generation machinery without needing a
37+
/// `FunctionDefinition`.
38+
pub(crate) comptime fn create_stub_base_from_parts(
39+
fn_name: Quoted,
40+
fn_parameters: [(Quoted, Type)],
41+
) -> (Quoted, Quoted, Quoted, Quoted, u32, Quoted, u32, Field) {
3342
let fn_parameters_list = fn_parameters.map(|(name, typ): (Quoted, Type)| quote { $name: $typ }).join(quote {,});
3443

3544
let (serialized_args_array_construction, serialized_args_array_len_quote, serialized_args_array_name) =
@@ -38,7 +47,7 @@ comptime fn create_stub_base(f: FunctionDefinition) -> (Quoted, Quoted, Quoted,
3847

3948
let fn_name_str = f"\"{fn_name}\"".quoted_contents();
4049
let fn_name_len: u32 = unquote!(quote { $fn_name_str.as_bytes().len()});
41-
let fn_selector: Field = compute_fn_selector(f.name(), f.parameters());
50+
let fn_selector: Field = compute_fn_selector(fn_name, fn_parameters);
4251

4352
(
4453
fn_name, fn_parameters_list, serialized_args_array_construction, serialized_args_array_name,
@@ -123,9 +132,17 @@ pub(crate) comptime fn create_public_static_stub(f: FunctionDefinition) -> Quote
123132
}
124133

125134
pub(crate) comptime fn create_utility_stub(f: FunctionDefinition) -> Quoted {
135+
create_utility_stub_from_parts(f.name(), f.parameters(), f.return_type())
136+
}
137+
138+
/// Variant of `create_utility_stub` that takes raw `(name, parameters, return_type)` instead of `FunctionDefinition`.
139+
pub(crate) comptime fn create_utility_stub_from_parts(
140+
fn_name: Quoted,
141+
fn_parameters: [(Quoted, Type)],
142+
fn_return_type: Type,
143+
) -> Quoted {
126144
let (fn_name, fn_parameters_list, serialized_args_array_construction, serialized_args_array_name, serialized_args_array_len, fn_name_str, fn_name_len, fn_selector) =
127-
create_stub_base(f);
128-
let fn_return_type = f.return_type();
145+
create_stub_base_from_parts(fn_name, fn_parameters);
129146

130147
quote {
131148
pub fn $fn_name(self, $fn_parameters_list) -> aztec::context::calls::UtilityCall<$fn_name_len, $serialized_args_array_len, $fn_return_type> {

noir-projects/aztec-nr/aztec/src/macros/mod.nr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub use aztec::{aztec, AztecConfig};
66
pub mod dispatch;
77
pub(crate) mod calls_generation;
88
pub(crate) mod emit_public_init_nullifier;
9+
pub(crate) mod offchain_receive;
910
pub mod internals_functions_generation;
1011
pub mod functions;
1112
pub mod utils;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//! Shared signature for the macro-injected `offchain_receive` utility.
2+
//!
3+
//! `offchain_receive` lives in two places: it is injected into every contract by the `#[aztec]`
4+
//! macro (see `generate_offchain_receive` in `macros/aztec.nr`), and its interface stub is
5+
//! generated so other contracts can call it (see `create_offchain_receive_stub` in
6+
//! `macros/calls_generation/external_functions.nr`). Both sites must agree on the function's
7+
//! name, parameter name, parameter type, and return type, or the selectors they compute would
8+
//! diverge and runtime calls would fail silently.
9+
//!
10+
//! To keep them in lockstep, both sites pull the signature components from here.
11+
12+
/// Name of the injected utility function.
13+
pub(crate) comptime global OFFCHAIN_RECEIVE_FN_NAME: Quoted = quote { offchain_receive };
14+
15+
/// Name of the single parameter.
16+
pub(crate) comptime global OFFCHAIN_RECEIVE_PARAM_NAME: Quoted = quote { messages };
17+
18+
/// Return type of the function.
19+
pub(crate) comptime global OFFCHAIN_RECEIVE_RETURN_TYPE: Quoted = quote { () };
20+
21+
/// The parameter type `BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL>`.
22+
pub(crate) comptime fn offchain_receive_param_type(prefix: Quoted) -> Quoted {
23+
quote {
24+
BoundedVec<
25+
$prefix::messages::processing::offchain::OffchainMessage,
26+
$prefix::messages::processing::offchain::MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL,
27+
>
28+
}
29+
}

noir-projects/aztec-nr/aztec/src/messages/processing/offchain.nr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub(crate) type OffchainInboxSync<Env> = unconstrained fn[Env](
5252
/* contract_address */AztecAddress, /* scope */ AztecAddress) -> EphemeralArray<OffchainMessageWithContext>;
5353

5454
/// A message delivered via the `offchain_receive` utility function.
55+
#[derive(Serialize, Deserialize)]
5556
pub struct OffchainMessage {
5657
/// The encrypted message payload.
5758
pub ciphertext: BoundedVec<Field, MESSAGE_CIPHERTEXT_LEN>,

0 commit comments

Comments
 (0)