Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
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_tagging_index(app_siloed_secret: Field) -> u32 {
get_next_constrained_tagging_index_oracle(app_siloed_secret)
}

#[oracle(aztec_prv_getNextConstrainedTaggingIndex)]
unconstrained fn get_next_constrained_tagging_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 = 25;
pub global ORACLE_VERSION_MINOR: Field = 0;
pub global ORACLE_VERSION_MINOR: Field = 1;

/// 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 @@ -716,6 +716,8 @@ 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`].
pub global DOM_SEP__CONSTRAINED_MSG_LOG_TAG: u32 = 3715244738;
/// 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,11 +9,11 @@ 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_V2,
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__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONSTRAINED_MSG_LOG_TAG,
DOM_SEP__CONTRACT_ADDRESS_V2, 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,
DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS,
Expand Down Expand Up @@ -143,7 +143,7 @@ impl<let NUM_VALUES: u32, let NUM_U32_VALUES: u32> HashedValueTester<NUM_VALUES,

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

// -----------------
// Domain separators
Expand Down Expand Up @@ -176,6 +176,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
1 change: 1 addition & 0 deletions yarn-project/constants/src/constants.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,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
Expand Up @@ -197,4 +197,5 @@ export interface IPrivateExecutionOracle {
getSenderForTags(): Promise<Option<AztecAddress>>;
setSenderForTags(senderForTags: AztecAddress): Promise<void>;
getNextAppTagAsSender(sender: AztecAddress, recipient: AztecAddress): Promise<Tag>;
getNextConstrainedTaggingIndex(appSiloedSecret: Fr): Promise<number>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,15 @@ export class Oracle {
});
}

// eslint-disable-next-line camelcase
aztec_prv_getNextConstrainedTaggingIndex(...inputs: ACVMField[][]): Promise<(ACVMField | ACVMField[])[]> {
return callHandler({
oracle: 'aztec_prv_getNextConstrainedTaggingIndex',
inputs,
handler: ([appSiloedSecret]) => this.handlerAsPrivate().getNextConstrainedTaggingIndex(appSiloedSecret),
});
}

