Skip to content

Commit c76e1fc

Browse files
author
AztecBot
committed
Merge branch 'next' into merge-train/barretenberg
2 parents f42f032 + 2d79115 commit c76e1fc

10 files changed

Lines changed: 157 additions & 127 deletions

File tree

yarn-project/pxe/src/contract_function_simulator/execution_data_provider.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,12 @@ export interface ExecutionDataProvider {
239239
syncTaggedLogsAsSender(secret: DirectionalAppTaggingSecret, contractAddress: AztecAddress): Promise<void>;
240240

241241
/**
242-
* Returns the next index to be used to compute a tag when sending a log.
242+
* Returns the last used index when sending a log with a given secret.
243243
* @param secret - The directional app tagging secret.
244-
* @returns The next index to be used to compute a tag for the given directional app tagging secret.
244+
* @returns The last used index for the given directional app tagging secret, or undefined if we never sent a log
245+
* from this sender to a recipient in a given contract (implicitly included in the secret).
245246
*/
246-
getNextIndexAsSender(secret: DirectionalAppTaggingSecret): Promise<number>;
247+
getLastUsedIndexAsSender(secret: DirectionalAppTaggingSecret): Promise<number | undefined>;
247248

248249
/**
249250
* Synchronizes the private logs tagged with scoped addresses and all the senders in the address book. Stores the found

yarn-project/pxe/src/contract_function_simulator/execution_tagging_index_cache.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,22 @@ import { DirectionalAppTaggingSecret, type IndexedTaggingSecret } from '@aztec/s
88
export class ExecutionTaggingIndexCache {
99
private taggingIndexMap: Map<string, number> = new Map();
1010

11-
public getTaggingIndex(secret: DirectionalAppTaggingSecret): number | undefined {
11+
public getLastUsedIndex(secret: DirectionalAppTaggingSecret): number | undefined {
1212
return this.taggingIndexMap.get(secret.toString());
1313
}
1414

15-
public setTaggingIndex(secret: DirectionalAppTaggingSecret, index: number) {
15+
public setLastUsedIndex(secret: DirectionalAppTaggingSecret, index: number) {
1616
const currentValue = this.taggingIndexMap.get(secret.toString());
1717
if (currentValue !== undefined && currentValue !== index - 1) {
1818
throw new Error(`Invalid tagging index update. Current value: ${currentValue}, new value: ${index}`);
1919
}
2020
this.taggingIndexMap.set(secret.toString(), index);
2121
}
2222

23-
public getIndexedTaggingSecrets(): IndexedTaggingSecret[] {
23+
/**
24+
* Returns the indexed tagging secrets that were used in this execution.
25+
*/
26+
public getUsedIndexedTaggingSecrets(): IndexedTaggingSecret[] {
2427
return Array.from(this.taggingIndexMap.entries()).map(([secret, index]) => ({
2528
secret: DirectionalAppTaggingSecret.fromString(secret),
2629
index,

yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,8 @@ describe('Private Execution test suite', () => {
304304
throw new Error(`Unknown address: ${address}. Recipient: ${recipient}, Owner: ${owner}`);
305305
});
306306

307-
executionDataProvider.getNextIndexAsSender.mockImplementation((_secret: DirectionalAppTaggingSecret) => {
308-
return Promise.resolve(0);
307+
executionDataProvider.getLastUsedIndexAsSender.mockImplementation((_secret: DirectionalAppTaggingSecret) => {
308+
return Promise.resolve(undefined);
309309
});
310310
executionDataProvider.getFunctionArtifact.mockImplementation(async (address, selector) => {
311311
const contract = contracts[address.toString()];

yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export async function executePrivateFunction(
8888
const newNotes = privateExecutionOracle.getNewNotes();
8989
const noteHashNullifierCounterMap = privateExecutionOracle.getNoteHashNullifierCounterMap();
9090
const offchainEffects = privateExecutionOracle.getOffchainEffects();
91-
const indexedTaggingSecrets = privateExecutionOracle.getIndexedTaggingSecrets();
91+
const indexedTaggingSecrets = privateExecutionOracle.getUsedIndexedTaggingSecrets();
9292
const nestedExecutionResults = privateExecutionOracle.getNestedExecutionResults();
9393

9494
let timerSubtractionList = nestedExecutionResults;

yarn-project/pxe/src/contract_function_simulator/oracle/private_execution_oracle.ts

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type { AuthWitness } from '@aztec/stdlib/auth-witness';
1414
import { AztecAddress } from '@aztec/stdlib/aztec-address';
1515
import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
1616
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
17-
import type { ContractClassLog, IndexedTaggingSecret } from '@aztec/stdlib/logs';
17+
import type { ContractClassLog, DirectionalAppTaggingSecret, IndexedTaggingSecret } from '@aztec/stdlib/logs';
1818
import { Note, type NoteStatus } from '@aztec/stdlib/note';
1919
import {
2020
type BlockHeader,
@@ -152,10 +152,10 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
152152
}
153153

154154
/**
155-
* Return the tagging indexes incremented by this execution along with the directional app tagging secrets.
155+
* Returns the indexed tagging secrets that were used in this execution.
156156
*/
157-
public getIndexedTaggingSecrets(): IndexedTaggingSecret[] {
158-
return this.taggingIndexCache.getIndexedTaggingSecrets();
157+
public getUsedIndexedTaggingSecrets(): IndexedTaggingSecret[] {
158+
return this.taggingIndexCache.getUsedIndexedTaggingSecrets();
159159
}
160160

161161
/**
@@ -208,34 +208,31 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
208208
recipient,
209209
);
210210

211+
const index = await this.#getIndexToUseForSecret(secret);
212+
this.log.debug(
213+
`Incrementing tagging index for sender: ${sender}, recipient: ${recipient}, contract: ${this.contractAddress} to ${index}`,
214+
);
215+
this.taggingIndexCache.setLastUsedIndex(secret, index);
216+
217+
return Tag.compute({ secret, index });
218+
}
219+
220+
async #getIndexToUseForSecret(secret: DirectionalAppTaggingSecret): Promise<number> {
211221
// If we have the tagging index in the cache, we use it. If not we obtain it from the execution data provider.
212-
// TODO(benesjan): Make this be `getLastUsedIndex` and refactor this function to look as proposed in this comment:
213-
// https://github.com/AztecProtocol/aztec-packages/pull/17445#discussion_r2400365845
214-
const maybeTaggingIndex = this.taggingIndexCache.getTaggingIndex(secret);
215-
let taggingIndex: number;
222+
const lastUsedIndexInTx = this.taggingIndexCache.getLastUsedIndex(secret);
216223

217-
if (maybeTaggingIndex !== undefined) {
218-
taggingIndex = maybeTaggingIndex;
224+
if (lastUsedIndexInTx !== undefined) {
225+
return lastUsedIndexInTx + 1;
219226
} else {
220227
// This is a tagging secret we've not yet used in this tx, so first sync our store to make sure its indices
221228
// are up to date. We do this here because this store is not synced as part of the global sync because
222229
// that'd be wasteful as most tagging secrets are not used in each tx.
223-
this.log.debug(`Syncing tagged logs as sender ${sender} for contract ${this.contractAddress}`, {
224-
directionalAppTaggingSecret: secret,
225-
recipient,
226-
});
227230
await this.executionDataProvider.syncTaggedLogsAsSender(secret, this.contractAddress);
228-
taggingIndex = await this.executionDataProvider.getNextIndexAsSender(secret);
231+
const lastUsedIndex = await this.executionDataProvider.getLastUsedIndexAsSender(secret);
232+
// If lastUsedIndex is undefined, we've never used this secret, so start from 0
233+
// Otherwise, the next index to use is one past the last used index
234+
return lastUsedIndex === undefined ? 0 : lastUsedIndex + 1;
229235
}
230-
231-
// Now we increment the index by 1 and store it in the cache.
232-
const nextTaggingIndex = taggingIndex + 1;
233-
this.log.debug(
234-
`Incrementing tagging index for sender: ${sender}, recipient: ${recipient}, contract: ${this.contractAddress} to ${nextTaggingIndex}`,
235-
);
236-
this.taggingIndexCache.setTaggingIndex(secret, nextTaggingIndex);
237-
238-
return Tag.compute({ secret, index: taggingIndex });
239236
}
240237

241238
/**

yarn-project/pxe/src/contract_function_simulator/pxe_oracle_interface.test.ts

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,13 @@ describe('PXEOracleInterface', () => {
206206
),
207207
);
208208

209-
// First sender should have 2 logs, but keep index 1 since they were built using the same tag
210-
// Next 4 senders should also have index 1 = offset + 1
211-
// Last 5 senders should have index 2 = offset + 2
212-
const indexes = await taggingDataProvider.getNextIndexesAsRecipient(secrets);
209+
// First sender should have 2 logs, but keep index 0 since they were built using the same tag
210+
// Next 4 senders should also have index 0 = offset + 0
211+
// Last 5 senders should have index 1 = offset + 1
212+
const indexes = await taggingDataProvider.getLastUsedIndexesAsRecipient(secrets);
213213

214214
expect(indexes).toHaveLength(NUM_SENDERS);
215-
expect(indexes).toEqual([1, 1, 1, 1, 1, 2, 2, 2, 2, 2]);
215+
expect(indexes).toEqual([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]);
216216

217217
// We should have called the node 2 times:
218218
// 2 times: first time during initial request, second time after pushing the edge of the window once
@@ -244,10 +244,21 @@ describe('PXEOracleInterface', () => {
244244
);
245245

246246
const getTaggingSecretsIndexesAsSenderForSenders = () =>
247-
Promise.all(secrets.map(secret => taggingDataProvider.getNextIndexAsSender(secret)));
247+
Promise.all(secrets.map(secret => taggingDataProvider.getLastUsedIndexesAsSender(secret)));
248248

249249
const indexesAsSender = await getTaggingSecretsIndexesAsSenderForSenders();
250-
expect(indexesAsSender).toStrictEqual([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
250+
expect(indexesAsSender).toStrictEqual([
251+
undefined,
252+
undefined,
253+
undefined,
254+
undefined,
255+
undefined,
256+
undefined,
257+
undefined,
258+
undefined,
259+
undefined,
260+
undefined,
261+
]);
251262

252263
expect(aztecNode.getLogsByTags.mock.calls.length).toBe(0);
253264

@@ -263,7 +274,7 @@ describe('PXEOracleInterface', () => {
263274
}
264275

265276
let indexesAsSenderAfterSync = await getTaggingSecretsIndexesAsSenderForSenders();
266-
expect(indexesAsSenderAfterSync).toStrictEqual([1, 1, 1, 1, 1, 2, 2, 2, 2, 2]);
277+
expect(indexesAsSenderAfterSync).toStrictEqual([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]);
267278

268279
// Only 1 window is obtained for each sender
269280
expect(aztecNode.getLogsByTags.mock.calls.length).toBe(NUM_SENDERS);
@@ -285,7 +296,7 @@ describe('PXEOracleInterface', () => {
285296
}
286297

287298
indexesAsSenderAfterSync = await getTaggingSecretsIndexesAsSenderForSenders();
288-
expect(indexesAsSenderAfterSync).toStrictEqual([12, 12, 12, 12, 12, 13, 13, 13, 13, 13]);
299+
expect(indexesAsSenderAfterSync).toStrictEqual([10, 10, 10, 10, 10, 11, 11, 11, 11, 11]);
289300

290301
expect(aztecNode.getLogsByTags.mock.calls.length).toBe(NUM_SENDERS * 2);
291302
});
@@ -313,13 +324,13 @@ describe('PXEOracleInterface', () => {
313324
),
314325
);
315326

316-
// First sender should have 2 logs, but keep index 6 since they were built using the same tag
317-
// Next 4 senders should also have index 6 = offset + 1
318-
// Last 5 senders should have index 7 = offset + 2
319-
const indexes = await taggingDataProvider.getNextIndexesAsRecipient(secrets);
327+
// First sender should have 2 logs, but keep index 5 since they were built using the same tag
328+
// Next 4 senders should also have index 5 = offset
329+
// Last 5 senders should have index 6 = offset + 1
330+
const indexes = await taggingDataProvider.getLastUsedIndexesAsRecipient(secrets);
320331

321332
expect(indexes).toHaveLength(NUM_SENDERS);
322-
expect(indexes).toEqual([6, 6, 6, 6, 6, 7, 7, 7, 7, 7]);
333+
expect(indexes).toEqual([5, 5, 5, 5, 5, 6, 6, 6, 6, 6]);
323334

324335
// We should have called the node 2 times:
325336
// 2 times: first time during initial request, second time after pushing the edge of the window once
@@ -344,22 +355,22 @@ describe('PXEOracleInterface', () => {
344355
),
345356
);
346357

347-
// Increase our indexes to 2
348-
await taggingDataProvider.setNextIndexesAsRecipient(secrets.map(secret => ({ secret, index: 2 })));
358+
// Set last used indexes to 1 (so next scan starts at 2)
359+
await taggingDataProvider.setLastUsedIndexesAsRecipient(secrets.map(secret => ({ secret, index: 1 })));
349360

350361
await pxeOracleInterface.syncTaggedLogs(contractAddress, PENDING_TAGGED_LOG_ARRAY_BASE_SLOT);
351362

352363
// Even if our index as recipient is higher than what the sender sent, we should be able to find the logs
353364
// since the window starts at Math.max(0, 2 - window_size) = 0
354365
await expectPendingTaggedLogArrayLengthToBe(contractAddress, NUM_SENDERS + 1 + NUM_SENDERS / 2);
355366

356-
// First sender should have 2 logs, but keep index 2 since they were built using the same tag
357-
// Next 4 senders should also have index 2 = tagIndex + 1
358-
// Last 5 senders should have index 3 = tagIndex + 2
359-
const indexes = await taggingDataProvider.getNextIndexesAsRecipient(secrets);
367+
// First sender should have 2 logs, but keep index 1 since they were built using the same tag
368+
// Next 4 senders should also have index 1 = tagIndex
369+
// Last 5 senders should have index 2 = tagIndex + 1
370+
const indexes = await taggingDataProvider.getLastUsedIndexesAsRecipient(secrets);
360371

361372
expect(indexes).toHaveLength(NUM_SENDERS);
362-
expect(indexes).toEqual([2, 2, 2, 2, 2, 3, 3, 3, 3, 3]);
373+
expect(indexes).toEqual([1, 1, 1, 1, 1, 2, 2, 2, 2, 2]);
363374

364375
// We should have called the node 2 times:
365376
// first time during initial request, second time after pushing the edge of the window once
@@ -384,19 +395,19 @@ describe('PXEOracleInterface', () => {
384395
),
385396
);
386397

387-
// We set the indexes to WINDOW_HALF_SIZE + 1 so that it's outside the window and for this reason no updates
388-
// should be triggered.
398+
// We set the last used indexes to WINDOW_HALF_SIZE so that next scan starts at WINDOW_HALF_SIZE + 1,
399+
// which is outside the window, and for this reason no updates should be triggered.
389400
const index = WINDOW_HALF_SIZE + 1;
390-
await taggingDataProvider.setNextIndexesAsRecipient(secrets.map(secret => ({ secret, index })));
401+
await taggingDataProvider.setLastUsedIndexesAsRecipient(secrets.map(secret => ({ secret, index })));
391402

392403
await pxeOracleInterface.syncTaggedLogs(contractAddress, PENDING_TAGGED_LOG_ARRAY_BASE_SLOT);
393404

394405
// Only half of the logs should be synced since we start from index 1 = (11 - window_size), the other half should
395406
// be skipped
396407
await expectPendingTaggedLogArrayLengthToBe(contractAddress, NUM_SENDERS / 2);
397408

398-
// Indexes should remain where we set them (window_size + 1)
399-
const indexes = await taggingDataProvider.getNextIndexesAsRecipient(secrets);
409+
// Indexes should remain where we set them (window_size)
410+
const indexes = await taggingDataProvider.getLastUsedIndexesAsRecipient(secrets);
400411

401412
expect(indexes).toHaveLength(NUM_SENDERS);
402413
expect(indexes).toEqual([index, index, index, index, index, index, index, index, index, index]);
@@ -423,7 +434,7 @@ describe('PXEOracleInterface', () => {
423434
),
424435
);
425436

426-
await taggingDataProvider.setNextIndexesAsRecipient(
437+
await taggingDataProvider.setLastUsedIndexesAsRecipient(
427438
secrets.map(secret => ({ secret, index: WINDOW_HALF_SIZE + 2 })),
428439
);
429440

@@ -443,13 +454,13 @@ describe('PXEOracleInterface', () => {
443454

444455
await pxeOracleInterface.syncTaggedLogs(contractAddress, PENDING_TAGGED_LOG_ARRAY_BASE_SLOT);
445456

446-
// First sender should have 2 logs, but keep index 1 since they were built using the same tag
447-
// Next 4 senders should also have index 1 = offset + 1
448-
// Last 5 senders should have index 2 = offset + 2
449-
const indexes = await taggingDataProvider.getNextIndexesAsRecipient(secrets);
457+
// First sender should have 2 logs, but keep index 0 since they were built using the same tag
458+
// Next 4 senders should also have index 0 = offset
459+
// Last 5 senders should have index 1 = offset + 1
460+
const indexes = await taggingDataProvider.getLastUsedIndexesAsRecipient(secrets);
450461

451462
expect(indexes).toHaveLength(NUM_SENDERS);
452-
expect(indexes).toEqual([1, 1, 1, 1, 1, 2, 2, 2, 2, 2]);
463+
expect(indexes).toEqual([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]);
453464

454465
// We should have called the node 2 times:
455466
// first time during initial request, second time after pushing the edge of the window once

0 commit comments

Comments
 (0)