Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/docs-developers/docs/resources/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ Aztec is in active development. Each version may introduce breaking changes that

## TBD

### [Aztec.js] `ExtendedDirectionalAppTaggingSecret` renamed to `AppTaggingSecret`

`ExtendedDirectionalAppTaggingSecret` has been renamed to `AppTaggingSecret`.

**Migration:**

```diff
- import { ExtendedDirectionalAppTaggingSecret } from '@aztec/stdlib/logs';
+ import { AppTaggingSecret } from '@aztec/stdlib/logs';

- ExtendedDirectionalAppTaggingSecret.fromString(value)
+ AppTaggingSecret.fromString(value)
```

**Impact**: Code importing or referencing `ExtendedDirectionalAppTaggingSecret` should update to `AppTaggingSecret`.

### [Aztec.nr] `public_checks` helpers moved to `aztec-nr`

The `privately_check_timestamp`, `privately_check_block_number`, and related caller helpers previously in `noir-contracts/contracts/protocol/public_checks_contract/src/utils.nr` are now in `aztec-nr/aztec/src/public_checks.nr`. Consumer contracts should update their imports:
Expand Down
16 changes: 8 additions & 8 deletions docs/static/typescript-api/mainnet/pxe.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,10 @@ new RecipientTaggingStore(store: AztecAsyncKVStore)
**Methods**
- `commit(jobId: string) => Promise<void>` - Writes all job-specific in-memory data to persistent storage.
- `discardStaged(jobId: string) => Promise<void>` - Discards staged data without committing. Called on abort.
- `getHighestAgedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string) => Promise<number | undefined>`
- `getHighestFinalizedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string) => Promise<number | undefined>`
- `updateHighestAgedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number, jobId: string) => Promise<void>`
- `updateHighestFinalizedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number, jobId: string) => Promise<void>`
- `getHighestAgedIndex(secret: AppTaggingSecret, jobId: string) => Promise<number | undefined>`
- `getHighestFinalizedIndex(secret: AppTaggingSecret, jobId: string) => Promise<number | undefined>`
- `updateHighestAgedIndex(secret: AppTaggingSecret, index: number, jobId: string) => Promise<void>`
- `updateHighestFinalizedIndex(secret: AppTaggingSecret, index: number, jobId: string) => Promise<void>`

### SenderAddressBookStore

Expand Down Expand Up @@ -319,9 +319,9 @@ new SenderTaggingStore(store: AztecAsyncKVStore)
- `dropPendingIndexes(txHashes: TxHash[], jobId: string) => Promise<void>` - Drops all pending indexes corresponding to the given transaction hashes.
- `finalizePendingIndexes(txHashes: TxHash[], jobId: string) => Promise<void>` - Updates pending indexes corresponding to the given transaction hashes to be finalized and prunes any lower pending indexes.
- `finalizePendingIndexesOfAPartiallyRevertedTx(txEffect: TxEffect, jobId: string) => Promise<void>` - Handles finalization of pending indexes for a transaction whose execution was partially reverted. Recomputes the siloed tags for each pending index of the given tx and checks which ones appear in the TxEffect's private logs (i.e., which ones made it onchain). Those that survived are finalized; those that didn't are dropped.
- `getLastFinalizedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string) => Promise<number | undefined>` - Returns the last (highest) finalized index for a given secret.
- `getLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string) => Promise<number | undefined>` - Returns the last used index for a given directional app tagging secret, considering both finalized and pending indexes.
- `getTxHashesOfPendingIndexes(secret: ExtendedDirectionalAppTaggingSecret, startIndex: number, endIndex: number, jobId: string) => Promise<TxHash[]>` - Returns the transaction hashes of all pending transactions that contain highest indexes within a specified range for a given directional app tagging secret. We check based on the highest indexes only as that is the relevant information for the caller of this function.
- `getLastFinalizedIndex(secret: AppTaggingSecret, jobId: string) => Promise<number | undefined>` - Returns the last (highest) finalized index for a given secret.
- `getLastUsedIndex(secret: AppTaggingSecret, jobId: string) => Promise<number | undefined>` - Returns the last used index for a given directional app tagging secret, considering both finalized and pending indexes.
- `getTxHashesOfPendingIndexes(secret: AppTaggingSecret, startIndex: number, endIndex: number, jobId: string) => Promise<TxHash[]>` - Returns the transaction hashes of all pending transactions that contain highest indexes within a specified range for a given directional app tagging secret. We check based on the highest indexes only as that is the relevant information for the caller of this function.
- `storePendingIndexes(ranges: TaggingIndexRange[], txHash: TxHash, jobId: string) => Promise<void>` - Stores pending index ranges.