// eslint-disable-next-line camelcase
aztec_utl_getPendingTaggedLogs(...inputs: ACVMField[][]): Promise<(ACVMField | ACVMField[])[]> {
return callHandler({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,11 @@ const ORACLE_REGISTRY = {
returnType: TAG,
}),

aztec_prv_getNextConstrainedTaggingIndex: makeEntry({
params: [{ name: 'appSiloedSecret', type: FIELD }],
returnType: U32,
}),

aztec_prv_getSenderForTags: makeEntry({ returnType: OPTION(AZTEC_ADDRESS) }),

aztec_prv_setSenderForTags: makeEntry({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ import {
import { AztecAddress } from '@aztec/stdlib/aztec-address';
import { siloNullifier } from '@aztec/stdlib/hash';
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
import { AppTaggingSecret, type ContractClassLog, type TaggingIndexRange } from '@aztec/stdlib/logs';
import { Tag } from '@aztec/stdlib/logs';
import {
AppTaggingSecret,
AppTaggingSecretKind,
type ContractClassLog,
Tag,
type TaggingIndexRange,
} from '@aztec/stdlib/logs';
import { Note, type NoteStatus } from '@aztec/stdlib/note';
import {
CallContext,
Expand Down Expand Up @@ -201,7 +206,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 @@ -219,19 +228,50 @@ 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 getNextConstrainedTaggingIndex(appSiloedSecret: Fr): Promise<number> {
const secret = new AppTaggingSecret(appSiloedSecret, this.contractAddress, AppTaggingSecretKind.CONSTRAINED);
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 #calculateAppTaggingSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
const senderCompleteAddress = await this.getCompleteAddressOrFail(sender);
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
return AppTaggingSecret.compute(senderCompleteAddress, senderIvsk, recipient, contractAddress, recipient);
return AppTaggingSecret.computeUnconstrained(
senderCompleteAddress,
senderIvsk,
recipient,
contractAddress,
recipient,
);
}

async #getIndexToUseForSecret(secret: AppTaggingSecret): Promise<number> {
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/pxe/src/logs/log_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export class LogService {

return Promise.all(
deduplicatedSenders.map(async sender => {
const secret = await AppTaggingSecret.compute(
const secret = await AppTaggingSecret.computeUnconstrained(
recipientCompleteAddress,
recipientIvsk,
sender,
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 = 25;
export const ORACLE_VERSION_MINOR = 0;
export const ORACLE_VERSION_MINOR = 1;

/// 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 = 'da24bdc7eb9cdee8bcdb61905a5306d62b9c2da5565c28ff75c44f9404efd571';
export const ORACLE_INTERFACE_HASH = '69655a31fd7cc8ad71635e71d50d9b7e0b3690f1a3e39ce992c9f872b06fea0f';
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Fr } from '@aztec/foundation/curves/bn254';
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
import { RevertCode } from '@aztec/stdlib/avm';
import type { AppTaggingSecret, TaggingIndexRange } from '@aztec/stdlib/logs';
import { PrivateLog, SiloedTag } from '@aztec/stdlib/logs';
import { randomAppTaggingSecret } from '@aztec/stdlib/testing';
import { AppTaggingSecret, PrivateLog, SiloedTag, type TaggingIndexRange } from '@aztec/stdlib/logs';
import { randomAppTaggingSecret, randomConstrainedAppTaggingSecret } from '@aztec/stdlib/testing';
import { TxEffect, TxHash } from '@aztec/stdlib/tx';

import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../../tagging/constants.js';
Expand Down Expand Up @@ -606,6 +605,47 @@ describe('SenderTaggingStore', () => {
expect(await taggingStore.getLastFinalizedIndex(secret1, 'test')).toBe(4);
expect(await taggingStore.getTxHashesOfPendingIndexes(secret1, 0, 10, 'test')).toHaveLength(0);
});

it('recomputes siloed tags via the constrained domain separator for constrained-delivery secrets', async () => {
const constrainedSecret = await randomConstrainedAppTaggingSecret();
const txHash = TxHash.random();

await taggingStore.storePendingIndexes([range(constrainedSecret, 3, 5)], txHash, 'test');

// The onchain tag must be derived with the constrained log domain separator.
const survivingTag = await SiloedTag.compute({ extendedSecret: constrainedSecret, index: 4 });
const txEffect = makeTxEffect(txHash, [survivingTag]);

await taggingStore.finalizePendingIndexesOfAPartiallyRevertedTx(txEffect, 'test');

expect(await taggingStore.getLastFinalizedIndex(constrainedSecret, 'test')).toBe(4);
expect(await taggingStore.getTxHashesOfPendingIndexes(constrainedSecret, 0, 10, 'test')).toHaveLength(0);
});

// If an unconstrained tag (computed with the unconstrained domain separator) accidentally appears in a tx
// effect alongside a pending range for the *same* underlying Fr but registered as a constrained secret, the
// finalizer must not treat it as a surviving constrained-tag. The onchain emission would have used the
// constrained domain separator, so the values are different.
it('does not cross-match a tag computed under the wrong domain separator', async () => {
const constrainedSecret = await randomConstrainedAppTaggingSecret();

const txHash = TxHash.random();
await taggingStore.storePendingIndexes([range(constrainedSecret, 0, 2)], txHash, 'test');

// Build an unconstrained twin whose `secret` field happens to equal the constrained secret's `secret`. Doing
// this via the public construction path keeps the test independent of how the production code derives Frs.
// Emit a tag using the *unconstrained* domain separator for the same Fr/index combination. This should NOT match.
const wrongDomSepTag = await SiloedTag.compute({
extendedSecret: new AppTaggingSecret(constrainedSecret.secret, constrainedSecret.app),
index: 1,
});
const txEffect = makeTxEffect(txHash, [wrongDomSepTag]);

await taggingStore.finalizePendingIndexesOfAPartiallyRevertedTx(txEffect, 'test');

// No constrained index survived (the domain separator mismatch means the tag doesn't reconstruct).
expect(await taggingStore.getLastFinalizedIndex(constrainedSecret, 'test')).toBeUndefined();
});
});

describe('staged writes', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
import { AppTaggingSecret, SiloedTag, type TaggingIndexRange } from '@aztec/stdlib/logs';
import {
AppTaggingSecret,
SiloedTag,
type TaggingIndexRange,
} from '@aztec/stdlib/logs';
import { TxEffect, TxHash } from '@aztec/stdlib/tx';

import type { StagedStore } from '../../job_coordinator/job_coordinator.js';
Expand Down Expand Up @@ -449,11 +453,11 @@ export class SenderTaggingStore implements StagedStore {
const pendingEntry = matchingEntries[0];

// Expand each matching entry's range and recompute siloed tags for each index.
const extendedSecret = AppTaggingSecret.fromString(secret);
const appTaggingSecret = AppTaggingSecret.fromString(secret);
let highestSurvivingIndex: number | undefined;

for (let index = pendingEntry.lowestIndex; index <= pendingEntry.highestIndex; index++) {
const siloedTag = await SiloedTag.compute({ extendedSecret, index });
const siloedTag = await SiloedTag.compute({ extendedSecret: appTaggingSecret, index });
if (onChainTags.has(siloedTag.value.toString())) {
highestSurvivingIndex = highestSurvivingIndex !== undefined ? Math.max(highestSurvivingIndex, index) : index;
}
Expand Down
14 changes: 7 additions & 7 deletions yarn-project/pxe/src/tagging/reconcile_tagging_index_ranges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { type AppTaggingSecret, SiloedTag, type TaggingIndexRange } from '@aztec
* private logs survived to the final kernel output.
*
* Each input range is the contiguous `[lowestIndex, highestIndex]` set of indexes that the tagging index cache
* reserved for a given `(sender, recipient, app)` secret while a tx was being executed. The kernel may then squash
* some of those logs (e.g. when a note is created and nullified within the same tx, taking its log with it), so the
* actual on-chain footprint can be a strict subset of what was reserved.
* reserved for a given tagging secret while a tx was being executed. The kernel may then squash some of those logs
* (e.g. when a note is created and nullified within the same tx, taking its log with it), so the actual on-chain
* footprint can be a strict subset of what was reserved.
*
* For each input range, this function shrinks `[lowestIndex, highestIndex]` so that both bounds correspond to indexes
* that actually survived, trimming any dropped indices at the front or the back. It is possible that some interior
Expand Down Expand Up @@ -71,13 +71,13 @@ export async function reconcileTaggingIndexRangesAgainstSurvivingTags(

/** Scans `[start, end]` ascending and returns the first index whose siloed tag is in `survivingTags`. */
async function findFirstSurvivingIndex(
extendedSecret: AppTaggingSecret,
secret: AppTaggingSecret,
start: number,
end: number,
survivingTags: Set<string>,
): Promise<number | undefined> {
for (let index = start; index <= end; index++) {
const tag = await SiloedTag.compute({ extendedSecret, index });
const tag = await SiloedTag.compute({ extendedSecret: secret, index });
if (survivingTags.has(tag.value.toString())) {
return index;
}
Expand All @@ -87,13 +87,13 @@ async function findFirstSurvivingIndex(

/** Scans `[start, end]` descending and returns the first index whose siloed tag is in `survivingTags`. */
async function findLastSurvivingIndex(
extendedSecret: AppTaggingSecret,
secret: AppTaggingSecret,
start: number,
end: number,
survivingTags: Set<string>,
): Promise<number | undefined> {
for (let index = end; index >= start; index--) {
const tag = await SiloedTag.compute({ extendedSecret, index });
const tag = await SiloedTag.compute({ extendedSecret: secret, index });
if (survivingTags.has(tag.value.toString())) {
return index;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import { loadAndStoreNewTaggingIndexes } from './utils/load_and_store_new_taggin
/**
* Syncs tagging indexes. This function needs to be called whenever a private log is being sent.
*
* @param secret - The secret that's unique for (sender, recipient, app) tuple while the direction of
* sender -> recipient matters.
* @param secret - The sender-side tagging `AppTaggingSecret`.
* @remarks When syncing the indexes as sender we don't care about the log contents - we only care about the highest
* pending and highest finalized indexes as that guides the next index choice when sending a log. The next index choice
* is simply the highest pending index plus one (or finalized if pending is undefined).
Expand Down
Loading
Loading