Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
98b9784
udpates to handshake registry
vezenovm May 14, 2026
27e5a5e
nargo fmt
vezenovm May 14, 2026
381858d
clean up bug repros and link to TODO
vezenovm May 14, 2026
fff3541
fmt
vezenovm May 14, 2026
3202ab1
constants test update
vezenovm May 14, 2026
49bfefc
switch to handshakes: Map<AztecAddress, Owned<PrivateMutable<Handshak…
vezenovm May 14, 2026
d00136d
remove old comment referencing issue
vezenovm May 14, 2026
76c025e
Update noir-projects/noir-contracts/contracts/message_discovery/hands…
vezenovm May 14, 2026
75554b1
pr comments, cleanup, additional tests
vezenovm May 15, 2026
9a451ef
extend sender tagging store and make a new oracle to get next constra…
vezenovm May 18, 2026
14d22ca
merge conflicts w/ fairies
vezenovm May 18, 2026
bfb03bf
fix: bump HashedValueTester capacities for new constrained-msg dom sep
AztecBot May 18, 2026
aa3d1e6
merge w/ fairies
vezenovm May 26, 2026
df3f982
test: bump HashedValueTester capacity for new constrained_msg_log_tag…
AztecBot May 26, 2026
36d355d
test cleanup
vezenovm May 26, 2026
3bad347
Merge remote-tracking branch 'origin/maxim/f-668-aztec-nr-extend-get_…
vezenovm May 26, 2026
cbc905b
Apply suggestions from code review
vezenovm May 27, 2026
0d1e1c5
comment
vezenovm May 27, 2026
cc18df1
Merge remote-tracking branch 'origin/merge-train/fairies' into maxim/…
vezenovm May 27, 2026
a018a02
Merge remote-tracking branch 'origin/merge-train/fairies' into maxim/…
vezenovm May 27, 2026
cbf7fed
docs: wrap constrained tagging comment
vezenovm May 27, 2026
8188a7d
test: clarify app tagging kind parsing
vezenovm May 27, 2026
ccf6647
refactor: clarify constrained tagging index oracle
vezenovm May 27, 2026
4e77dc0
no need for sileodTagFor
vezenovm May 28, 2026
6446fa6
constants fmt
vezenovm May 28, 2026
f6dd2da
oracle
vezenovm May 28, 2026
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
3 changes: 3 additions & 0 deletions noir-projects/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ 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)`
///
/// Public so that contracts holding a raw `Point` (e.g. the constrained-delivery handshake registry) can
/// reuse the canonical silo formula rather than re-inlining it and risking drift.
Comment thread
vezenovm marked this conversation as resolved.
Outdated
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()],
Expand Down
18 changes: 18 additions & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/notes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,24 @@ pub unconstrained fn get_next_app_tag_as_sender(sender: AztecAddress, recipient:
#[oracle(aztec_prv_getNextAppTagAsSender)]
unconstrained fn get_next_app_tag_as_sender_oracle(_sender: AztecAddress, _recipient: AztecAddress) -> Field {}

/// Returns the next sender-side index for a constrained-delivery shared secret.
///
/// Unlike [`get_next_app_tag_as_sender`], which derives the full tag from a `(sender, recipient)` pair that only the
/// simulator knows the directional secret for, the constrained-delivery flow has the app contract holding the
/// app-siloed shared secret directly. The app computes the tag itself as
/// `compute_log_tag(poseidon2_hash([app_siloed_secret, index]), DOM_SEP__CONSTRAINED_MSG_LOG_TAG)`, so the simulator
/// only needs to hand out a fresh per-secret index.
///
/// As with the unconstrained variant, the simulator persists the index increment only if the tagged log is found in
/// an actual block - a reverting transaction can otherwise cause the sender to accidentally skip indices and later
/// produce notes that are not found by the recipient.
pub unconstrained fn get_next_constrained_index(app_siloed_secret: Field) -> u32 {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few thoughts about this:

  1. The name it not clear, what about get_next_tagging_index?
  2. I'm thinking if it makes sense to force this for constrained only? What if we had get_next_tagging_index(secret, kind)? Maybe it makes sense to have something like that in the future

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. get_next_constrained_tagging_index?
  2. I'm not sure about designing for a kind parameter as generalizing here feels a bit pre-mature. The design for unconstrained tagging is quite different than constrained, thus that is why we made this entirely separate oracle rather than extending get_next_app_tag_as_sender.

Copy link
Copy Markdown
Contributor

@nchamo nchamo May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm not saying we should extend or replace get_next_app_tag_as_sender. It just feels weird to me to force this oracle to be for constrained delivery only while we could easily accept an unconstrained secret and also return the next tagging index.

While I don't see a use case for it today, I'm thinking that it might make sense to make the oracle as generic as possible. Specially when the cost to do so is close to 0, right? I'm not completely sold on the idea, but I wanted to bring it up

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I brought up get_next_app_tag_as_sender as it feels like the same reasoning applies here. Unconstrained tagging intentionally has the PXE derive and return the full tag while in constrained tagging we only need the PXE to reserve the next index as the app holds the secret. It feels as though we would be extending the Noir oracle surface/API without a use case. I guess I ultimately am just hesitant to generalize when I don't know what the generalized version will look like in the future.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, makes sense. But let's rename to get_next_constrained_tagging_index please

get_next_constrained_index_oracle(app_siloed_secret)
}

#[oracle(aztec_prv_getNextConstrainedIndex)]
unconstrained fn get_next_constrained_index_oracle(_app_siloed_secret: Field) -> u32 {}

/// Gets the sender for tags.
///
/// This unconstrained value is used as the sender when computing an unconstrained shared secret for a tag in order to
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/oracle/version.nr
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/// immediately if AZTEC_NR_MINOR > PXE_MINOR because if a contract is updated to use a newer Aztec.nr dependency
/// without actually using any of the new oracles then there is no reason to throw.
pub global ORACLE_VERSION_MAJOR: Field = 22;
pub global ORACLE_VERSION_MINOR: Field = 3;
pub global ORACLE_VERSION_MINOR: Field = 4;

/// Asserts that the version of the oracle is compatible with the version expected by the contract.
pub fn assert_compatible_oracle_version() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,10 @@ pub global DOM_SEP__EVENT_LOG_TAG: u32 = 926040838;
pub global DOM_SEP__NOTE_COMPLETION_LOG_TAG: u32 = 3372669888;
/// Domain separator for unconstrained message delivery log tags. Used by [`crate::hash::compute_log_tag`].
pub global DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG: u32 = 1485357192;
/// Domain separator for constrained message delivery log tags. Used by [`crate::hash::compute_log_tag`] when the
/// sender derives the tag from an app-siloed shared secret rather than the directional `(sender, recipient)`
/// tagging secret.
pub global DOM_SEP__CONSTRAINED_MSG_LOG_TAG: u32 = 3715244738;
Comment thread
vezenovm marked this conversation as resolved.
Outdated
/// Domain separator for non-interactive handshake log tags emitted by the handshake registry contract. Used by
/// [`crate::hash::compute_log_tag`].
pub global DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG: u32 = 4046403018;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ use crate::{
DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_NULLIFIER,
DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOB_CHALLENGE_Z, DOM_SEP__BLOB_GAMMA_ACC,
DOM_SEP__BLOB_GAMMA_FINAL, DOM_SEP__BLOB_HASHED_Y_LIMBS, DOM_SEP__BLOB_Z_ACC,
DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONTRACT_ADDRESS_V1,
DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY,
DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FUNCTION_ARGS,
DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER,
DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONSTRAINED_MSG_LOG_TAG,
DOM_SEP__CONTRACT_ADDRESS_V1, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK,
DOM_SEP__ECDH_SUBKEY, DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG,
DOM_SEP__FUNCTION_ARGS, DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER,
DOM_SEP__IVSK_M, DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M,
DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_COMPLETION_LOG_TAG,
DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER,
Expand Down Expand Up @@ -142,7 +142,7 @@ impl<let NUM_VALUES: u32, let NUM_U32_VALUES: u32> HashedValueTester<NUM_VALUES,

#[test]
fn hashed_values_match_derived() {
let mut tester = HashedValueTester::<70, 63>::new();
let mut tester = HashedValueTester::<71, 64>::new();

// -----------------
// Domain separators
Expand Down Expand Up @@ -175,6 +175,10 @@ fn hashed_values_match_derived() {
DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG,
"unconstrained_msg_log_tag",
);
tester.assert_dom_sep_matches_derived(
DOM_SEP__CONSTRAINED_MSG_LOG_TAG,
"constrained_msg_log_tag",
);
tester.assert_dom_sep_matches_derived(
DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG,
"non_interactive_handshake_log_tag",
Expand Down
31 changes: 21 additions & 10 deletions yarn-project/constants/src/constants.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,29 @@ export const MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 3000;
export const MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS = 3000;
export const CLASS_REGISTRY_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 23;
export const CLASS_REGISTRY_UTILITY_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 14;
export const CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE = 14907836659448373306373608164128296596488873008270905914742877230397948162628n;
export const CONTRACT_CLASS_REGISTRY_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE = 6632427679359753950122686582223287785801228472790519808071945107172278003224n;
export const CONTRACT_CLASS_REGISTRY_UTILITY_FUNCTION_BROADCASTED_MAGIC_VALUE = 2863388930963370662477859081312917957786876946407365497018765359301074232169n;
export const CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE = 10538216027419913765597387738085647348651103543680388181336823392401502757423n;
export const CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE = 20721543224513346060908370400407150739273836456436647488068002302723900469047n;
export const CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE =
14907836659448373306373608164128296596488873008270905914742877230397948162628n;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a lot of the changes here are not related to your change. Can we revert them?

export const CONTRACT_CLASS_REGISTRY_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE =
6632427679359753950122686582223287785801228472790519808071945107172278003224n;
export const CONTRACT_CLASS_REGISTRY_UTILITY_FUNCTION_BROADCASTED_MAGIC_VALUE =
2863388930963370662477859081312917957786876946407365497018765359301074232169n;
export const CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE =
10538216027419913765597387738085647348651103543680388181336823392401502757423n;
export const CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE =
20721543224513346060908370400407150739273836456436647488068002302723900469047n;
export const MAX_PROTOCOL_CONTRACTS = 11;
export const CANONICAL_AUTH_REGISTRY_ADDRESS = 1;
export const CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS = 2;
export const CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS = 3;
export const MULTI_CALL_ENTRYPOINT_ADDRESS = 4;
export const FEE_JUICE_ADDRESS = 5;
export const PUBLIC_CHECKS_ADDRESS = 6;
export const SIDE_EFFECT_MASKING_ADDRESS = 19523154334483583633304358390644137470227519736821975910774528428729027989987n;
export const NULL_MSG_SENDER_CONTRACT_ADDRESS = 21888242871839275222246405745257275088548364400416034343698204186575808495616n;
export const CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT = 14193106819744442689484501689686180698286338820089744102289275815863062044599n;
export const SIDE_EFFECT_MASKING_ADDRESS =
19523154334483583633304358390644137470227519736821975910774528428729027989987n;
export const NULL_MSG_SENDER_CONTRACT_ADDRESS =
21888242871839275222246405745257275088548364400416034343698204186575808495616n;
export const CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT =
14193106819744442689484501689686180698286338820089744102289275815863062044599n;
export const FEE_JUICE_BALANCES_SLOT = 1;
export const UPDATED_CLASS_IDS_SLOT = 1;
export const DEFAULT_NPK_M_X = 582240093077765400562621227108555700500271598878376310175765873770292988861n;
Expand Down Expand Up @@ -487,10 +495,12 @@ export const PROOF_TYPE_HN_TAIL = 8;
export const PROOF_TYPE_CHONK = 9;
export const TWO_POW_64 = 18446744073709551616n;
export const AVM_WRITTEN_PUBLIC_DATA_SLOTS_TREE_HEIGHT = 6;
export const AVM_WRITTEN_PUBLIC_DATA_SLOTS_TREE_INITIAL_ROOT = 8857725174171741160013581538021104168730942281584695363072221389187184558934n;
export const AVM_WRITTEN_PUBLIC_DATA_SLOTS_TREE_INITIAL_ROOT =
8857725174171741160013581538021104168730942281584695363072221389187184558934n;
export const AVM_WRITTEN_PUBLIC_DATA_SLOTS_TREE_INITIAL_SIZE = 1;
export const AVM_RETRIEVED_BYTECODES_TREE_HEIGHT = 5;
export const AVM_RETRIEVED_BYTECODES_TREE_INITIAL_ROOT = 7219963955978612430652135562469971022121082503142071142433583613738272177170n;
export const AVM_RETRIEVED_BYTECODES_TREE_INITIAL_ROOT =
7219963955978612430652135562469971022121082503142071142433583613738272177170n;
export const AVM_RETRIEVED_BYTECODES_TREE_INITIAL_SIZE = 1;
export const TIMESTAMP_OF_CHANGE_BIT_SIZE = 32;
export const DEFAULT_UPDATE_DELAY = 86400;
Expand All @@ -517,6 +527,7 @@ export enum DomainSeparator {
EVENT_LOG_TAG = 926040838,
NOTE_COMPLETION_LOG_TAG = 3372669888,
UNCONSTRAINED_MSG_LOG_TAG = 1485357192,
CONSTRAINED_MSG_LOG_TAG = 3715244738,
NON_INTERACTIVE_HANDSHAKE_LOG_TAG = 4046403018,
PRIVATE_LOG_FIRST_FIELD = 2769976252,
PUBLIC_LEAF_SLOT = 1247650290,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { ExtendedDirectionalAppTaggingSecret, type TaggingIndexRange } from '@aztec/stdlib/logs';
import { type AppTaggingSecret, type TaggingIndexRange, appTaggingSecretFromString } from '@aztec/stdlib/logs';

/**
* A map that stores the tagging index range for a given extended directional app tagging secret.
* Note: The directional app tagging secret is unique for a (sender, recipient, contract) tuple while the direction
* of sender -> recipient matters.
* A map that stores the tagging index range for a given sender-side `AppTaggingSecret`.
*/
export class ExecutionTaggingIndexCache {
private taggingIndexMap: Map<string, { lowestIndex: number; highestIndex: number }> = new Map();

public getLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret): number | undefined {
public getLastUsedIndex(secret: AppTaggingSecret): number | undefined {
return this.taggingIndexMap.get(secret.toString())?.highestIndex;
}

public setLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number) {
public setLastUsedIndex(secret: AppTaggingSecret, index: number) {
const currentValue = this.taggingIndexMap.get(secret.toString());
if (currentValue !== undefined && currentValue.highestIndex !== index - 1) {
throw new Error(`Invalid tagging index update. Current value: ${currentValue.highestIndex}, new value: ${index}`);
Expand All @@ -29,7 +27,7 @@ export class ExecutionTaggingIndexCache {
*/
public getUsedTaggingIndexRanges(): TaggingIndexRange[] {
return Array.from(this.taggingIndexMap.entries()).map(([secret, { lowestIndex, highestIndex }]) => ({
extendedSecret: ExtendedDirectionalAppTaggingSecret.fromString(secret),
extendedSecret: appTaggingSecretFromString(secret),
lowestIndex,
highestIndex,
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,5 @@ export interface IPrivateExecutionOracle {
getSenderForTags(): Promise<AztecAddress | undefined>;
setSenderForTags(senderForTags: AztecAddress): Promise<void>;
getNextAppTagAsSender(sender: AztecAddress, recipient: AztecAddress): Promise<Tag>;
getNextConstrainedIndex(appSiloedSecret: Fr): Promise<number>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,12 @@ export class Oracle {
return [toACVMField(tag.value)];
}

// eslint-disable-next-line camelcase
async aztec_prv_getNextConstrainedIndex([appSiloedSecret]: ACVMField[]): Promise<ACVMField[]> {
const index = await this.handlerAsPrivate().getNextConstrainedIndex(Fr.fromString(appSiloedSecret));
return [toACVMField(index)];
}

// eslint-disable-next-line camelcase
async aztec_utl_getPendingTaggedLogs(
[pendingTaggedLogArrayBaseSlot]: ACVMField[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ import {
import { AztecAddress } from '@aztec/stdlib/aztec-address';
import { siloNullifier } from '@aztec/stdlib/hash';
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
import { type ContractClassLog, ExtendedDirectionalAppTaggingSecret, type TaggingIndexRange } from '@aztec/stdlib/logs';
import {
type AppTaggingSecret,
ConstrainedAppTaggingSecret,
type ContractClassLog,
ExtendedDirectionalAppTaggingSecret,
type TaggingIndexRange,
} from '@aztec/stdlib/logs';
import { Tag } from '@aztec/stdlib/logs';
import { Note, type NoteStatus } from '@aztec/stdlib/note';
import {
Expand Down Expand Up @@ -198,7 +204,11 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
}

/**
* Returns the next app tag for a given sender and recipient pair.
* Returns the next app tag for a given sender and recipient pair (unconstrained delivery).
*
* The simulator owns the directional tagging secret (derived via ECDH from `(sender, recipient, contract)`), so it
* computes the full siloed tag here and hands the opaque value back to the caller.
*
* @param sender - The address sending the log
* @param recipient - The address receiving the log
* @returns An app tag to be used in a log.
Expand All @@ -220,15 +230,40 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
return Tag.random();
}

const index = await this.#getIndexToUseForSecret(extendedSecret);
const index = await this.#reserveNextIndexForSecret(extendedSecret);
this.logger.debug(
`Incrementing tagging index for sender: ${sender}, recipient: ${recipient}, contract: ${this.contractAddress} to ${index}`,
);
this.taggingIndexCache.setLastUsedIndex(extendedSecret, index);

return Tag.compute({ extendedSecret, index });
}

/**
* Returns the next sender-side index for a constrained-delivery app-siloed shared secret.
*
* Unlike the unconstrained variant, the simulator does not own the secret: it was supplied by the calling contract
* (which retrieved it from an onchain handshake registry). The simulator only acts as a per-secret index counter. The caller
* computes the onchain tag itself.
*
* @param appSiloedSecret - The app-siloed shared secret retrieved from the handshake registry by the caller.
* @returns The next index to use for this secret.
*/
public async getNextConstrainedIndex(appSiloedSecret: Fr): Promise<number> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this detect already if another PXE with the same recipient-sender pair used an index? For example, PXE A uses 1, so PXE B detects it and moves on to index 2

Maybe the unconstrained path already did it, what why I'm asking. It would be a nice e2e test to have if I'm being honest

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized I edited the tag computation in yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.ts but didn't update any tests in yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts. Do you think that would be sufficient for testing here? Looking at "step 1: highest finalized index is updated" this looks like basically what we want to test.

Copy link
Copy Markdown
Contributor

@nchamo nchamo May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, that is exactly what we needed. I love it when the code already works as expected 🎉

No need to do anything else

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The siloing only checks unconstrained tags still though. So I will extend that one test to check both tag kinds.

const secret = new ConstrainedAppTaggingSecret(appSiloedSecret, this.contractAddress);
const index = await this.#reserveNextIndexForSecret(secret);
this.logger.debug(
`Incrementing tagging index for constrained-delivery secret in contract ${this.contractAddress} to ${index}`,
);
return index;
}

/** Resolves the next index for a given tagging secret, syncing from chain if it is missing from the in-tx cache. */
async #reserveNextIndexForSecret(secret: AppTaggingSecret): Promise<number> {
const index = await this.#getIndexToUseForSecret(secret);
this.taggingIndexCache.setLastUsedIndex(secret, index);
return index;
}

async #calculateExtendedDirectionalAppTaggingSecret(
contractAddress: AztecAddress,
sender: AztecAddress,
Expand All @@ -245,7 +280,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
);
}

async #getIndexToUseForSecret(secret: ExtendedDirectionalAppTaggingSecret): Promise<number> {
async #getIndexToUseForSecret(secret: AppTaggingSecret): Promise<number> {
// If we have the tagging index in the cache, we use it. If not we obtain it from the execution data provider.
const lastUsedIndexInTx = this.taggingIndexCache.getLastUsedIndex(secret);

Expand Down
4 changes: 2 additions & 2 deletions yarn-project/pxe/src/oracle_version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
/// if AZTEC_NR_MINOR > PXE_MINOR because if a contract is updated to use a newer Aztec.nr dependency without actually
/// using any of the new oracles then there is no reason to throw.
export const ORACLE_VERSION_MAJOR = 22;
export const ORACLE_VERSION_MINOR = 3;
export const ORACLE_VERSION_MINOR = 4;

/// This hash is computed from the Oracle interface and is used to detect when that interface changes. When it does,
/// you need to either:
/// - increment `ORACLE_VERSION_MAJOR` and reset `ORACLE_VERSION_MINOR` to zero if the change is breaking, or
/// - increment only `ORACLE_VERSION_MINOR` if the change is additive (a new oracle was added).
///
/// These constants must be kept in sync between this file and `noir-projects/aztec-nr/aztec/src/oracle/version.nr`.
export const ORACLE_INTERFACE_HASH = '0649632102f27d1411749e46733b96103eaac948914d328afc4b90d3bf6e5af5';
export const ORACLE_INTERFACE_HASH = 'bff6ee56a09a4081cbd1c98c3983e438c775e7a83eb82fcfe17a342705fd4a10';
Loading
Loading