## Interfaces
Expand Down Expand Up @@ -548,4 +548,4 @@ This package references types from other Aztec packages:
- `AztecAsyncKVStore`, `DataStoreConfig`

**@aztec/stdlib**
- `AztecAddress`, `AztecNode`, `BlockHeader`, `Capsule`, `ChainConfig`, `CompleteAddress`, `ContractArtifact`, `ContractClass`, `ContractClassCommitments`, `ContractClassIdPreimage`, `ContractInstance`, `ContractInstanceWithAddress`, `DataInBlock`, `DebugLog`, `EventSelector`, `ExtendedDirectionalAppTaggingSecret`, `FunctionAbi`, `FunctionArtifactWithContractName`, `FunctionCall`, `FunctionDebugMetadata`, `FunctionSelector`, `InTx`, `IndexedTxEffect`, `Note`, `NoteDao`, `NoteStatus`, `SimulationError`, `TaggingIndexRange`, `TxEffect`, `TxExecutionRequest`, `TxHash`, `TxProfileResult`, `TxProvingResult`, `TxSimulationResult`, `UtilityExecutionResult`
- `AppTaggingSecret`, `AztecAddress`, `AztecNode`, `BlockHeader`, `Capsule`, `ChainConfig`, `CompleteAddress`, `ContractArtifact`, `ContractClass`, `ContractClassCommitments`, `ContractClassIdPreimage`, `ContractInstance`, `ContractInstanceWithAddress`, `DataInBlock`, `DebugLog`, `EventSelector`, `FunctionAbi`, `FunctionArtifactWithContractName`, `FunctionCall`, `FunctionDebugMetadata`, `FunctionSelector`, `InTx`, `IndexedTxEffect`, `Note`, `NoteDao`, `NoteStatus`, `SimulationError`, `TaggingIndexRange`, `TxEffect`, `TxExecutionRequest`, `TxHash`, `TxProfileResult`, `TxProvingResult`, `TxSimulationResult`, `UtilityExecutionResult`
12 changes: 6 additions & 6 deletions docs/static/typescript-api/mainnet/stdlib.md
Original file line number Diff line number Diff line change
Expand Up @@ -646,22 +646,22 @@ new ExtendedContractClassLog(id: LogId, log: ContractClassLog)
- `toBuffer() => Buffer` - Serializes log to a buffer.
- `toString() => string` - Serializes log to a string.

### ExtendedDirectionalAppTaggingSecret
### AppTaggingSecret

Extended directional application tagging secret used for log tagging. "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. "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.
Application tagging secret used for log tagging. 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. The derived secret is directional because it 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.

**Constructor**
```typescript
new ExtendedDirectionalAppTaggingSecret(secret: Fr, app: AztecAddress)
new AppTaggingSecret(secret: Fr, app: AztecAddress)
```

**Properties**
- `readonly app: AztecAddress`
- `readonly secret: Fr`

**Methods**
- `static compute(localAddress: CompleteAddress, localIvsk: Fq, externalAddress: AztecAddress, app: AztecAddress, recipient: AztecAddress) => Promise<ExtendedDirectionalAppTaggingSecret | undefined>` - Derives shared tagging secret and from that, the app address and recipient derives the directional app tagging secret. Returns undefined if `externalAddress` is an invalid address.
- `static fromString(str: string) => ExtendedDirectionalAppTaggingSecret`
- `static compute(localAddress: CompleteAddress, localIvsk: Fq, externalAddress: AztecAddress, app: AztecAddress, recipient: AztecAddress) => Promise<AppTaggingSecret | undefined>` - Derives shared tagging secret and from that, the app address and recipient derives the directional app tagging secret. Returns undefined if `externalAddress` is an invalid address.
- `static fromString(str: string) => AppTaggingSecret`
- `toString() => string`

### ExtendedPublicLog
Expand Down Expand Up @@ -4110,7 +4110,7 @@ type TX_ERROR_SIZE_ABOVE_LIMIT = "Transaction size above size limit"
```typescript
type TaggingIndexRange = unknown
```
Represents a range of tagging indexes for a given extended directional app tagging secret. Used to track the lowest and highest indexes used in a transaction for a given (sender, recipient, app/contract) tuple.
Represents a range of tagging indexes for a given app tagging secret.

