Skip to content

Commit 4f39410

Browse files
committed
feat(pxe,nr): allow simulation overrides to sync without exclusions
Mirrors the real-account note storage (signing_public_key) on the simulated Schnorr/ECDSA account stubs and removes the manual sync_state() override so the #[aztec] macro generates a sync_state matching the real contract's selector. With matching note storage, the macro-generated _compute_note_hash can decode the real account's signing_public_key note during simulation sync. Removes the PXE setExcludedFromSync plumbing that previously skipped overridden contracts from sync. Required for fastForwardContractUpdate's private-call simulation to discover notes through the override.
1 parent b5280d2 commit 4f39410

5 files changed

Lines changed: 36 additions & 24 deletions

File tree

noir-projects/noir-contracts/contracts/account/simulated_ecdsa_account_contract/Nargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ type = "contract"
66

77
[dependencies]
88
aztec = { path = "../../../../aztec-nr/aztec" }
9+
ecdsa_public_key_note = { path = "../../libs/ecdsa_public_key_note" }

noir-projects/noir-contracts/contracts/account/simulated_ecdsa_account_contract/src/main.nr

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,26 @@ use aztec::macros::aztec;
33
// Stub account contract for ECDSA accounts (both secp256k1 and secp256r1) used during simulation.
44
// Matches the constructor signature of EcdsaKAccount / EcdsaRAccount so that deployment
55
// simulations using this stub as an override do not fail on selector lookup.
6-
// See simulated_account_contract for the base stub without a constructor.
6+
// Mirrors the EcdsaKAccount/EcdsaRAccount storage layout so simulation sync can decode
7+
// the real account's signing_public_key note.
78
#[aztec]
89
pub contract SimulatedEcdsaAccount {
910
use aztec::{
1011
authwit::{account::AccountActions, auth::IS_VALID_SELECTOR, entrypoint::app::AppPayload},
1112
context::PrivateContext,
12-
macros::functions::{allow_phase_change, external, view},
13+
macros::{functions::{allow_phase_change, external, view}, storage::storage},
1314
messages::encoding::MESSAGE_CIPHERTEXT_LEN,
1415
oracle::random::random,
16+
state_vars::SinglePrivateImmutable,
1517
};
1618

19+
use ecdsa_public_key_note::EcdsaPublicKeyNote;
20+
21+
#[storage]
22+
struct Storage<Context> {
23+
signing_public_key: SinglePrivateImmutable<EcdsaPublicKeyNote, Context>,
24+
}
25+
1726
// Stub constructor matching the EcdsaKAccount / EcdsaRAccount constructor signature.
1827
// Does NOT use #[initializer] so that the macro does not inject
1928
// assert_initialization_matches_address_preimage_private, which would fail during kernelless
@@ -67,9 +76,4 @@ pub contract SimulatedEcdsaAccount {
6776
fn is_valid_impl(_context: &mut PrivateContext, _outer_hash: Field) -> bool {
6877
true
6978
}
70-
71-
#[external("utility")]
72-
unconstrained fn sync_state() {
73-
assert(false, "BUG ALERT: sync_state on a simulated account contract should never be triggered.");
74-
}
7579
}

noir-projects/noir-contracts/contracts/account/simulated_schnorr_account_contract/src/main.nr

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
1+
mod public_key_note;
2+
13
use aztec::macros::aztec;
24

35
// Stub account contract for Schnorr accounts used during simulation.
46
// Matches the constructor signature of SchnorrAccount so that deployment
57
// simulations using this stub as an override do not fail on selector lookup.
6-
// See simulated_account_contract for the base stub without a constructor.
8+
// Mirrors the SchnorrAccount storage layout so simulation sync can decode
9+
// the real account's signing_public_key note.
710
#[aztec]
811
pub contract SimulatedSchnorrAccount {
912
use aztec::{
1013
authwit::{account::AccountActions, auth::IS_VALID_SELECTOR, entrypoint::app::AppPayload},
1114
context::PrivateContext,
12-
macros::functions::{allow_phase_change, external, view},
15+
macros::{functions::{allow_phase_change, external, view}, storage::storage},
1316
messages::encoding::MESSAGE_CIPHERTEXT_LEN,
1417
oracle::random::random,
18+
state_vars::SinglePrivateImmutable,
1519
};
1620

21+
use crate::public_key_note::PublicKeyNote;
22+
23+
#[storage]
24+
struct Storage<Context> {
25+
signing_public_key: SinglePrivateImmutable<PublicKeyNote, Context>,
26+
}
27+
1728
// Stub constructor matching the SchnorrAccount constructor signature.
1829
// Does NOT use #[initializer] so that the macro does not inject
1930
// assert_initialization_matches_address_preimage_private, which would fail during kernelless
@@ -67,9 +78,4 @@ pub contract SimulatedSchnorrAccount {
6778
fn is_valid_impl(_context: &mut PrivateContext, _outer_hash: Field) -> bool {
6879
true
6980
}
70-
71-
#[external("utility")]
72-
unconstrained fn sync_state() {
73-
assert(false, "BUG ALERT: sync_state on a simulated account contract should never be triggered.");
74-
}
7581
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use aztec::{macros::notes::note, protocol::traits::Packable};
2+
3+
// Mirrors PublicKeyNote in schnorr_account_contract so the stub's auto-generated _compute_note_hash
4+
// can decode the real account's signing_public_key note during simulation sync.
5+
#[derive(Eq, Packable)]
6+
#[note]
7+
pub struct PublicKeyNote {
8+
pub x: Field,
9+
pub y: Field,
10+
}

yarn-project/pxe/src/pxe.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,22 +1002,13 @@ export class PXE {
10021002
const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
10031003
const syncTime = syncTimer.ms();
10041004

1005-
const overriddenContracts = overrides?.contracts ? new Set(Object.keys(overrides.contracts)) : undefined;
1006-
const hasOverriddenContracts = overriddenContracts !== undefined && overriddenContracts.size > 0;
1007-
1008-
if (hasOverriddenContracts && !skipKernels) {
1005+
if (overrides?.contracts && Object.keys(overrides.contracts).length > 0 && !skipKernels) {
10091006
throw new Error(
10101007
'Simulating with overridden contracts is not compatible with kernel execution. Please set skipKernels to true when simulating with overridden contracts.',
10111008
);
10121009
}
10131010
const contractFunctionSimulator = this.#getSimulatorForTx(overrides);
10141011

1015-
if (hasOverriddenContracts) {
1016-
// Overridden contracts don't have a sync function, so calling sync on them would fail.
1017-
// We exclude them so the sync service skips them entirely.
1018-
this.contractSyncService.setExcludedFromSync(jobId, overriddenContracts);
1019-
}
1020-
10211012
// Execution of private functions only; no proving, and no kernel logic.
10221013
const privateExecutionResult = await this.#executePrivate({
10231014
contractFunctionSimulator,

0 commit comments

Comments
 (0)