-
Notifications
You must be signed in to change notification settings - Fork 575
feat: ExecutionTaggingIndexCache
#17445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import { DirectionalAppTaggingSecret, type IndexedTaggingSecret } from '@aztec/stdlib/logs'; | ||
|
|
||
| /** | ||
| * A map that stores the tagging index for a given 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<string, number> = new Map(); | ||
|
|
||
| public getTaggingIndex(secret: DirectionalAppTaggingSecret): number | undefined { | ||
| return this.taggingIndexMap.get(secret.toString()); | ||
| } | ||
|
|
||
| public setTaggingIndex(secret: DirectionalAppTaggingSecret, 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}`); | ||
| } | ||
| this.taggingIndexMap.set(secret.toString(), index); | ||
| } | ||
|
|
||
| public getIndexedTaggingSecrets(): IndexedTaggingSecret[] { | ||
| return Array.from(this.taggingIndexMap.entries()).map(([secret, index]) => ({ | ||
| secret: DirectionalAppTaggingSecret.fromString(secret), | ||
| index, | ||
| })); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ import type { AuthWitness } from '@aztec/stdlib/auth-witness'; | |
| import { AztecAddress } from '@aztec/stdlib/aztec-address'; | ||
| import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash'; | ||
| import { PrivateContextInputs } from '@aztec/stdlib/kernel'; | ||
| import type { ContractClassLog } from '@aztec/stdlib/logs'; | ||
| import type { ContractClassLog, IndexedTaggingSecret } from '@aztec/stdlib/logs'; | ||
| import { Note, type NoteStatus } from '@aztec/stdlib/note'; | ||
| import { | ||
| type BlockHeader, | ||
|
|
@@ -26,9 +26,10 @@ import { | |
| type TxContext, | ||
| } from '@aztec/stdlib/tx'; | ||
|
|
||
| import type { Tag } from '../../tagging/tag.js'; | ||
| import { Tag } from '../../tagging/tag.js'; | ||
| import type { ExecutionDataProvider } from '../execution_data_provider.js'; | ||
| import type { ExecutionNoteCache } from '../execution_note_cache.js'; | ||
| import { ExecutionTaggingIndexCache } from '../execution_tagging_index_cache.js'; | ||
| import type { HashedValuesCache } from '../hashed_values_cache.js'; | ||
| import { pickNotes } from '../pick_notes.js'; | ||
| import type { IPrivateExecutionOracle, NoteData } from './interfaces.js'; | ||
|
|
@@ -76,6 +77,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP | |
| capsules: Capsule[], | ||
| private readonly executionCache: HashedValuesCache, | ||
| private readonly noteCache: ExecutionNoteCache, | ||
| private readonly taggingIndexCache: ExecutionTaggingIndexCache, | ||
| executionDataProvider: ExecutionDataProvider, | ||
| private totalPublicCalldataCount: number = 0, | ||
| protected sideEffectCounter: number = 0, | ||
|
|
@@ -149,6 +151,13 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP | |
| return this.offchainEffects; | ||
| } | ||
|
|
||
| /** | ||
| * Return the tagging indexes incremented by this execution along with the directional app tagging secrets. | ||
| */ | ||
| public getIndexedTaggingSecrets(): IndexedTaggingSecret[] { | ||
| return this.taggingIndexCache.getIndexedTaggingSecrets(); | ||
| } | ||
|
Comment on lines
+155
to
+159
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This solidified me not liking the 'indexed tagging secret' name - I just don't really know what it means. The 'tagging secret' part is particuarly annoying because it hides a lot of stuff and makes me have to think about the complexity of the tag derivation. Like, the tagging secret is not really indexed - that'd be the tag. What this is is the 'app siloed sender/recipient shared secret'. Perhaps we need to come up with a name for the thing that we combine with an index to get a tag, e.g. the 'pretag', 'tag seed', or whatever. At any rate, I'd also change the name of this function, which is not very descriptive. Get which tagging secrets? I'd call it 'getUsedTags' or something nicer that conveys that these are the tags that this execution consumed and should be a) tracked by tx and b) never used again.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have a point. The As to the name of the function it's quite confusing here because it's not the last used indexes but it's the indexes that are to be used in a tx. This is done because it makes the tagging data provider simpler as then we never need to return undefined from the
But anyway I think it would be a good way to change this as handling undefined in 1 place is better then having all these function confusing. I propose the following:
Doing all these refactor would explode the scope of this PR so I would do that in a followup one. Sounds good? |
||
|
|
||
| /** | ||
| * Return the nested execution results during this execution. | ||
| */ | ||
|
|
@@ -193,21 +202,40 @@ 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<Tag> { | ||
| const directionalAppTaggingSecret = await this.executionDataProvider.calculateDirectionalAppTaggingSecret( | ||
| const secret = await this.executionDataProvider.calculateDirectionalAppTaggingSecret( | ||
| this.contractAddress, | ||
| sender, | ||
| recipient, | ||
| ); | ||
|
|
||
| // TODO(benesjan): In a follow-up PR we will load here the index from the ExecutionTaggingIndexCache if present | ||
| // and if not we will obtain it from the execution data provider. | ||
| // If we have the tagging index in the cache, we use it. If not we obtain it from the execution data provider. | ||
| // TODO(benesjan): Make this be `getLastUsedIndex` and refactor this function to look as proposed in this comment: | ||
| // https://github.com/AztecProtocol/aztec-packages/pull/17445#discussion_r2400365845 | ||
| const maybeTaggingIndex = this.taggingIndexCache.getTaggingIndex(secret); | ||
| let taggingIndex: number; | ||
|
|
||
| if (maybeTaggingIndex !== undefined) { | ||
| taggingIndex = maybeTaggingIndex; | ||
| } else { | ||
| // This is a tagging secret we've not yet used in this tx, so first sync our store to make sure its indices | ||
| // are up to date. We do this here because this store is not synced as part of the global sync because | ||
| // that'd be wasteful as most tagging secrets are not used in each tx. | ||
| this.log.debug(`Syncing tagged logs as sender ${sender} for contract ${this.contractAddress}`, { | ||
| directionalAppTaggingSecret: secret, | ||
| recipient, | ||
| }); | ||
| await this.executionDataProvider.syncTaggedLogsAsSender(secret, this.contractAddress); | ||
| taggingIndex = await this.executionDataProvider.getNextIndexAsSender(secret); | ||
| } | ||
|
|
||
| this.log.debug(`Syncing tagged logs as sender ${sender} for contract ${this.contractAddress}`, { | ||
| directionalAppTaggingSecret, | ||
| recipient, | ||
| }); | ||
| await this.executionDataProvider.syncTaggedLogsAsSender(directionalAppTaggingSecret, this.contractAddress); | ||
| return this.executionDataProvider.getNextAppTagAsSender(directionalAppTaggingSecret); | ||
| // Now we increment the index by 1 and store it in the cache. | ||
| const nextTaggingIndex = taggingIndex + 1; | ||
| this.log.debug( | ||
| `Incrementing tagging index for sender: ${sender}, recipient: ${recipient}, contract: ${this.contractAddress} to ${nextTaggingIndex}`, | ||
| ); | ||
| this.taggingIndexCache.setTaggingIndex(secret, nextTaggingIndex); | ||
|
|
||
| return Tag.compute({ secret, index: taggingIndex }); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -480,6 +508,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP | |
| this.capsules, | ||
| this.executionCache, | ||
| this.noteCache, | ||
| this.taggingIndexCache, | ||
| this.executionDataProvider, | ||
| this.totalPublicCalldataCount, | ||
| sideEffectCounter, | ||
|
|
||

Uh oh!
There was an error while loading. Please reload this page.