### TxValidationResult
```typescript
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import { ExtendedDirectionalAppTaggingSecret, type TaggingIndexRange } from '@aztec/stdlib/logs';
import { AppTaggingSecret, type TaggingIndexRange } from '@aztec/stdlib/logs';

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

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

public setLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number) {
public setLastUsedIndex(secret: AppTaggingSecret, index: number) {
const currentValue = this.taggingIndexMap.get(secret.toString());
if (currentValue !== undefined && currentValue.highestIndex !== index - 1) {
throw new Error(`Invalid tagging index update. Current value: ${currentValue.highestIndex}, new value: ${index}`);
Expand All @@ -29,7 +25,7 @@ export class ExecutionTaggingIndexCache {
*/
public getUsedTaggingIndexRanges(): TaggingIndexRange[] {
return Array.from(this.taggingIndexMap.entries()).map(([secret, { lowestIndex, highestIndex }]) => ({
extendedSecret: ExtendedDirectionalAppTaggingSecret.fromString(secret),
extendedSecret: AppTaggingSecret.fromString(secret),
lowestIndex,
highestIndex,
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { AztecAddress } from '@aztec/stdlib/aztec-address';
import { siloNullifier } from '@aztec/stdlib/hash';
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
import { type ContractClassLog, ExtendedDirectionalAppTaggingSecret, type TaggingIndexRange } from '@aztec/stdlib/logs';
import { AppTaggingSecret, type ContractClassLog, type TaggingIndexRange } from '@aztec/stdlib/logs';
import { Tag } from '@aztec/stdlib/logs';
import { Note, type NoteStatus } from '@aztec/stdlib/note';
import {
Expand Down Expand Up @@ -207,11 +207,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
* @returns An app tag to be used in a log.
*/
public async getNextAppTagAsSender(sender: AztecAddress, recipient: AztecAddress): Promise<Tag> {
const extendedSecret = await this.#calculateExtendedDirectionalAppTaggingSecret(
this.contractAddress,
sender,
recipient,
);
const extendedSecret = await this.#calculateAppTaggingSecret(this.contractAddress, sender, recipient);

if (!extendedSecret) {
// We'd only fail to compute an extended secret if the recipient is an invalid address. To prevent
Expand All @@ -232,23 +228,13 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
return Tag.compute({ extendedSecret, index });
}

async #calculateExtendedDirectionalAppTaggingSecret(
contractAddress: AztecAddress,
sender: AztecAddress,
recipient: AztecAddress,
) {
async #calculateAppTaggingSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
const senderCompleteAddress = await this.getCompleteAddressOrFail(sender);
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
return ExtendedDirectionalAppTaggingSecret.compute(
senderCompleteAddress,
senderIvsk,
recipient,
contractAddress,
recipient,
);
return AppTaggingSecret.compute(senderCompleteAddress, senderIvsk, recipient, contractAddress, recipient);
}

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

Expand Down
14 changes: 3 additions & 11 deletions yarn-project/pxe/src/logs/log_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import type { KeyStore } from '@aztec/key-store';
import { AztecAddress } from '@aztec/stdlib/aztec-address';
import type { BlockHash, L2TipsProvider } from '@aztec/stdlib/block';
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
import {
ExtendedDirectionalAppTaggingSecret,
PendingTaggedLog,
SiloedTag,
type TxScopedL2Log,
} from '@aztec/stdlib/logs';
import { AppTaggingSecret, PendingTaggedLog, SiloedTag, type TxScopedL2Log } from '@aztec/stdlib/logs';
import type { BlockHeader } from '@aztec/stdlib/tx';

import {
Expand Down Expand Up @@ -158,10 +153,7 @@ export class LogService {
);
}

async #getSecretsForSenders(
contractAddress: AztecAddress,
recipient: AztecAddress,
): Promise<ExtendedDirectionalAppTaggingSecret[]> {
async #getSecretsForSenders(contractAddress: AztecAddress, recipient: AztecAddress): Promise<AppTaggingSecret[]> {
const recipientCompleteAddress = await this.addressStore.getCompleteAddress(recipient);
if (!recipientCompleteAddress) {
return [];
Expand All @@ -179,7 +171,7 @@ export class LogService {

return Promise.all(
deduplicatedSenders.map(async sender => {
const secret = await ExtendedDirectionalAppTaggingSecret.compute(
const secret = await AppTaggingSecret.compute(
recipientCompleteAddress,
recipientIvsk,
sender,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import { CompleteAddress, SerializableContractInstance } from '@aztec/stdlib/con
import { GasFees } from '@aztec/stdlib/gas';
import { PublicKey, PublicKeys } from '@aztec/stdlib/keys';
import {
AppTaggingSecret,
ContractClassLog,
ContractClassLogFields,
ExtendedDirectionalAppTaggingSecret,
PrivateLog,
PublicLog,
type TaggingIndexRange,
Expand Down Expand Up @@ -478,8 +478,8 @@ export const SCHEMA_TESTS: readonly SchemaTest[] = [
const recipientTaggingStore = new RecipientTaggingStore(kvStore);

const jobId = 'fixture-job';
const secretA = new ExtendedDirectionalAppTaggingSecret(new Fr(2n), AztecAddress.fromBigInt(3n));
const secretB = new ExtendedDirectionalAppTaggingSecret(new Fr(5n), AztecAddress.fromBigInt(7n));
const secretA = new AppTaggingSecret(new Fr(2n), AztecAddress.fromBigInt(3n));
const secretB = new AppTaggingSecret(new Fr(5n), AztecAddress.fromBigInt(7n));

await recipientTaggingStore.updateHighestFinalizedIndex(secretA, 11, jobId);
await recipientTaggingStore.updateHighestAgedIndex(secretA, 13, jobId);
Expand Down Expand Up @@ -512,9 +512,9 @@ export const SCHEMA_TESTS: readonly SchemaTest[] = [
const senderTaggingStore = new SenderTaggingStore(kvStore);

const jobId = 'fixture-job';
const secretA = new ExtendedDirectionalAppTaggingSecret(new Fr(2n), AztecAddress.fromBigInt(3n));
const secretB = new ExtendedDirectionalAppTaggingSecret(new Fr(5n), AztecAddress.fromBigInt(7n));
const secretC = new ExtendedDirectionalAppTaggingSecret(new Fr(11n), AztecAddress.fromBigInt(13n));
const secretA = new AppTaggingSecret(new Fr(2n), AztecAddress.fromBigInt(3n));
const secretB = new AppTaggingSecret(new Fr(5n), AztecAddress.fromBigInt(7n));
const secretC = new AppTaggingSecret(new Fr(11n), AztecAddress.fromBigInt(13n));
const txHashA = TxHash.fromBigInt(17n);
const txHashB = TxHash.fromBigInt(19n);
const txHashC = TxHash.fromBigInt(23n);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
import type { ExtendedDirectionalAppTaggingSecret } from '@aztec/stdlib/logs';
import { randomExtendedDirectionalAppTaggingSecret } from '@aztec/stdlib/testing';
import type { AppTaggingSecret } from '@aztec/stdlib/logs';
import { randomAppTaggingSecret } from '@aztec/stdlib/testing';

import { RecipientTaggingStore } from './recipient_tagging_store.js';

describe('RecipientTaggingStore', () => {
let taggingStore: RecipientTaggingStore;
let secret1: ExtendedDirectionalAppTaggingSecret;
let secret2: ExtendedDirectionalAppTaggingSecret;
let secret1: AppTaggingSecret;
let secret2: AppTaggingSecret;

beforeEach(async () => {
taggingStore = new RecipientTaggingStore(await openTmpStore('test'));
secret1 = await randomExtendedDirectionalAppTaggingSecret();
secret2 = await randomExtendedDirectionalAppTaggingSecret();
secret1 = await randomAppTaggingSecret();
secret2 = await randomAppTaggingSecret();
});

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

import type { StagedStore } from '../../job_coordinator/job_coordinator.js';

Expand Down Expand Up @@ -106,11 +106,11 @@ export class RecipientTaggingStore implements StagedStore {
return Promise.resolve();
}

getHighestAgedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
getHighestAgedIndex(secret: AppTaggingSecret, jobId: string): Promise<number | undefined> {
return this.#store.transactionAsync(() => this.#readHighestAgedIndex(jobId, secret.toString()));
}

updateHighestAgedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number, jobId: string): Promise<void> {
updateHighestAgedIndex(secret: AppTaggingSecret, index: number, jobId: string): Promise<void> {
return this.#store.transactionAsync(async () => {
const currentIndex = await this.#readHighestAgedIndex(jobId, secret.toString());
if (currentIndex !== undefined && index <= currentIndex) {
Expand All @@ -121,15 +121,11 @@ export class RecipientTaggingStore implements StagedStore {
});
}

getHighestFinalizedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
getHighestFinalizedIndex(secret: AppTaggingSecret, jobId: string): Promise<number | undefined> {
return this.#store.transactionAsync(() => this.#readHighestFinalizedIndex(jobId, secret.toString()));
}

updateHighestFinalizedIndex(
secret: ExtendedDirectionalAppTaggingSecret,
index: number,
jobId: string,
): Promise<void> {
updateHighestFinalizedIndex(secret: AppTaggingSecret, index: number, jobId: string): Promise<void> {
return this.#store.transactionAsync(async () => {
const currentIndex = await this.#readHighestFinalizedIndex(jobId, secret.toString());
if (currentIndex !== undefined && index < currentIndex) {
Expand Down
Loading
Loading