diff --git a/yarn-project/pxe/src/contract_function_simulator/execution_tagging_index_cache.ts b/yarn-project/pxe/src/contract_function_simulator/execution_tagging_index_cache.ts index 85a45f7fb108..37ffc83016d9 100644 --- a/yarn-project/pxe/src/contract_function_simulator/execution_tagging_index_cache.ts +++ b/yarn-project/pxe/src/contract_function_simulator/execution_tagging_index_cache.ts @@ -1,18 +1,18 @@ -import { DirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs'; +import { ExtendedDirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs'; /** - * A map that stores the tagging index for a given directional app tagging secret. + * A map that stores the tagging index 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. */ export class ExecutionTaggingIndexCache { private taggingIndexMap: Map = new Map(); - public getLastUsedIndex(secret: DirectionalAppTaggingSecret): number | undefined { + public getLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret): number | undefined { return this.taggingIndexMap.get(secret.toString()); } - public setLastUsedIndex(secret: DirectionalAppTaggingSecret, index: number) { + public setLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number) { const currentValue = this.taggingIndexMap.get(secret.toString()); if (currentValue !== undefined && currentValue !== index - 1) { throw new Error(`Invalid tagging index update. Current value: ${currentValue}, new value: ${index}`); @@ -25,7 +25,7 @@ export class ExecutionTaggingIndexCache { */ public getUsedPreTags(): PreTag[] { return Array.from(this.taggingIndexMap.entries()).map(([secret, index]) => ({ - secret: DirectionalAppTaggingSecret.fromString(secret), + extendedSecret: ExtendedDirectionalAppTaggingSecret.fromString(secret), index, })); } diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution_oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution_oracle.ts index f49faf4a03e2..c6d33cc7244e 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution_oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution_oracle.ts @@ -14,7 +14,7 @@ import { import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { siloNullifier } from '@aztec/stdlib/hash'; import { PrivateContextInputs } from '@aztec/stdlib/kernel'; -import { type ContractClassLog, DirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs'; +import { type ContractClassLog, ExtendedDirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs'; import { Tag } from '@aztec/stdlib/logs'; import { Note, type NoteStatus } from '@aztec/stdlib/note'; import { @@ -216,25 +216,29 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP * @returns An app tag to be used in a log. */ public async privateGetNextAppTagAsSender(sender: AztecAddress, recipient: AztecAddress): Promise { - const secret = await this.#calculateDirectionalAppTaggingSecret(this.contractAddress, sender, recipient); + const extendedSecret = await this.#calculateExtendedDirectionalAppTaggingSecret( + this.contractAddress, + sender, + recipient, + ); - const index = await this.#getIndexToUseForSecret(secret); + const index = await this.#getIndexToUseForSecret(extendedSecret); this.log.debug( `Incrementing tagging index for sender: ${sender}, recipient: ${recipient}, contract: ${this.contractAddress} to ${index}`, ); - this.taggingIndexCache.setLastUsedIndex(secret, index); + this.taggingIndexCache.setLastUsedIndex(extendedSecret, index); - return Tag.compute({ secret, index }); + return Tag.compute({ extendedSecret, index }); } - async #calculateDirectionalAppTaggingSecret( + async #calculateExtendedDirectionalAppTaggingSecret( contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress, ) { const senderCompleteAddress = await this.getCompleteAddressOrFail(sender); const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender); - return DirectionalAppTaggingSecret.compute( + return ExtendedDirectionalAppTaggingSecret.compute( senderCompleteAddress, senderIvsk, recipient, @@ -243,7 +247,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP ); } - async #getIndexToUseForSecret(secret: DirectionalAppTaggingSecret): Promise { + async #getIndexToUseForSecret(secret: ExtendedDirectionalAppTaggingSecret): Promise { // 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); @@ -255,7 +259,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP // that'd be wasteful as most tagging secrets are not used in each tx. await syncSenderTaggingIndexes( secret, - this.contractAddress, this.aztecNode, this.senderTaggingStore, await this.anchorBlockHeader.hash(), diff --git a/yarn-project/pxe/src/logs/log_service.ts b/yarn-project/pxe/src/logs/log_service.ts index 55a90c779a4b..aff6c65a03ac 100644 --- a/yarn-project/pxe/src/logs/log_service.ts +++ b/yarn-project/pxe/src/logs/log_service.ts @@ -3,7 +3,13 @@ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundatio import type { KeyStore } from '@aztec/key-store'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { DirectionalAppTaggingSecret, PendingTaggedLog, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs'; +import { + ExtendedDirectionalAppTaggingSecret, + PendingTaggedLog, + SiloedTag, + Tag, + TxScopedL2Log, +} from '@aztec/stdlib/logs'; import type { BlockHeader } from '@aztec/stdlib/tx'; import type { AccessScopes } from '../access_scopes.js'; @@ -130,7 +136,6 @@ export class LogService { secrets.map(secret => loadPrivateLogsForSenderRecipientPair( secret, - contractAddress, this.aztecNode, this.recipientTaggingStore, anchorBlockNumber, @@ -154,7 +159,7 @@ export class LogService { async #getSecretsForSenders( contractAddress: AztecAddress, recipient: AztecAddress, - ): Promise { + ): Promise { const recipientCompleteAddress = await this.addressStore.getCompleteAddress(recipient); if (!recipientCompleteAddress) { return []; @@ -172,7 +177,7 @@ export class LogService { return Promise.all( deduplicatedSenders.map(sender => { - return DirectionalAppTaggingSecret.compute( + return ExtendedDirectionalAppTaggingSecret.compute( recipientCompleteAddress, recipientIvsk, sender, diff --git a/yarn-project/pxe/src/storage/tagging_store/recipient_tagging_store.test.ts b/yarn-project/pxe/src/storage/tagging_store/recipient_tagging_store.test.ts index 49ff3ad27a89..33f2c60d2291 100644 --- a/yarn-project/pxe/src/storage/tagging_store/recipient_tagging_store.test.ts +++ b/yarn-project/pxe/src/storage/tagging_store/recipient_tagging_store.test.ts @@ -1,18 +1,18 @@ -import { Fr } from '@aztec/foundation/curves/bn254'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; -import { DirectionalAppTaggingSecret } from '@aztec/stdlib/logs'; +import type { ExtendedDirectionalAppTaggingSecret } from '@aztec/stdlib/logs'; +import { randomExtendedDirectionalAppTaggingSecret } from '@aztec/stdlib/testing'; import { RecipientTaggingStore } from './recipient_tagging_store.js'; describe('RecipientTaggingStore', () => { let taggingStore: RecipientTaggingStore; - let secret1: DirectionalAppTaggingSecret; - let secret2: DirectionalAppTaggingSecret; + let secret1: ExtendedDirectionalAppTaggingSecret; + let secret2: ExtendedDirectionalAppTaggingSecret; beforeEach(async () => { taggingStore = new RecipientTaggingStore(await openTmpStore('test')); - secret1 = DirectionalAppTaggingSecret.fromString(Fr.random().toString()); - secret2 = DirectionalAppTaggingSecret.fromString(Fr.random().toString()); + secret1 = await randomExtendedDirectionalAppTaggingSecret(); + secret2 = await randomExtendedDirectionalAppTaggingSecret(); }); describe('staged writes', () => { diff --git a/yarn-project/pxe/src/storage/tagging_store/recipient_tagging_store.ts b/yarn-project/pxe/src/storage/tagging_store/recipient_tagging_store.ts index d492c0ff99b8..148d9b59dcfc 100644 --- a/yarn-project/pxe/src/storage/tagging_store/recipient_tagging_store.ts +++ b/yarn-project/pxe/src/storage/tagging_store/recipient_tagging_store.ts @@ -1,5 +1,5 @@ import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store'; -import type { DirectionalAppTaggingSecret } from '@aztec/stdlib/logs'; +import type { ExtendedDirectionalAppTaggingSecret } from '@aztec/stdlib/logs'; import type { StagedStore } from '../../job_coordinator/job_coordinator.js'; @@ -106,11 +106,11 @@ export class RecipientTaggingStore implements StagedStore { return Promise.resolve(); } - getHighestAgedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise { + getHighestAgedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise { return this.#store.transactionAsync(() => this.#readHighestAgedIndex(jobId, secret.toString())); } - updateHighestAgedIndex(secret: DirectionalAppTaggingSecret, index: number, jobId: string): Promise { + updateHighestAgedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number, jobId: string): Promise { return this.#store.transactionAsync(async () => { const currentIndex = await this.#readHighestAgedIndex(jobId, secret.toString()); if (currentIndex !== undefined && index <= currentIndex) { @@ -121,11 +121,15 @@ export class RecipientTaggingStore implements StagedStore { }); } - getHighestFinalizedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise { + getHighestFinalizedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise { return this.#store.transactionAsync(() => this.#readHighestFinalizedIndex(jobId, secret.toString())); } - updateHighestFinalizedIndex(secret: DirectionalAppTaggingSecret, index: number, jobId: string): Promise { + updateHighestFinalizedIndex( + secret: ExtendedDirectionalAppTaggingSecret, + index: number, + jobId: string, + ): Promise { return this.#store.transactionAsync(async () => { const currentIndex = await this.#readHighestFinalizedIndex(jobId, secret.toString()); if (currentIndex !== undefined && index < currentIndex) { diff --git a/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts b/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts index 7b78ce0141a3..986f1daef6fc 100644 --- a/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts +++ b/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.test.ts @@ -1,6 +1,6 @@ -import { Fr } from '@aztec/foundation/curves/bn254'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; -import { DirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs'; +import type { ExtendedDirectionalAppTaggingSecret, PreTag } from '@aztec/stdlib/logs'; +import { randomExtendedDirectionalAppTaggingSecret } from '@aztec/stdlib/testing'; import { TxHash } from '@aztec/stdlib/tx'; import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../../tagging/constants.js'; @@ -8,19 +8,19 @@ import { SenderTaggingStore } from './sender_tagging_store.js'; describe('SenderTaggingStore', () => { let taggingStore: SenderTaggingStore; - let secret1: DirectionalAppTaggingSecret; - let secret2: DirectionalAppTaggingSecret; + let secret1: ExtendedDirectionalAppTaggingSecret; + let secret2: ExtendedDirectionalAppTaggingSecret; beforeEach(async () => { taggingStore = new SenderTaggingStore(await openTmpStore('test')); - secret1 = DirectionalAppTaggingSecret.fromString(Fr.random().toString()); - secret2 = DirectionalAppTaggingSecret.fromString(Fr.random().toString()); + secret1 = await randomExtendedDirectionalAppTaggingSecret(); + secret2 = await randomExtendedDirectionalAppTaggingSecret(); }); describe('storePendingIndexes', () => { it('stores a single pending index', async () => { const txHash = TxHash.random(); - const preTag: PreTag = { secret: secret1, index: 5 }; + const preTag: PreTag = { extendedSecret: secret1, index: 5 }; await taggingStore.storePendingIndexes([preTag], txHash, 'test'); @@ -32,8 +32,8 @@ describe('SenderTaggingStore', () => { it('stores multiple pending indexes for different secrets', async () => { const txHash = TxHash.random(); const preTags: PreTag[] = [ - { secret: secret1, index: 3 }, - { secret: secret2, index: 7 }, + { extendedSecret: secret1, index: 3 }, + { extendedSecret: secret2, index: 7 }, ]; await taggingStore.storePendingIndexes(preTags, txHash, 'test'); @@ -51,8 +51,8 @@ describe('SenderTaggingStore', () => { const txHash1 = TxHash.random(); const txHash2 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash2, 'test'); const txHashes = await taggingStore.getTxHashesOfPendingIndexes(secret1, 0, 10, 'test'); expect(txHashes).toHaveLength(2); @@ -62,7 +62,7 @@ describe('SenderTaggingStore', () => { it('ignores duplicate preTag + txHash combination', async () => { const txHash = TxHash.random(); - const preTag: PreTag = { secret: secret1, index: 5 }; + const preTag: PreTag = { extendedSecret: secret1, index: 5 }; await taggingStore.storePendingIndexes([preTag], txHash, 'test'); await taggingStore.storePendingIndexes([preTag], txHash, 'test'); @@ -75,8 +75,8 @@ describe('SenderTaggingStore', () => { it('throws when storing duplicate secrets in the same call', async () => { const txHash = TxHash.random(); const preTags: PreTag[] = [ - { secret: secret1, index: 3 }, - { secret: secret1, index: 7 }, + { extendedSecret: secret1, index: 3 }, + { extendedSecret: secret1, index: 7 }, ]; await expect(taggingStore.storePendingIndexes(preTags, txHash, 'test')).rejects.toThrow( @@ -88,12 +88,12 @@ describe('SenderTaggingStore', () => { const txHash = TxHash.random(); // First store an index - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash, 'test'); // Try to store a different index for the same secret + txHash pair - await expect(taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash, 'test')).rejects.toThrow( - /Cannot store index 7.*a different index 5 already exists/, - ); + await expect( + taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash, 'test'), + ).rejects.toThrow(/Cannot store index 7.*a different index 5 already exists/); }); it('throws when storing a pending index lower than the last finalized index', async () => { @@ -101,13 +101,13 @@ describe('SenderTaggingStore', () => { const txHash2 = TxHash.random(); // First store and finalize an index - await taggingStore.storePendingIndexes([{ secret: secret1, index: 10 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 10 }], txHash1, 'test'); await taggingStore.finalizePendingIndexes([txHash1], 'test'); // Try to store a pending index lower than the finalized index - await expect(taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash2, 'test')).rejects.toThrow( - /Cannot store pending index 5.*lower than or equal to the last finalized index 10/, - ); + await expect( + taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash2, 'test'), + ).rejects.toThrow(/Cannot store pending index 5.*lower than or equal to the last finalized index 10/); }); it('throws when storing a pending index equal to the last finalized index', async () => { @@ -115,13 +115,13 @@ describe('SenderTaggingStore', () => { const txHash2 = TxHash.random(); // First store and finalize an index - await taggingStore.storePendingIndexes([{ secret: secret1, index: 10 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 10 }], txHash1, 'test'); await taggingStore.finalizePendingIndexes([txHash1], 'test'); // Try to store a pending index equal to the finalized index - await expect(taggingStore.storePendingIndexes([{ secret: secret1, index: 10 }], txHash2, 'test')).rejects.toThrow( - /Cannot store pending index 10.*lower than or equal to the last finalized index 10/, - ); + await expect( + taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 10 }], txHash2, 'test'), + ).rejects.toThrow(/Cannot store pending index 10.*lower than or equal to the last finalized index 10/); }); it('allows storing a pending index higher than the last finalized index', async () => { @@ -129,12 +129,12 @@ describe('SenderTaggingStore', () => { const txHash2 = TxHash.random(); // First store and finalize an index - await taggingStore.storePendingIndexes([{ secret: secret1, index: 10 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 10 }], txHash1, 'test'); await taggingStore.finalizePendingIndexes([txHash1], 'test'); // Store a pending index higher than the finalized index - should succeed await expect( - taggingStore.storePendingIndexes([{ secret: secret1, index: 15 }], txHash2, 'test'), + taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 15 }], txHash2, 'test'), ).resolves.not.toThrow(); const txHashes = await taggingStore.getTxHashesOfPendingIndexes(secret1, 0, 20, 'test'); @@ -150,12 +150,12 @@ describe('SenderTaggingStore', () => { const indexBeyondWindow = finalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN + 1; // First store and finalize an index - await taggingStore.storePendingIndexes([{ secret: secret1, index: finalizedIndex }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: finalizedIndex }], txHash1, 'test'); await taggingStore.finalizePendingIndexes([txHash1], 'test'); // Try to store an index beyond the window await expect( - taggingStore.storePendingIndexes([{ secret: secret1, index: indexBeyondWindow }], txHash2, 'test'), + taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: indexBeyondWindow }], txHash2, 'test'), ).rejects.toThrow( `Highest used index ${indexBeyondWindow} is further than window length from the highest finalized index ${finalizedIndex}`, ); @@ -168,12 +168,12 @@ describe('SenderTaggingStore', () => { const indexAtBoundary = finalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN; // First store and finalize an index - await taggingStore.storePendingIndexes([{ secret: secret1, index: finalizedIndex }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: finalizedIndex }], txHash1, 'test'); await taggingStore.finalizePendingIndexes([txHash1], 'test'); // Store an index at the boundary, but check is >, so it should succeed await expect( - taggingStore.storePendingIndexes([{ secret: secret1, index: indexAtBoundary }], txHash2, 'test'), + taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: indexAtBoundary }], txHash2, 'test'), ).resolves.not.toThrow(); const txHashes = await taggingStore.getTxHashesOfPendingIndexes(secret1, 0, indexAtBoundary + 5, 'test'); @@ -194,9 +194,9 @@ describe('SenderTaggingStore', () => { const txHash2 = TxHash.random(); const txHash3 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash2, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 8 }], txHash3, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 8 }], txHash3, 'test'); const txHashes = await taggingStore.getTxHashesOfPendingIndexes(secret1, 4, 9, 'test'); expect(txHashes).toHaveLength(2); @@ -209,8 +209,8 @@ describe('SenderTaggingStore', () => { const txHash1 = TxHash.random(); const txHash2 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 10 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 10 }], txHash2, 'test'); const txHashes = await taggingStore.getTxHashesOfPendingIndexes(secret1, 5, 10, 'test'); expect(txHashes).toHaveLength(1); @@ -223,13 +223,13 @@ describe('SenderTaggingStore', () => { const txHash3 = TxHash.random(); const txHash4 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash2, 'test'); // We store different secret with txHash1 to check we correctly don't return it in the result - await taggingStore.storePendingIndexes([{ secret: secret2, index: 7 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret2, index: 7 }], txHash1, 'test'); // Store "parallel" index for secret1 with a different tx (can happen when sending logs from multiple PXEs) - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash3, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash4, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash3, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash4, 'test'); const txHashes = await taggingStore.getTxHashesOfPendingIndexes(secret1, 0, 10, 'test'); // Should have 3 unique tx hashes for secret1 @@ -245,7 +245,7 @@ describe('SenderTaggingStore', () => { it('returns the last finalized index after finalizePendingIndexes', async () => { const txHash = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash, 'test'); await taggingStore.finalizePendingIndexes([txHash], 'test'); const lastFinalized = await taggingStore.getLastFinalizedIndex(secret1, 'test'); @@ -261,7 +261,7 @@ describe('SenderTaggingStore', () => { it('returns the last finalized index when no pending indexes exist', async () => { const txHash = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash, 'test'); await taggingStore.finalizePendingIndexes([txHash], 'test'); const lastUsed = await taggingStore.getLastUsedIndex(secret1, 'test'); @@ -273,11 +273,11 @@ describe('SenderTaggingStore', () => { const txHash2 = TxHash.random(); // First, finalize an index - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); await taggingStore.finalizePendingIndexes([txHash1], 'test'); // Then add a higher pending index - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash2, 'test'); const lastUsed = await taggingStore.getLastUsedIndex(secret1, 'test'); expect(lastUsed).toBe(7); @@ -288,9 +288,9 @@ describe('SenderTaggingStore', () => { const txHash2 = TxHash.random(); const txHash3 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash2, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash3, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash3, 'test'); const lastUsed = await taggingStore.getLastUsedIndex(secret1, 'test'); expect(lastUsed).toBe(7); @@ -302,9 +302,9 @@ describe('SenderTaggingStore', () => { const txHash1 = TxHash.random(); const txHash2 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret2, index: 5 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret2, index: 5 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash2, 'test'); await taggingStore.dropPendingIndexes([txHash1], 'test'); @@ -322,7 +322,7 @@ describe('SenderTaggingStore', () => { describe('finalizePendingIndexes', () => { it('moves pending index to finalized for a given tx hash', async () => { const txHash = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash, 'test'); await taggingStore.finalizePendingIndexes([txHash], 'test'); @@ -338,10 +338,10 @@ describe('SenderTaggingStore', () => { const txHash1 = TxHash.random(); const txHash2 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); await taggingStore.finalizePendingIndexes([txHash1], 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash2, 'test'); await taggingStore.finalizePendingIndexes([txHash2], 'test'); const lastFinalized = await taggingStore.getLastFinalizedIndex(secret1, 'test'); @@ -353,8 +353,8 @@ describe('SenderTaggingStore', () => { const txHash2 = TxHash.random(); // Store both pending indexes first - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash2, 'test'); // Finalize the higher index first await taggingStore.finalizePendingIndexes([txHash1], 'test'); @@ -371,9 +371,9 @@ describe('SenderTaggingStore', () => { const txHash2 = TxHash.random(); const txHash3 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash2, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash3, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash3, 'test'); // Finalize txHash2 (index 5) await taggingStore.finalizePendingIndexes([txHash2], 'test'); @@ -389,8 +389,8 @@ describe('SenderTaggingStore', () => { const txHash = TxHash.random(); await taggingStore.storePendingIndexes( [ - { secret: secret1, index: 3 }, - { secret: secret2, index: 7 }, + { extendedSecret: secret1, index: 3 }, + { extendedSecret: secret2, index: 7 }, ], txHash, 'test', @@ -407,7 +407,7 @@ describe('SenderTaggingStore', () => { it('does nothing when tx hash does not exist', async () => { const txHash = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash, 'test'); await taggingStore.finalizePendingIndexes([TxHash.random()], 'test'); @@ -427,7 +427,7 @@ describe('SenderTaggingStore', () => { const txHash2 = TxHash.random(); // Step 1: Add pending index - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); expect(await taggingStore.getLastUsedIndex(secret1, 'test')).toBe(3); expect(await taggingStore.getLastFinalizedIndex(secret1, 'test')).toBeUndefined(); @@ -437,7 +437,7 @@ describe('SenderTaggingStore', () => { expect(await taggingStore.getLastFinalizedIndex(secret1, 'test')).toBe(3); // Step 3: Add a new higher pending index - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash2, 'test'); expect(await taggingStore.getLastUsedIndex(secret1, 'test')).toBe(7); expect(await taggingStore.getLastFinalizedIndex(secret1, 'test')).toBe(3); @@ -451,8 +451,8 @@ describe('SenderTaggingStore', () => { const txHash1 = TxHash.random(); const txHash2 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], txHash2, 'test'); expect(await taggingStore.getLastUsedIndex(secret1, 'test')).toBe(5); @@ -468,14 +468,14 @@ describe('SenderTaggingStore', () => { const txHash3 = TxHash.random(); // Secret1: pending -> finalized - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, 'test'); await taggingStore.finalizePendingIndexes([txHash1], 'test'); // Secret2: pending (not finalized) - await taggingStore.storePendingIndexes([{ secret: secret2, index: 5 }], txHash2, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret2, index: 5 }], txHash2, 'test'); // Secret1: new pending - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash3, 'test'); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash3, 'test'); expect(await taggingStore.getLastFinalizedIndex(secret1, 'test')).toBe(3); expect(await taggingStore.getLastUsedIndex(secret1, 'test')).toBe(7); @@ -489,13 +489,13 @@ describe('SenderTaggingStore', () => { const committedTxHash = TxHash.random(); { const commitJobId: string = 'commit-job'; - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], committedTxHash, commitJobId); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], committedTxHash, commitJobId); await taggingStore.commit(commitJobId); } const stagedTxHash = TxHash.random(); const stagingJobId: string = 'staging-job'; - await taggingStore.storePendingIndexes([{ secret: secret1, index: 5 }], stagedTxHash, stagingJobId); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 5 }], stagedTxHash, stagingJobId); // For a job without any staged data we should only get committed data const txHashesWithoutJobId = await taggingStore.getTxHashesOfPendingIndexes(secret1, 0, 10, 'no-data-job'); @@ -513,7 +513,7 @@ describe('SenderTaggingStore', () => { const txHash1 = TxHash.random(); { const commitJobId: string = 'commit-job'; - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash1, commitJobId); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash1, commitJobId); await taggingStore.finalizePendingIndexes([txHash1], commitJobId); await taggingStore.commit(commitJobId); } @@ -522,7 +522,7 @@ describe('SenderTaggingStore', () => { const stagingJobId: string = 'staging-job'; // Stage a higher finalized index (not committed) - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash2, stagingJobId); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash2, stagingJobId); await taggingStore.finalizePendingIndexes([txHash2], stagingJobId); // With a different jobId, should get the committed finalized index @@ -537,8 +537,8 @@ describe('SenderTaggingStore', () => { const txHash1 = TxHash.random(); const txHash2 = TxHash.random(); const commitJobId: string = 'commit-job'; - await taggingStore.storePendingIndexes([{ secret: secret1, index: 2 }], txHash1, commitJobId); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 3 }], txHash2, commitJobId); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 2 }], txHash1, commitJobId); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 3 }], txHash2, commitJobId); await taggingStore.finalizePendingIndexes([txHash1], commitJobId); await taggingStore.commit(commitJobId); } @@ -546,7 +546,7 @@ describe('SenderTaggingStore', () => { const stagingJobId: string = 'staging-job'; { const txHash3 = TxHash.random(); - await taggingStore.storePendingIndexes([{ secret: secret1, index: 7 }], txHash3, stagingJobId); + await taggingStore.storePendingIndexes([{ extendedSecret: secret1, index: 7 }], txHash3, stagingJobId); await taggingStore.finalizePendingIndexes([txHash3], stagingJobId); await taggingStore.discardStaged(stagingJobId); } diff --git a/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.ts b/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.ts index 8da2e88ab91f..1b15bbbb207a 100644 --- a/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.ts +++ b/yarn-project/pxe/src/storage/tagging_store/sender_tagging_store.ts @@ -1,5 +1,5 @@ import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store'; -import type { DirectionalAppTaggingSecret, PreTag } from '@aztec/stdlib/logs'; +import type { ExtendedDirectionalAppTaggingSecret, PreTag } from '@aztec/stdlib/logs'; import { TxHash } from '@aztec/stdlib/tx'; import type { StagedStore } from '../../job_coordinator/job_coordinator.js'; @@ -154,7 +154,7 @@ export class SenderTaggingStore implements StagedStore { // The secrets in pre-tags should be unique because we always store just the highest index per given secret-txHash // pair. Below we check that this is the case. - const secretsSet = new Set(preTags.map(preTag => preTag.secret.toString())); + const secretsSet = new Set(preTags.map(preTag => preTag.extendedSecret.toString())); if (secretsSet.size !== preTags.length) { return Promise.reject(new Error(`Duplicate secrets found when storing pending indexes`)); } @@ -163,10 +163,10 @@ export class SenderTaggingStore implements StagedStore { return this.#store.transactionAsync(async () => { // Prefetch all data, start reads during iteration to keep IndexedDB transaction alive - const preTagReadPromises = preTags.map(({ secret, index }) => { - const secretStr = secret.toString(); + const preTagReadPromises = preTags.map(({ extendedSecret, index }) => { + const secretStr = extendedSecret.toString(); return { - secret, + extendedSecret, secretStr, index, pending: this.#readPendingIndexes(jobId, secretStr), @@ -233,7 +233,7 @@ export class SenderTaggingStore implements StagedStore { * [startIndex, endIndex). Returns an empty array if no pending indexes exist in the range. */ getTxHashesOfPendingIndexes( - secret: DirectionalAppTaggingSecret, + secret: ExtendedDirectionalAppTaggingSecret, startIndex: number, endIndex: number, jobId: string, @@ -252,7 +252,7 @@ export class SenderTaggingStore implements StagedStore { * @param secret - The secret to get the last finalized index for. * @returns The last (highest) finalized index for the given secret. */ - getLastFinalizedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise { + getLastFinalizedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise { return this.#store.transactionAsync(() => this.#readLastFinalizedIndex(jobId, secret.toString())); } @@ -262,7 +262,7 @@ export class SenderTaggingStore implements StagedStore { * @param secret - The directional app tagging secret to query the last used index for. * @returns The last used index. */ - getLastUsedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise { + getLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise { const secretStr = secret.toString(); return this.#store.transactionAsync(async () => { diff --git a/yarn-project/pxe/src/tagging/index.ts b/yarn-project/pxe/src/tagging/index.ts index beeb055a2e17..ea8c6f80f613 100644 --- a/yarn-project/pxe/src/tagging/index.ts +++ b/yarn-project/pxe/src/tagging/index.ts @@ -15,5 +15,5 @@ export { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from './constants.js'; export { getAllPrivateLogsByTags, getAllPublicLogsByTagsFromContract } from './get_all_logs_by_tags.js'; // Re-export tagging-related types from stdlib -export { DirectionalAppTaggingSecret, Tag, SiloedTag } from '@aztec/stdlib/logs'; +export { ExtendedDirectionalAppTaggingSecret, Tag, SiloedTag } from '@aztec/stdlib/logs'; export { type PreTag } from '@aztec/stdlib/logs'; diff --git a/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.test.ts b/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.test.ts index 7a19c393ae72..a02ac7e42f1a 100644 --- a/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.test.ts +++ b/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.test.ts @@ -2,11 +2,15 @@ import { MAX_TX_LIFETIME } from '@aztec/constants'; import { BlockNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; -import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { BlockHash } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { DirectionalAppTaggingSecret, SiloedTag, Tag } from '@aztec/stdlib/logs'; -import { makeBlockHeader, makeL2Tips, randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; +import { type ExtendedDirectionalAppTaggingSecret, SiloedTag, Tag } from '@aztec/stdlib/logs'; +import { + makeBlockHeader, + makeL2Tips, + randomExtendedDirectionalAppTaggingSecret, + randomTxScopedPrivateL2Log, +} from '@aztec/stdlib/testing'; import { type MockProxy, mock } from 'jest-mock-extended'; @@ -20,8 +24,7 @@ const FAR_FUTURE_BLOCK_NUMBER = BlockNumber(100); const MOCK_ANCHOR_BLOCK_HASH = BlockHash.random(); describe('loadPrivateLogsForSenderRecipientPair', () => { - let secret: DirectionalAppTaggingSecret; - let app: AztecAddress; + let secret: ExtendedDirectionalAppTaggingSecret; let aztecNode: MockProxy; let taggingStore: RecipientTaggingStore; @@ -29,8 +32,8 @@ describe('loadPrivateLogsForSenderRecipientPair', () => { const currentTimestamp = BigInt(Math.floor(Date.now() / 1000)); async function computeSiloedTagForIndex(index: number) { - const tag = await Tag.compute({ secret, index }); - return SiloedTag.compute(tag, app); + const tag = await Tag.compute({ extendedSecret: secret, index }); + return SiloedTag.compute(tag, secret.app); } function makeLog(blockNumber: number, blockTimestamp: bigint, tag: Fr) { @@ -38,8 +41,7 @@ describe('loadPrivateLogsForSenderRecipientPair', () => { } beforeAll(async () => { - secret = DirectionalAppTaggingSecret.fromString(Fr.random().toString()); - app = await AztecAddress.random(); + secret = await randomExtendedDirectionalAppTaggingSecret(); aztecNode = mock(); }); @@ -62,7 +64,6 @@ describe('loadPrivateLogsForSenderRecipientPair', () => { const logs = await loadPrivateLogsForSenderRecipientPair( secret, - app, aztecNode, taggingStore, FAR_FUTURE_BLOCK_NUMBER, @@ -97,7 +98,6 @@ describe('loadPrivateLogsForSenderRecipientPair', () => { const logs = await loadPrivateLogsForSenderRecipientPair( secret, - app, aztecNode, taggingStore, FAR_FUTURE_BLOCK_NUMBER, @@ -132,7 +132,6 @@ describe('loadPrivateLogsForSenderRecipientPair', () => { const logs = await loadPrivateLogsForSenderRecipientPair( secret, - app, aztecNode, taggingStore, FAR_FUTURE_BLOCK_NUMBER, @@ -184,7 +183,6 @@ describe('loadPrivateLogsForSenderRecipientPair', () => { const logs = await loadPrivateLogsForSenderRecipientPair( secret, - app, aztecNode, taggingStore, FAR_FUTURE_BLOCK_NUMBER, diff --git a/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts b/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts index de527f8a7f61..8587860539bf 100644 --- a/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +++ b/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts @@ -1,8 +1,7 @@ import type { BlockNumber } from '@aztec/foundation/branded-types'; -import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { BlockHash } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/client'; -import type { DirectionalAppTaggingSecret, TxScopedL2Log } from '@aztec/stdlib/logs'; +import type { ExtendedDirectionalAppTaggingSecret, TxScopedL2Log } from '@aztec/stdlib/logs'; import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js'; import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../constants.js'; @@ -10,15 +9,14 @@ import { findHighestIndexes } from './utils/find_highest_indexes.js'; import { loadLogsForRange } from './utils/load_logs_for_range.js'; /** - * Loads private logs for `app` and sender-recipient pair defined by `secret` and updates the highest aged and + * Loads private logs for the app-sender-recipient triplet defined by `secret` and updates the highest aged and * finalized indexes in the db. At most load logs from blocks up to and including `anchorBlockNumber`. * * @dev This function can be safely executed "in parallel" for other sender-recipient pairs because the data in * in the tagging data provider is indexed by the secret and hence completely disjoint. */ export async function loadPrivateLogsForSenderRecipientPair( - secret: DirectionalAppTaggingSecret, - app: AztecAddress, + secret: ExtendedDirectionalAppTaggingSecret, aztecNode: AztecNode, taggingStore: RecipientTaggingStore, anchorBlockNumber: BlockNumber, @@ -96,7 +94,6 @@ export async function loadPrivateLogsForSenderRecipientPair( // Get private logs with their block timestamps and corresponding tagging indexes const privateLogsWithIndexes = await loadLogsForRange( secret, - app, aztecNode, start, end, diff --git a/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.test.ts b/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.test.ts index 24c278dd2e4d..4261fe83b86b 100644 --- a/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.test.ts +++ b/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.test.ts @@ -1,10 +1,8 @@ import { BlockNumber } from '@aztec/foundation/branded-types'; -import { Fr } from '@aztec/foundation/curves/bn254'; -import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { BlockHash } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { DirectionalAppTaggingSecret, SiloedTag, Tag } from '@aztec/stdlib/logs'; -import { randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; +import { type ExtendedDirectionalAppTaggingSecret, SiloedTag, Tag } from '@aztec/stdlib/logs'; +import { randomExtendedDirectionalAppTaggingSecret, randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; import { TxHash } from '@aztec/stdlib/tx'; import { type MockProxy, mock } from 'jest-mock-extended'; @@ -18,14 +16,13 @@ const MOCK_ANCHOR_BLOCK_HASH = BlockHash.random(); describe('loadLogsForRange', () => { // App contract address and secret to be used on the input of the loadLogsForRange function. - let secret: DirectionalAppTaggingSecret; - let app: AztecAddress; + let secret: ExtendedDirectionalAppTaggingSecret; let aztecNode: MockProxy; async function computeSiloedTagForIndex(index: number) { - const tag = await Tag.compute({ secret, index }); - return SiloedTag.compute(tag, app); + const tag = await Tag.compute({ extendedSecret: secret, index }); + return SiloedTag.compute(tag, secret.app); } function makeLog(txHash: TxHash, blockNumber: number, blockTimestamp: bigint, tag: SiloedTag) { @@ -33,8 +30,7 @@ describe('loadLogsForRange', () => { } beforeAll(async () => { - secret = DirectionalAppTaggingSecret.fromString(Fr.random().toString()); - app = await AztecAddress.random(); + secret = await randomExtendedDirectionalAppTaggingSecret(); aztecNode = mock(); }); @@ -49,7 +45,7 @@ describe('loadLogsForRange', () => { }); expect( - await loadLogsForRange(secret, app, aztecNode, 0, 10, FAR_FUTURE_BLOCK_NUMBER, MOCK_ANCHOR_BLOCK_HASH), + await loadLogsForRange(secret, aztecNode, 0, 10, FAR_FUTURE_BLOCK_NUMBER, MOCK_ANCHOR_BLOCK_HASH), ).toHaveLength(0); }); @@ -78,15 +74,7 @@ describe('loadLogsForRange', () => { ); }); - const result = await loadLogsForRange( - secret, - app, - aztecNode, - 0, - 10, - FAR_FUTURE_BLOCK_NUMBER, - MOCK_ANCHOR_BLOCK_HASH, - ); + const result = await loadLogsForRange(secret, aztecNode, 0, 10, FAR_FUTURE_BLOCK_NUMBER, MOCK_ANCHOR_BLOCK_HASH); expect(result).toHaveLength(2); const resultByIndex = result.sort((a, b) => a.taggingIndex - b.taggingIndex); @@ -118,15 +106,7 @@ describe('loadLogsForRange', () => { ); }); - const result = await loadLogsForRange( - secret, - app, - aztecNode, - 0, - 10, - FAR_FUTURE_BLOCK_NUMBER, - MOCK_ANCHOR_BLOCK_HASH, - ); + const result = await loadLogsForRange(secret, aztecNode, 0, 10, FAR_FUTURE_BLOCK_NUMBER, MOCK_ANCHOR_BLOCK_HASH); expect(result).toHaveLength(2); expect(result[0].taggingIndex).toBe(index); @@ -159,15 +139,7 @@ describe('loadLogsForRange', () => { ); }); - const result = await loadLogsForRange( - secret, - app, - aztecNode, - 0, - 10, - FAR_FUTURE_BLOCK_NUMBER, - MOCK_ANCHOR_BLOCK_HASH, - ); + const result = await loadLogsForRange(secret, aztecNode, 0, 10, FAR_FUTURE_BLOCK_NUMBER, MOCK_ANCHOR_BLOCK_HASH); expect(result).toHaveLength(2); @@ -203,7 +175,6 @@ describe('loadLogsForRange', () => { const result = await loadLogsForRange( secret, - app, aztecNode, start, end, @@ -240,7 +211,6 @@ describe('loadLogsForRange', () => { const result = await loadLogsForRange( secret, - app, aztecNode, 0, 10, diff --git a/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.ts b/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.ts index d9e8ce3eb2ee..90c5bd38d88e 100644 --- a/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.ts +++ b/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.ts @@ -1,20 +1,18 @@ import type { BlockNumber } from '@aztec/foundation/branded-types'; -import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { BlockHash } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/client'; -import type { DirectionalAppTaggingSecret, PreTag, TxScopedL2Log } from '@aztec/stdlib/logs'; +import type { ExtendedDirectionalAppTaggingSecret, PreTag, TxScopedL2Log } from '@aztec/stdlib/logs'; import { SiloedTag, Tag } from '@aztec/stdlib/logs'; import { getAllPrivateLogsByTags } from '../../get_all_logs_by_tags.js'; /** - * Gets private logs with their corresponding block timestamps and tagging indexes for the given index range, `app` and - * `secret`. At most load logs from blocks up to and including `anchorBlockNumber`. `start` is inclusive and `end` is - * exclusive. + * Gets private logs with their corresponding block timestamps and tagging indexes for the given index range and + * `extendedSecret`. At most load logs from blocks up to and including `anchorBlockNumber`. `start` is inclusive and + * `end` is exclusive. */ export async function loadLogsForRange( - secret: DirectionalAppTaggingSecret, - app: AztecAddress, + extendedSecret: ExtendedDirectionalAppTaggingSecret, aztecNode: AztecNode, start: number, end: number, @@ -24,9 +22,9 @@ export async function loadLogsForRange( // Derive tags for the window const preTags: PreTag[] = Array(end - start) .fill(0) - .map((_, i) => ({ secret, index: start + i })); + .map((_, i) => ({ extendedSecret, index: start + i })); const siloedTags = await Promise.all(preTags.map(preTag => Tag.compute(preTag))).then(tags => - Promise.all(tags.map(tag => SiloedTag.compute(tag, app))), + Promise.all(tags.map(tag => SiloedTag.compute(tag, extendedSecret.app))), ); // We use the utility function below to retrieve all logs for the tags across all pages, so we don't need to handle diff --git a/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts b/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts index ba4cb0466a0f..8ee9406c1456 100644 --- a/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts +++ b/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.test.ts @@ -1,31 +1,34 @@ import { BlockNumber } from '@aztec/foundation/branded-types'; import { Fr } from '@aztec/foundation/curves/bn254'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; -import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { BlockHash } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/client'; -import { randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; +import { randomExtendedDirectionalAppTaggingSecret, randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; import { TxExecutionResult, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx'; import { type MockProxy, mock } from 'jest-mock-extended'; import { SenderTaggingStore } from '../../storage/tagging_store/sender_tagging_store.js'; -import { DirectionalAppTaggingSecret, SiloedTag, Tag, UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../index.js'; +import { + type ExtendedDirectionalAppTaggingSecret, + SiloedTag, + Tag, + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN, +} from '../index.js'; import { syncSenderTaggingIndexes } from './sync_sender_tagging_indexes.js'; const MOCK_ANCHOR_BLOCK_HASH = BlockHash.random(); describe('syncSenderTaggingIndexes', () => { - // Contract address and secret to be used on the input of the syncSenderTaggingIndexes function. - let secret: DirectionalAppTaggingSecret; - let contractAddress: AztecAddress; + // The secret to be used on the input of the syncSenderTaggingIndexes function. + let secret: ExtendedDirectionalAppTaggingSecret; let aztecNode: MockProxy; let taggingStore: SenderTaggingStore; async function computeSiloedTagForIndex(index: number) { - const tag = await Tag.compute({ secret, index }); - return SiloedTag.compute(tag, contractAddress); + const tag = await Tag.compute({ extendedSecret: secret, index }); + return SiloedTag.compute(tag, secret.app); } function makeLog(txHash: TxHash, tag: Fr) { @@ -33,8 +36,7 @@ describe('syncSenderTaggingIndexes', () => { } async function setUp() { - secret = DirectionalAppTaggingSecret.fromString(Fr.random().toString()); - contractAddress = await AztecAddress.random(); + secret = await randomExtendedDirectionalAppTaggingSecret(); aztecNode = mock(); taggingStore = new SenderTaggingStore(await openTmpStore('test')); @@ -48,7 +50,7 @@ describe('syncSenderTaggingIndexes', () => { return Promise.resolve(tags.map((_tag: SiloedTag) => [])); }); - await syncSenderTaggingIndexes(secret, contractAddress, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await syncSenderTaggingIndexes(secret, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Highest used and finalized indexes should stay undefined expect(await taggingStore.getLastUsedIndex(secret, 'test')).toBeUndefined(); @@ -91,7 +93,7 @@ describe('syncSenderTaggingIndexes', () => { ), ); - await syncSenderTaggingIndexes(secret, contractAddress, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await syncSenderTaggingIndexes(secret, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify the highest finalized index is updated to 3 expect(await taggingStore.getLastFinalizedIndex(secret, 'test')).toBe(finalizedIndexStep1); @@ -123,7 +125,7 @@ describe('syncSenderTaggingIndexes', () => { ), ); - await syncSenderTaggingIndexes(secret, contractAddress, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await syncSenderTaggingIndexes(secret, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify the highest finalized index was not updated expect(await taggingStore.getLastFinalizedIndex(secret, 'test')).toBe(finalizedIndexStep1); @@ -206,7 +208,7 @@ describe('syncSenderTaggingIndexes', () => { } }); - await syncSenderTaggingIndexes(secret, contractAddress, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await syncSenderTaggingIndexes(secret, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); expect(await taggingStore.getLastFinalizedIndex(secret, 'test')).toBe(newHighestFinalizedIndex); expect(await taggingStore.getLastUsedIndex(secret, 'test')).toBe(newHighestUsedIndex); @@ -269,7 +271,7 @@ describe('syncSenderTaggingIndexes', () => { }); // Sync tagged logs - await syncSenderTaggingIndexes(secret, contractAddress, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await syncSenderTaggingIndexes(secret, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify that both highest finalized and highest used were set to the pending and finalized index expect(await taggingStore.getLastFinalizedIndex(secret, 'test')).toBe(pendingAndFinalizedIndex); diff --git a/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.ts b/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.ts index 0270ead82a35..87d56d6a46e7 100644 --- a/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +++ b/yarn-project/pxe/src/tagging/sender_sync/sync_sender_tagging_indexes.ts @@ -1,7 +1,6 @@ -import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { BlockHash } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import type { DirectionalAppTaggingSecret } from '@aztec/stdlib/logs'; +import type { ExtendedDirectionalAppTaggingSecret } from '@aztec/stdlib/logs'; import type { SenderTaggingStore } from '../../storage/tagging_store/sender_tagging_store.js'; import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../constants.js'; @@ -11,11 +10,8 @@ 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, contract) tuple while the direction of + * @param secret - The secret that's unique for (sender, recipient, app) tuple while the direction of * sender -> recipient matters. - * @param app - The address of the contract that the logs are tagged for. Needs to be provided because we perform - * second round of siloing in this function which is necessary because kernels do it as well (they silo first field - * of the private log which corresponds to the tag). * @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). @@ -23,8 +19,7 @@ import { loadAndStoreNewTaggingIndexes } from './utils/load_and_store_new_taggin * updates its status accordingly. */ export async function syncSenderTaggingIndexes( - secret: DirectionalAppTaggingSecret, - app: AztecAddress, + secret: ExtendedDirectionalAppTaggingSecret, aztecNode: AztecNode, taggingStore: SenderTaggingStore, anchorBlockHash: BlockHash, @@ -59,7 +54,7 @@ export async function syncSenderTaggingIndexes( while (true) { // Load and store indexes for the current window. These indexes may already exist in the database if txs using // them were previously sent from this PXE. Any duplicates are handled by the tagging data provider. - await loadAndStoreNewTaggingIndexes(secret, app, start, end, aztecNode, taggingStore, anchorBlockHash, jobId); + await loadAndStoreNewTaggingIndexes(secret, start, end, aztecNode, taggingStore, anchorBlockHash, jobId); // Retrieve all indexes within the current window from storage and update their status accordingly. const pendingTxHashes = await taggingStore.getTxHashesOfPendingIndexes(secret, start, end, jobId); diff --git a/yarn-project/pxe/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.test.ts b/yarn-project/pxe/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.test.ts index 6ee625261b16..5814d3039469 100644 --- a/yarn-project/pxe/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.test.ts +++ b/yarn-project/pxe/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.test.ts @@ -1,10 +1,9 @@ -import { Fr } from '@aztec/foundation/curves/bn254'; +import type { Fr } from '@aztec/foundation/curves/bn254'; import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; -import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { BlockHash } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { DirectionalAppTaggingSecret, SiloedTag, Tag } from '@aztec/stdlib/logs'; -import { randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; +import { type ExtendedDirectionalAppTaggingSecret, SiloedTag, Tag } from '@aztec/stdlib/logs'; +import { randomExtendedDirectionalAppTaggingSecret, randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; import { TxHash } from '@aztec/stdlib/tx'; import { type MockProxy, mock } from 'jest-mock-extended'; @@ -15,16 +14,15 @@ import { loadAndStoreNewTaggingIndexes } from './load_and_store_new_tagging_inde const MOCK_ANCHOR_BLOCK_HASH = BlockHash.random(); describe('loadAndStoreNewTaggingIndexes', () => { - // App contract address and secret to be used on the input of the loadAndStoreNewTaggingIndexes function. - let secret: DirectionalAppTaggingSecret; - let app: AztecAddress; + // Secret to be used on the input of the loadAndStoreNewTaggingIndexes function. + let secret: ExtendedDirectionalAppTaggingSecret; let aztecNode: MockProxy; let taggingStore: SenderTaggingStore; async function computeSiloedTagForIndex(index: number) { - const tag = await Tag.compute({ secret, index }); - return SiloedTag.compute(tag, app); + const tag = await Tag.compute({ extendedSecret: secret, index }); + return SiloedTag.compute(tag, secret.app); } function makeLog(txHash: TxHash, tag: Fr) { @@ -32,8 +30,7 @@ describe('loadAndStoreNewTaggingIndexes', () => { } beforeAll(async () => { - secret = DirectionalAppTaggingSecret.fromString(Fr.random().toString()); - app = await AztecAddress.random(); + secret = await randomExtendedDirectionalAppTaggingSecret(); aztecNode = mock(); }); @@ -49,7 +46,7 @@ describe('loadAndStoreNewTaggingIndexes', () => { return Promise.resolve(tags.map((_tag: SiloedTag) => [])); }); - await loadAndStoreNewTaggingIndexes(secret, app, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await loadAndStoreNewTaggingIndexes(secret, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify that no pending indexes were stored expect(await taggingStore.getLastUsedIndex(secret, 'test')).toBeUndefined(); @@ -69,7 +66,7 @@ describe('loadAndStoreNewTaggingIndexes', () => { return Promise.resolve(tags.map((t: SiloedTag) => (t.equals(tag) ? [makeLog(txHash, tag.value)] : []))); }); - await loadAndStoreNewTaggingIndexes(secret, app, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await loadAndStoreNewTaggingIndexes(secret, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify that the pending index was stored for this txHash const txHashesInRange = await taggingStore.getTxHashesOfPendingIndexes(secret, index, index + 1, 'test'); @@ -100,7 +97,7 @@ describe('loadAndStoreNewTaggingIndexes', () => { ); }); - await loadAndStoreNewTaggingIndexes(secret, app, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await loadAndStoreNewTaggingIndexes(secret, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify that only the highest index (7) was stored for this txHash and secret const txHashesAtIndex2 = await taggingStore.getTxHashesOfPendingIndexes(secret, index2, index2 + 1, 'test'); @@ -136,7 +133,7 @@ describe('loadAndStoreNewTaggingIndexes', () => { ); }); - await loadAndStoreNewTaggingIndexes(secret, app, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await loadAndStoreNewTaggingIndexes(secret, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify that both txHashes have their respective indexes stored const txHashesAtIndex1 = await taggingStore.getTxHashesOfPendingIndexes(secret, index1, index1 + 1, 'test'); @@ -164,7 +161,7 @@ describe('loadAndStoreNewTaggingIndexes', () => { ); }); - await loadAndStoreNewTaggingIndexes(secret, app, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await loadAndStoreNewTaggingIndexes(secret, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify that both txHashes have the same index stored const txHashesAtIndex = await taggingStore.getTxHashesOfPendingIndexes(secret, index, index + 1, 'test'); @@ -210,7 +207,7 @@ describe('loadAndStoreNewTaggingIndexes', () => { ); }); - await loadAndStoreNewTaggingIndexes(secret, app, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); + await loadAndStoreNewTaggingIndexes(secret, 0, 10, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify txHash1 has highest index 8 (should not be at index 1) const txHashesAtIndex1 = await taggingStore.getTxHashesOfPendingIndexes(secret, 1, 2, 'test'); @@ -258,16 +255,7 @@ describe('loadAndStoreNewTaggingIndexes', () => { ); }); - await loadAndStoreNewTaggingIndexes( - secret, - app, - start, - end, - aztecNode, - taggingStore, - MOCK_ANCHOR_BLOCK_HASH, - 'test', - ); + await loadAndStoreNewTaggingIndexes(secret, start, end, aztecNode, taggingStore, MOCK_ANCHOR_BLOCK_HASH, 'test'); // Verify that the log at start (inclusive) was processed const txHashesAtStart = await taggingStore.getTxHashesOfPendingIndexes(secret, start, start + 1, 'test'); diff --git a/yarn-project/pxe/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts b/yarn-project/pxe/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts index 4fa1939d4fe8..68008ab814a1 100644 --- a/yarn-project/pxe/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +++ b/yarn-project/pxe/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts @@ -1,7 +1,6 @@ -import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { BlockHash } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import type { DirectionalAppTaggingSecret, PreTag } from '@aztec/stdlib/logs'; +import type { ExtendedDirectionalAppTaggingSecret, PreTag } from '@aztec/stdlib/logs'; import { SiloedTag, Tag } from '@aztec/stdlib/logs'; import { TxHash } from '@aztec/stdlib/tx'; @@ -12,9 +11,7 @@ import { getAllPrivateLogsByTags } from '../../get_all_logs_by_tags.js'; * Loads tagging indexes from the Aztec node and stores them in the tagging data provider. * @remarks This function is one of two places by which a pending index can get to the tagging data provider. The other * place is when a tx is being sent from this PXE. - * @param secret - The directional app tagging secret that's unique for (sender, recipient, contract) tuple. - * @param app - The address of the contract that the logs are tagged for. Used for siloing tags to match - * kernel circuit behavior. + * @param extendedSecret - The extended directional app tagging secret that's unique for (sender, recipient, app) tuple. * @param start - The starting index (inclusive) of the window to process. * @param end - The ending index (exclusive) of the window to process. * @param aztecNode - The Aztec node instance to query for logs. @@ -23,8 +20,7 @@ import { getAllPrivateLogsByTags } from '../../get_all_logs_by_tags.js'; * preserving way. */ export async function loadAndStoreNewTaggingIndexes( - secret: DirectionalAppTaggingSecret, - app: AztecAddress, + extendedSecret: ExtendedDirectionalAppTaggingSecret, start: number, end: number, aztecNode: AztecNode, @@ -35,9 +31,9 @@ export async function loadAndStoreNewTaggingIndexes( // We compute the tags for the current window of indexes const preTagsForWindow: PreTag[] = Array(end - start) .fill(0) - .map((_, i) => ({ secret, index: start + i })); + .map((_, i) => ({ extendedSecret, index: start + i })); const siloedTagsForWindow = await Promise.all( - preTagsForWindow.map(async preTag => SiloedTag.compute(await Tag.compute(preTag), app)), + preTagsForWindow.map(async preTag => SiloedTag.compute(await Tag.compute(preTag), extendedSecret.app)), ); const txsForTags = await getTxsContainingTags(siloedTagsForWindow, aztecNode, anchorBlockHash); @@ -46,7 +42,7 @@ export async function loadAndStoreNewTaggingIndexes( // Now we iterate over the map, reconstruct the preTags and tx hash and store them in the db. for (const [txHashStr, highestIndex] of highestIndexMap.entries()) { const txHash = TxHash.fromString(txHashStr); - await taggingStore.storePendingIndexes([{ secret, index: highestIndex }], txHash, jobId); + await taggingStore.storePendingIndexes([{ extendedSecret, index: highestIndex }], txHash, jobId); } } diff --git a/yarn-project/stdlib/src/logs/extended_directional_app_tagging_secret.test.ts b/yarn-project/stdlib/src/logs/extended_directional_app_tagging_secret.test.ts new file mode 100644 index 000000000000..59b38d10eb77 --- /dev/null +++ b/yarn-project/stdlib/src/logs/extended_directional_app_tagging_secret.test.ts @@ -0,0 +1,13 @@ +import { randomExtendedDirectionalAppTaggingSecret } from '../tests/factories.js'; +import { ExtendedDirectionalAppTaggingSecret } from './extended_directional_app_tagging_secret.js'; + +describe('ExtendedDirectionalAppTaggingSecret', () => { + it('toString and fromString works', async () => { + const secret = await randomExtendedDirectionalAppTaggingSecret(); + const str = secret.toString(); + const parsed = ExtendedDirectionalAppTaggingSecret.fromString(str); + + expect(parsed.secret).toEqual(secret.secret); + expect(parsed.app).toEqual(secret.app); + }); +}); diff --git a/yarn-project/stdlib/src/logs/directional_app_tagging_secret.ts b/yarn-project/stdlib/src/logs/extended_directional_app_tagging_secret.ts similarity index 67% rename from yarn-project/stdlib/src/logs/directional_app_tagging_secret.ts rename to yarn-project/stdlib/src/logs/extended_directional_app_tagging_secret.ts index 410eaf6f2be1..0a083ed053bc 100644 --- a/yarn-project/stdlib/src/logs/directional_app_tagging_secret.ts +++ b/yarn-project/stdlib/src/logs/extended_directional_app_tagging_secret.ts @@ -5,22 +5,28 @@ import type { Point } from '@aztec/foundation/curves/grumpkin'; import { z } from 'zod'; -import type { AztecAddress } from '../aztec-address/index.js'; +import { AztecAddress } from '../aztec-address/index.js'; import type { CompleteAddress } from '../contract/complete_address.js'; import { computeAddressSecret, computePreaddress } from '../keys/derivation.js'; /** - * Directional application tagging secret used for log tagging. + * Extended directional application tagging secret used for log tagging. * - * "Directional" because the derived secret is bound to the recipient - * address: A→B differs from B→A even with the same participants and app. + * "Extended" because it bundles the directional app tagging secret with the app (contract) address. This bundling was + * done because where this type is used we commonly need access to both the secret and the address. * - * Note: It's a bit unfortunate that this type resides in `stdlib` as the rest of the tagging functionality resides - * in `pxe/src/tagging`. We need to use this type in `PreTag` that in turn is used by other types - * in stdlib hence there doesn't seem to be a good way around this. + * "Directional" because the derived secret is bound to the recipient address: A→B differs from B→A even with the same + * participants and app. + * + * Note: It's a bit unfortunate that this type resides in `stdlib` as the rest of the tagging functionality resides in + * `pxe/src/tagging`. We need to use this type in `PreTag` that in turn is used by other types in stdlib hence there + * doesn't seem to be a good way around this. */ -export class DirectionalAppTaggingSecret { - private constructor(public readonly value: Fr) {} +export class ExtendedDirectionalAppTaggingSecret { + private constructor( + public readonly secret: Fr, + public readonly app: AztecAddress, + ) {} /** * Derives shared tagging secret and from that, the app address and recipient derives the directional app tagging @@ -39,20 +45,21 @@ export class DirectionalAppTaggingSecret { externalAddress: AztecAddress, app: AztecAddress, recipient: AztecAddress, - ): Promise { + ): Promise { const taggingSecretPoint = await computeSharedTaggingSecret(localAddress, localIvsk, externalAddress); const appTaggingSecret = await poseidon2Hash([taggingSecretPoint.x, taggingSecretPoint.y, app]); const directionalAppTaggingSecret = await poseidon2Hash([appTaggingSecret, recipient]); - return new DirectionalAppTaggingSecret(directionalAppTaggingSecret); + return new ExtendedDirectionalAppTaggingSecret(directionalAppTaggingSecret, app); } toString(): string { - return this.value.toString(); + return `${this.secret.toString()}:${this.app.toString()}`; } - static fromString(str: string): DirectionalAppTaggingSecret { - return new DirectionalAppTaggingSecret(Fr.fromString(str)); + static fromString(str: string): ExtendedDirectionalAppTaggingSecret { + const [secretStr, appStr] = str.split(':'); + return new ExtendedDirectionalAppTaggingSecret(Fr.fromString(secretStr), AztecAddress.fromString(appStr)); } } @@ -74,6 +81,7 @@ async function computeSharedTaggingSecret( return Grumpkin.mul(externalAddressPoint, await computeAddressSecret(knownPreaddress, localIvsk)); } -export const DirectionalAppTaggingSecretSchema = z.object({ - value: Fr.schema, +export const ExtendedDirectionalAppTaggingSecretSchema = z.object({ + secret: Fr.schema, + app: AztecAddress.schema, }); diff --git a/yarn-project/stdlib/src/logs/index.ts b/yarn-project/stdlib/src/logs/index.ts index aba30077041d..2e25c40da7c3 100644 --- a/yarn-project/stdlib/src/logs/index.ts +++ b/yarn-project/stdlib/src/logs/index.ts @@ -1,4 +1,4 @@ -export * from './directional_app_tagging_secret.js'; +export * from './extended_directional_app_tagging_secret.js'; export * from './pre_tag.js'; export * from './contract_class_log.js'; export * from './public_log.js'; diff --git a/yarn-project/stdlib/src/logs/pre_tag.ts b/yarn-project/stdlib/src/logs/pre_tag.ts index 0110412cbd15..40f13b6f501b 100644 --- a/yarn-project/stdlib/src/logs/pre_tag.ts +++ b/yarn-project/stdlib/src/logs/pre_tag.ts @@ -3,9 +3,9 @@ import { schemas } from '@aztec/foundation/schemas'; import { z } from 'zod'; import { - type DirectionalAppTaggingSecret, - DirectionalAppTaggingSecretSchema, -} from './directional_app_tagging_secret.js'; + type ExtendedDirectionalAppTaggingSecret, + ExtendedDirectionalAppTaggingSecretSchema, +} from './extended_directional_app_tagging_secret.js'; /** * Represents a preimage of a private log tag (see `Tag` in `pxe/src/tagging`). @@ -15,11 +15,11 @@ import { * around this. */ export type PreTag = { - secret: DirectionalAppTaggingSecret; + extendedSecret: ExtendedDirectionalAppTaggingSecret; index: number; }; export const PreTagSchema = z.object({ - secret: DirectionalAppTaggingSecretSchema, + extendedSecret: ExtendedDirectionalAppTaggingSecretSchema, index: schemas.Integer, }); diff --git a/yarn-project/stdlib/src/logs/tag.ts b/yarn-project/stdlib/src/logs/tag.ts index ff7e120bc5b2..c16771da9f8c 100644 --- a/yarn-project/stdlib/src/logs/tag.ts +++ b/yarn-project/stdlib/src/logs/tag.ts @@ -20,7 +20,7 @@ export class Tag { constructor(public readonly value: Fr) {} static async compute(preTag: PreTag): Promise { - const tag = await poseidon2Hash([preTag.secret.value, preTag.index]); + const tag = await poseidon2Hash([preTag.extendedSecret.secret, preTag.index]); return new Tag(tag); } diff --git a/yarn-project/stdlib/src/tests/factories.ts b/yarn-project/stdlib/src/tests/factories.ts index e2d22f969b2c..c33aaa591bd4 100644 --- a/yarn-project/stdlib/src/tests/factories.ts +++ b/yarn-project/stdlib/src/tests/factories.ts @@ -128,6 +128,7 @@ import { PublicCallRequestArrayLengths, } from '../kernel/public_call_request.js'; import { PublicKeys, computeAddress } from '../keys/index.js'; +import { ExtendedDirectionalAppTaggingSecret } from '../logs/extended_directional_app_tagging_secret.js'; import { ContractClassLog, ContractClassLogFields } from '../logs/index.js'; import { PrivateLog } from '../logs/private_log.js'; import { FlatPublicLogs, PublicLog } from '../logs/public_log.js'; @@ -1757,3 +1758,11 @@ export function makeL2Tips( }, }; } + +export async function randomExtendedDirectionalAppTaggingSecret(): Promise { + const resolvedApp = await AztecAddress.random(); + // Using the fromString method like this is messy as it leaks the underlying serialization format but I don't want to + // expose the type's constructor just for tests since in prod the secret is always constructed via compute. Also this + // method is tested in extended_directional_app_tagging_secret.test.ts hence all should be fine. + return ExtendedDirectionalAppTaggingSecret.fromString(`${Fr.random().toString()}:${resolvedApp.toString()}`); +}