Skip to content

Commit cd9e095

Browse files
authored
fix: Merge Conflicts (#24014)
.
2 parents 5570957 + 6ed544b commit cd9e095

47 files changed

Lines changed: 1314 additions & 559 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci3.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,15 +208,19 @@ jobs:
208208
fail-fast: false
209209
matrix:
210210
test_set: ["1", "2"]
211-
# We run on current nightly tags only, or when the ci-network-scenario label is present in a PR.
211+
# We run on the current v5-next nightly tag (private repo only), or when the ci-network-scenario label is present in a PR.
212212
needs: [ci, validate-nightly-tag]
213213
if: |
214214
always()
215215
&& (needs.ci.result == 'success' || needs.ci.result == 'skipped')
216216
&& github.event.pull_request.head.repo.fork != true
217217
&& github.event.pull_request.draft == false
218218
&& (
219-
needs.validate-nightly-tag.outputs.is_current == 'true'
219+
(
220+
needs.validate-nightly-tag.outputs.is_current == 'true'
221+
&& github.repository == 'AztecProtocol/aztec-packages-private'
222+
&& startsWith(github.ref_name, 'v5.')
223+
)
220224
|| contains(github.event.pull_request.labels.*.name, 'ci-network-scenario')
221225
)
222226
steps:

Makefile

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,19 +287,30 @@ claude-tests:
287287
# Noir Projects
288288
#==============================================================================
289289

290-
noir-protocol-circuits: noir bb-cpp-native
290+
# Generates the noir-protocol-circuits workspace files (Nargo.toml, autogenerated crates),
291+
# which are git-ignored and must exist before nargo can run in that workspace. Needs only
292+
# yarn/node, so no prerequisites: it runs in parallel with the noir build.
293+
noir-protocol-circuits-variants:
294+
$(call build,$@,noir-projects,generate_variants)
295+
296+
# Format check. Also warms the nargo dependency cache, so it must complete before the
297+
# subproject builds to avoid parallel nargo runs tripping over each other downloading.
298+
noir-projects-format-check: noir noir-protocol-circuits-variants
299+
$(call build,$@,noir-projects,format_check)
300+
301+
noir-protocol-circuits: noir bb-cpp-native noir-projects-format-check
291302
$(call build,$@,noir-projects/noir-protocol-circuits)
292303

293304
noir-protocol-circuits-tests: noir noir-protocol-circuits
294305
$(call test,$@,noir-projects/noir-protocol-circuits)
295306

296-
mock-protocol-circuits: noir bb-cpp-native
307+
mock-protocol-circuits: noir bb-cpp-native noir-projects-format-check
297308
$(call build,$@,noir-projects/mock-protocol-circuits)
298309

299-
noir-contracts: noir bb-cpp-native
310+
noir-contracts: noir bb-cpp-native noir-projects-format-check
300311
$(call build,$@,noir-projects/noir-contracts)
301312

302-
aztec-nr: noir bb-cpp-native
313+
aztec-nr: noir bb-cpp-native noir-projects-format-check
303314
$(call build,$@,noir-projects/aztec-nr)
304315

305316
# These tests are not included in the dep tree.
@@ -308,7 +319,7 @@ noir-projects-txe-tests:
308319
$(call test,$@,noir-projects/aztec-nr)
309320
$(call test,$@,noir-projects/noir-contracts)
310321

311-
contract-snapshots-tests: noir
322+
contract-snapshots-tests: noir noir-projects-format-check
312323
$(call test,$@,noir-projects/contract-snapshots)
313324

314325
# Noir Projects - Aggregate target (builds all sub-projects)

docs/docs-developers/docs/aztec-nr/debugging.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ LOG_LEVEL=verbose aztec start --local-network
3939

4040
#### Cross-contract utility call denied
4141

42-
Utility functions execute on the user's device and have access to private state. A cross-contract utility call made by a malicious or compromised contract could leak private information to an untrusted contract. PXE therefore denies all cross-contract utility calls by default and requires explicit authorization via an execution hook.
42+
Utility functions execute on the user's device and have access to private state. A cross-contract utility call made by
43+
a malicious or compromised contract could leak private information to an untrusted contract. PXE therefore denies cross-
44+
contract utility calls by default and requires explicit authorization via an execution hook. Calls to standard contracts
45+
(such as the HandshakeRegistry, which is queried during every contract's sync) are always automatically authorized.
4346

4447
When a contract executes a utility function that calls into a different contract, PXE asks an **execution hook** whether the call should be allowed. If no hook is configured, or the hook denies the request, you will see:
4548

noir-projects/aztec-nr/aztec/src/messages/delivery/builder.nr

Lines changed: 404 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
use crate::messages::delivery::OnchainDeliveryMode;
2+
use crate::protocol::point::EmbeddedCurvePoint;
3+
use crate::protocol::traits::{Deserialize, Serialize};
4+
5+
use crate::{
6+
ephemeral::EphemeralArray,
7+
messages::processing::provided_secret::ProvidedSecret,
8+
oracle::{call_utility_function::call_utility_function, shared_secret::get_shared_secrets},
9+
protocol::{
10+
abis::function_selector::FunctionSelector, address::AztecAddress, hash::sha256_to_field, traits::ToField,
11+
},
12+
standard_addresses::STANDARD_HANDSHAKE_REGISTRY_ADDRESS,
13+
};
14+
15+
/// Page size for handshake discovery pagination.
16+
pub global MAX_HANDSHAKES_PER_PAGE: u32 = 32;
17+
18+
/// A handshake discovered during sync: the sender's ephemeral public key and the delivery mode.
19+
#[derive(Deserialize, Eq, Serialize)]
20+
pub struct DiscoveredHandshake {
21+
pub eph_pk: EmbeddedCurvePoint,
22+
pub mode: OnchainDeliveryMode,
23+
}
24+
25+
/// A paginated response of discovered handshakes.
26+
#[derive(Deserialize, Serialize)]
27+
pub struct HandshakePage {
28+
pub items: BoundedVec<DiscoveredHandshake, MAX_HANDSHAKES_PER_PAGE>,
29+
pub total_count: u32,
30+
}
31+
32+
pub(crate) global PROVIDED_SECRETS_ARRAY_BASE_SLOT: Field =
33+
sha256_to_field("AZTEC_NR::PROVIDED_SECRETS_ARRAY_BASE_SLOT".as_bytes());
34+
35+
global HANDSHAKE_EPH_PKS_SLOT: Field = sha256_to_field("AZTEC_NR::HANDSHAKE_EPH_PKS_SLOT".as_bytes());
36+
37+
global HANDSHAKE_MODES_SLOT: Field = sha256_to_field("AZTEC_NR::HANDSHAKE_MODES_SLOT".as_bytes());
38+
39+
/// Fetches discovered handshakes from the HandshakeRegistry and derives app-siloed tagging secrets for each,
40+
/// returning them so that [`get_pending_tagged_logs`](crate::oracle::message_processing::get_pending_tagged_logs)
41+
/// searches for logs tagged with these secrets.
42+
pub(crate) unconstrained fn get_handshake_secrets(
43+
contract_address: AztecAddress,
44+
scope: AztecAddress,
45+
) -> EphemeralArray<ProvidedSecret> {
46+
let provided_secrets = EphemeralArray::<ProvidedSecret>::empty_at(PROVIDED_SECRETS_ARRAY_BASE_SLOT);
47+
48+
let eph_pks: EphemeralArray<EmbeddedCurvePoint> = EphemeralArray::empty_at(HANDSHAKE_EPH_PKS_SLOT);
49+
let modes: EphemeralArray<OnchainDeliveryMode> = EphemeralArray::empty_at(HANDSHAKE_MODES_SLOT);
50+
51+
let mut page_offset: u32 = 0;
52+
let mut has_more = true;
53+
while has_more {
54+
let page = fetch_handshake_page(scope, page_offset);
55+
56+
for j in 0..page.items.len() {
57+
let handshake = page.items.get(j);
58+
eph_pks.push(handshake.eph_pk);
59+
modes.push(handshake.mode);
60+
}
61+
62+
page_offset += page.items.len();
63+
has_more = page_offset < page.total_count;
64+
}
65+
66+
if eph_pks.len() > 0 {
67+
let secrets = get_shared_secrets(scope, eph_pks, contract_address);
68+
for j in 0..secrets.len() {
69+
provided_secrets.push(ProvidedSecret { secret: secrets.get(j), mode: modes.get(j) });
70+
}
71+
}
72+
73+
provided_secrets
74+
}
75+
76+
/// Calls the HandshakeRegistry's `get_handshakes` utility function and deserializes the response.
77+
unconstrained fn fetch_handshake_page(recipient: AztecAddress, page_offset: u32) -> HandshakePage {
78+
let selector = comptime { FunctionSelector::from_signature("get_handshakes((Field),u32)") };
79+
let args: [Field; 2] = [recipient.to_field(), page_offset as Field];
80+
let response = call_utility_function(STANDARD_HANDSHAKE_REGISTRY_ADDRESS, selector, args);
81+
HandshakePage::deserialize(response)
82+
}
83+
84+
mod test {
85+
use crate::ephemeral::EphemeralArray;
86+
use crate::messages::delivery::handshake::{
87+
DiscoveredHandshake, get_handshake_secrets, HandshakePage, MAX_HANDSHAKES_PER_PAGE,
88+
};
89+
use crate::messages::delivery::OnchainDeliveryMode;
90+
use crate::protocol::{address::AztecAddress, traits::Serialize};
91+
use crate::test::helpers::test_environment::TestEnvironment;
92+
use crate::utils::point::point_from_x_coord;
93+
use std::test::OracleMock;
94+
95+
global UNCONSTRAINED: OnchainDeliveryMode = OnchainDeliveryMode::onchain_unconstrained();
96+
global CONSTRAINED: OnchainDeliveryMode = OnchainDeliveryMode::onchain_constrained();
97+
98+
#[test]
99+
unconstrained fn get_handshake_secrets_returns_secrets_from_single_page() {
100+
let mut env = TestEnvironment::new();
101+
let scope = env.create_light_account();
102+
let contract_address = AztecAddress { inner: 0xdeadbeef };
103+
104+
env.utility_context_at(contract_address, |_| {
105+
let pk_a = point_from_x_coord(1).unwrap();
106+
let pk_b = point_from_x_coord(2).unwrap();
107+
108+
let mut items: BoundedVec<DiscoveredHandshake, MAX_HANDSHAKES_PER_PAGE> = BoundedVec::new();
109+
items.push(DiscoveredHandshake { eph_pk: pk_a, mode: UNCONSTRAINED });
110+
items.push(DiscoveredHandshake { eph_pk: pk_b, mode: CONSTRAINED });
111+
let page = HandshakePage { items, total_count: 2 };
112+
let _ = OracleMock::mock("aztec_utl_callUtilityFunction").returns(page.serialize());
113+
114+
let secret_a: Field = 111;
115+
let secret_b: Field = 222;
116+
mock_get_shared_secrets([secret_a, secret_b]);
117+
118+
let secrets = get_handshake_secrets(contract_address, scope);
119+
120+
assert_eq(secrets.len(), 2);
121+
assert_eq(secrets.get(0).secret, secret_a);
122+
assert_eq(secrets.get(0).mode, UNCONSTRAINED);
123+
assert_eq(secrets.get(1).secret, secret_b);
124+
assert_eq(secrets.get(1).mode, CONSTRAINED);
125+
});
126+
}
127+
128+
#[test]
129+
unconstrained fn get_handshake_secrets_fetches_multiple_pages() {
130+
let mut env = TestEnvironment::new();
131+
let scope = env.create_light_account();
132+
let contract_address = AztecAddress { inner: 0xdeadbeef };
133+
134+
env.utility_context_at(contract_address, |_| {
135+
let pk_a = point_from_x_coord(1).unwrap();
136+
let pk_b = point_from_x_coord(2).unwrap();
137+
let pk_c = point_from_x_coord(8).unwrap();
138+
139+
let mut page_1_items: BoundedVec<DiscoveredHandshake, MAX_HANDSHAKES_PER_PAGE> = BoundedVec::new();
140+
page_1_items.push(DiscoveredHandshake { eph_pk: pk_a, mode: UNCONSTRAINED });
141+
page_1_items.push(DiscoveredHandshake { eph_pk: pk_b, mode: CONSTRAINED });
142+
let page_1 = HandshakePage { items: page_1_items, total_count: 3 };
143+
144+
let mut page_2_items: BoundedVec<DiscoveredHandshake, MAX_HANDSHAKES_PER_PAGE> = BoundedVec::new();
145+
page_2_items.push(DiscoveredHandshake { eph_pk: pk_c, mode: UNCONSTRAINED });
146+
let page_2 = HandshakePage { items: page_2_items, total_count: 3 };
147+
148+
let _ = OracleMock::mock("aztec_utl_callUtilityFunction").returns(page_1.serialize()).times(1);
149+
let _ = OracleMock::mock("aztec_utl_callUtilityFunction").returns(page_2.serialize()).times(1);
150+
151+
mock_get_shared_secrets([111, 222, 333]);
152+
153+
let secrets = get_handshake_secrets(contract_address, scope);
154+
assert_eq(secrets.len(), 3);
155+
assert_eq(secrets.get(0).secret, 111);
156+
assert_eq(secrets.get(0).mode, UNCONSTRAINED);
157+
assert_eq(secrets.get(1).secret, 222);
158+
assert_eq(secrets.get(1).mode, CONSTRAINED);
159+
assert_eq(secrets.get(2).secret, 333);
160+
assert_eq(secrets.get(2).mode, UNCONSTRAINED);
161+
});
162+
}
163+
164+
unconstrained fn mock_get_shared_secrets<let N: u32>(response_values: [Field; N]) {
165+
let response_slot: Field = 99;
166+
let response_array: EphemeralArray<Field> = EphemeralArray::at(response_slot);
167+
for value in response_values {
168+
response_array.push(value);
169+
}
170+
let _ = OracleMock::mock("aztec_utl_getSharedSecrets").returns(response_slot);
171+
}
172+
}

0 commit comments

Comments
 (0)