Skip to content
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

feat: process tagged logs #9623

Merged
merged 22 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
13 changes: 13 additions & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/notes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,16 @@ pub unconstrained fn get_app_tagging_secrets_for_senders(

#[oracle(getAppTaggingSecretsForSenders)]
unconstrained fn get_app_tagging_secrets_for_senders_oracle(_recipient: AztecAddress) -> [Field] {}

pub fn sync_notes(targetContractAddress: AztecAddress, recipient: AztecAddress) {
unsafe {
sync_notes_oracle_wrapper(targetContractAddress, recipient);
}
}

unconstrained fn sync_notes_oracle_wrapper(targetContractAddress: AztecAddress, recipient: AztecAddress) {
sync_notes_oracle(targetContractAddress, recipient);
}

#[oracle(syncNotes)]
unconstrained fn sync_notes_oracle(_targetContractAddress: AztecAddress, _recipient: AztecAddress) {}
6 changes: 3 additions & 3 deletions yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
type EncryptedL2NoteLog,
type FromLogType,
type GetUnencryptedLogsResponse,
type InboxLeaf,
Expand All @@ -15,6 +14,7 @@ import {
type TxEffect,
type TxHash,
type TxReceipt,
type TxScopedEncryptedL2NoteLog,
type UnencryptedL2Log,
} from '@aztec/circuit-types';
import {
Expand Down Expand Up @@ -634,7 +634,7 @@ export class Archiver implements ArchiveSource {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
*/
getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]> {
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]> {
return this.store.getLogsByTags(tags);
}

Expand Down Expand Up @@ -934,7 +934,7 @@ class ArchiverStoreHelper
): Promise<L2BlockL2Logs<FromLogType<TLogType>>[]> {
return this.store.getLogs(from, limit, logType);
}
getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]> {
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]> {
return this.store.getLogsByTags(tags);
}
getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse> {
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/archiver/src/archiver/archiver_store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
type EncryptedL2NoteLog,
type FromLogType,
type GetUnencryptedLogsResponse,
type InboxLeaf,
Expand All @@ -10,6 +9,7 @@ import {
type TxEffect,
type TxHash,
type TxReceipt,
type TxScopedEncryptedL2NoteLog,
} from '@aztec/circuit-types';
import {
type ContractClassPublic,
Expand Down Expand Up @@ -142,7 +142,7 @@ export interface ArchiverDataStore {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
*/
getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]>;
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]>;

/**
* Gets unencrypted logs based on the provided filter.
Expand Down
12 changes: 7 additions & 5 deletions yarn-project/archiver/src/archiver/archiver_store_test_suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch

logsByTags.forEach((logsByTag, logIndex) => {
expect(logsByTag).toHaveLength(1);
const [log] = logsByTag;
expect(log).toEqual(
const [scopedLog] = logsByTag;
expect(scopedLog.txHash).toEqual(blocks[targetBlockIndex].data.body.txEffects[targetTxIndex].txHash);
expect(scopedLog.log).toEqual(
blocks[targetBlockIndex].data.body.noteEncryptedLogs.txLogs[targetTxIndex].unrollLogs()[logIndex],
);
});
Expand All @@ -427,7 +428,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch

logsByTags.forEach(logsByTag => {
expect(logsByTag).toHaveLength(2);
const [tag0, tag1] = logsByTag.map(log => new Fr(log.data.subarray(0, 32)));
const [tag0, tag1] = logsByTag.map(scopedLog => new Fr(scopedLog.log.data.subarray(0, 32)));
expect(tag0).toEqual(tag1);
});
});
Expand All @@ -450,8 +451,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch

populatedLogsByTags.forEach((logsByTag, logIndex) => {
expect(logsByTag).toHaveLength(1);
const [log] = logsByTag;
expect(log).toEqual(
const [scopedLog] = logsByTag;
expect(scopedLog.txHash).toEqual(blocks[targetBlockIndex].data.body.txEffects[targetTxIndex].txHash);
expect(scopedLog.log).toEqual(
blocks[targetBlockIndex].data.body.noteEncryptedLogs.txLogs[targetTxIndex].unrollLogs()[logIndex + 1],
);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
type EncryptedL2NoteLog,
type FromLogType,
type GetUnencryptedLogsResponse,
type InboxLeaf,
Expand All @@ -10,6 +9,7 @@ import {
type TxEffect,
type TxHash,
type TxReceipt,
type TxScopedEncryptedL2NoteLog,
} from '@aztec/circuit-types';
import {
type ContractClassPublic,
Expand Down Expand Up @@ -245,7 +245,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
*/
getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]> {
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]> {
try {
return this.#logStore.getLogsByTags(tags);
} catch (err) {
Expand Down
22 changes: 15 additions & 7 deletions yarn-project/archiver/src/archiver/kv_archiver_store/log_store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
EncryptedL2BlockL2Logs,
EncryptedL2NoteLog,
EncryptedNoteL2BlockL2Logs,
ExtendedUnencryptedL2Log,
type FromLogType,
Expand All @@ -10,11 +9,12 @@ import {
type LogFilter,
LogId,
LogType,
TxScopedEncryptedL2NoteLog,
UnencryptedL2BlockL2Logs,
type UnencryptedL2Log,
} from '@aztec/circuit-types';
import { Fr } from '@aztec/circuits.js';
import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants';
import { INITIAL_L2_BLOCK_NUM, MAX_NOTE_HASHES_PER_TX } from '@aztec/circuits.js/constants';
import { createDebugLogger } from '@aztec/foundation/log';
import { type AztecKVStore, type AztecMap, type AztecMultiMap } from '@aztec/kv-store';

Expand Down Expand Up @@ -52,8 +52,13 @@ export class LogStore {
addLogs(blocks: L2Block[]): Promise<boolean> {
return this.db.transaction(() => {
blocks.forEach(block => {
const dataStartIndexForBlock =
block.header.state.partial.noteHashTree.nextAvailableLeafIndex -
block.body.numberOfTxsIncludingPadded * MAX_NOTE_HASHES_PER_TX;
void this.#noteEncryptedLogsByBlock.set(block.number, block.body.noteEncryptedLogs.toBuffer());
block.body.noteEncryptedLogs.txLogs.forEach(txLogs => {
block.body.noteEncryptedLogs.txLogs.forEach((txLogs, txIndex) => {
const txHash = block.body.txEffects[txIndex].txHash;
const dataStartIndexForTx = dataStartIndexForBlock + txIndex * MAX_NOTE_HASHES_PER_TX;
Thunkar marked this conversation as resolved.
Show resolved Hide resolved
const noteLogs = txLogs.unrollLogs();
noteLogs.forEach(noteLog => {
if (noteLog.data.length < 32) {
Expand All @@ -63,12 +68,15 @@ export class LogStore {
try {
const tag = new Fr(noteLog.data.subarray(0, 32));
const hexHash = noteLog.hash().toString('hex');
// Ideally we'd store all of the logs for a matching tag in an AztecMultiMap, but this type doesn't doesn't
// Ideally we'd store all of the logs for a matching tag in an AztecMultiMap, but this type doesn't
// handle storing buffers well. The 'ordered-binary' encoding returns an error trying to decode buffers
// ('the number <> cannot be converted to a BigInt because it is not an integer'). We therefore store
// instead the hashes of the logs.
void this.#noteEncryptedLogHashesByTag.set(tag.toString(), hexHash);
void this.#noteEncryptedLogsByHash.set(hexHash, noteLog.toBuffer());
void this.#noteEncryptedLogsByHash.set(
hexHash,
new TxScopedEncryptedL2NoteLog(txHash, dataStartIndexForTx, noteLog).toBuffer(),
);
void this.#noteEncryptedLogTagsByBlock.set(block.number, tag.toString());
} catch (err) {
this.#log.warn(`Failed to add tagged note log to store: ${err}`);
Expand Down Expand Up @@ -156,7 +164,7 @@ export class LogStore {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
*/
getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]> {
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]> {
return this.db.transaction(() => {
return tags.map(tag => {
const logHashes = Array.from(this.#noteEncryptedLogHashesByTag.getValues(tag.toString()));
Expand All @@ -166,7 +174,7 @@ export class LogStore {
// addLogs should ensure that we never have undefined logs, but we filter them out regardless to protect
// ourselves from database corruption
.filter(noteLogBuffer => noteLogBuffer != undefined)
.map(noteLogBuffer => EncryptedL2NoteLog.fromBuffer(noteLogBuffer!))
.map(noteLogBuffer => TxScopedEncryptedL2NoteLog.fromBuffer(noteLogBuffer!))
);
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
type EncryptedL2BlockL2Logs,
type EncryptedL2NoteLog,
type EncryptedNoteL2BlockL2Logs,
ExtendedUnencryptedL2Log,
type FromLogType,
Expand All @@ -14,6 +13,7 @@ import {
type TxEffect,
type TxHash,
TxReceipt,
TxScopedEncryptedL2NoteLog,
type UnencryptedL2BlockL2Logs,
} from '@aztec/circuit-types';
import {
Expand All @@ -24,6 +24,7 @@ import {
Fr,
type Header,
INITIAL_L2_BLOCK_NUM,
MAX_NOTE_HASHES_PER_TX,
type UnconstrainedFunctionWithMembershipProof,
} from '@aztec/circuits.js';
import { type ContractArtifact } from '@aztec/foundation/abi';
Expand Down Expand Up @@ -51,7 +52,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {

private noteEncryptedLogsPerBlock: Map<number, EncryptedNoteL2BlockL2Logs> = new Map();

private taggedNoteEncryptedLogs: Map<string, EncryptedL2NoteLog[]> = new Map();
private taggedNoteEncryptedLogs: Map<string, TxScopedEncryptedL2NoteLog[]> = new Map();

private noteEncryptedLogTagsPerBlock: Map<number, Fr[]> = new Map();

Expand Down Expand Up @@ -213,8 +214,13 @@ export class MemoryArchiverStore implements ArchiverDataStore {
*/
addLogs(blocks: L2Block[]): Promise<boolean> {
blocks.forEach(block => {
const dataStartIndexForBlock =
block.header.state.partial.noteHashTree.nextAvailableLeafIndex -
block.body.numberOfTxsIncludingPadded * MAX_NOTE_HASHES_PER_TX;
this.noteEncryptedLogsPerBlock.set(block.number, block.body.noteEncryptedLogs);
block.body.noteEncryptedLogs.txLogs.forEach(txLogs => {
block.body.noteEncryptedLogs.txLogs.forEach((txLogs, txIndex) => {
const txHash = block.body.txEffects[txIndex].txHash;
const dataStartIndexForTx = dataStartIndexForBlock + txIndex * MAX_NOTE_HASHES_PER_TX;
const noteLogs = txLogs.unrollLogs();
noteLogs.forEach(noteLog => {
if (noteLog.data.length < 32) {
Expand All @@ -224,7 +230,10 @@ export class MemoryArchiverStore implements ArchiverDataStore {
try {
const tag = new Fr(noteLog.data.subarray(0, 32));
const currentNoteLogs = this.taggedNoteEncryptedLogs.get(tag.toString()) || [];
this.taggedNoteEncryptedLogs.set(tag.toString(), [...currentNoteLogs, noteLog]);
this.taggedNoteEncryptedLogs.set(tag.toString(), [
...currentNoteLogs,
new TxScopedEncryptedL2NoteLog(txHash, dataStartIndexForTx, noteLog),
]);
const currentTagsInBlock = this.noteEncryptedLogTagsPerBlock.get(block.number) || [];
this.noteEncryptedLogTagsPerBlock.set(block.number, [...currentTagsInBlock, tag]);
} catch (err) {
Expand Down Expand Up @@ -419,7 +428,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
*/
getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]> {
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]> {
const noteLogs = tags.map(tag => this.taggedNoteEncryptedLogs.get(tag.toString()) || []);
return Promise.resolve(noteLogs);
}
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { BBCircuitVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
import {
type AztecNode,
type ClientProtocolCircuitVerifier,
type EncryptedL2NoteLog,
type EpochProofQuote,
type FromLogType,
type GetUnencryptedLogsResponse,
Expand All @@ -27,6 +26,7 @@ import {
type TxEffect,
type TxHash,
TxReceipt,
type TxScopedEncryptedL2NoteLog,
TxStatus,
type TxValidator,
type WorldStateSynchronizer,
Expand Down Expand Up @@ -314,7 +314,7 @@ export class AztecNodeService implements AztecNode {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
*/
public getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]> {
public getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]> {
return this.encryptedLogsSource.getLogsByTags(tags);
}

Expand Down
3 changes: 2 additions & 1 deletion yarn-project/circuit-types/src/interfaces/aztec-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
L2BlockL2Logs,
LogFilter,
LogType,
TxScopedEncryptedL2NoteLog,
} from '../logs/index.js';
import type { MerkleTreeId } from '../merkle_tree_id.js';
import type { EpochProofQuote } from '../prover_coordination/epoch_proof_quote.js';
Expand Down Expand Up @@ -258,7 +259,7 @@ export interface AztecNode extends ProverCoordination {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
Thunkar marked this conversation as resolved.
Show resolved Hide resolved
*/
getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]>;
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]>;

/**
* Method to submit a transaction to the p2p pool.
Expand Down
37 changes: 37 additions & 0 deletions yarn-project/circuit-types/src/logs/get_logs_response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Fr } from '@aztec/circuits.js';
import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';

import { EncryptedL2NoteLog, Tx, TxHash } from '../index.js';
import { type ExtendedUnencryptedL2Log } from './extended_unencrypted_l2_log.js';

/**
* It provides documentation for the GetUnencryptedLogsResponse type.
*/
export type GetUnencryptedLogsResponse = {
/**
* An array of ExtendedUnencryptedL2Log elements.
*/
logs: ExtendedUnencryptedL2Log[];

/**
* Indicates if a limit has been reached.
*/
maxLogsHit: boolean;
};

export class TxScopedEncryptedL2NoteLog {
constructor(public txHash: TxHash, public dataStartIndexForTx: number, public log: EncryptedL2NoteLog) {}

toBuffer() {
return Buffer.concat([this.txHash.toBuffer(), numToUInt32BE(this.dataStartIndexForTx), this.log.toBuffer()]);
}

static fromBuffer(buffer: Buffer) {
const reader = BufferReader.asReader(buffer);
return new TxScopedEncryptedL2NoteLog(
TxHash.fromField(reader.readObject(Fr)),
reader.readNumber(),
EncryptedL2NoteLog.fromBuffer(reader.readToEnd()),
);
}
}

This file was deleted.

2 changes: 1 addition & 1 deletion yarn-project/circuit-types/src/logs/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export * from './encrypted_l2_note_log.js';
export * from './encrypted_l2_log.js';
export * from './event_metadata.js';
export * from './get_unencrypted_logs_response.js';
export * from './get_logs_response.js';
export * from './function_l2_logs.js';
export * from './l2_block_l2_logs.js';
export * from './l2_logs_source.js';
Expand Down
5 changes: 2 additions & 3 deletions yarn-project/circuit-types/src/logs/l2_logs_source.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { type Fr } from '@aztec/circuits.js';

import { type EncryptedL2NoteLog } from './encrypted_l2_note_log.js';
import { type GetUnencryptedLogsResponse } from './get_unencrypted_logs_response.js';
import { type GetUnencryptedLogsResponse, type TxScopedEncryptedL2NoteLog } from './get_logs_response.js';
import { type L2BlockL2Logs } from './l2_block_l2_logs.js';
import { type LogFilter } from './log_filter.js';
import { type FromLogType, type LogType } from './log_type.js';
Expand Down Expand Up @@ -29,7 +28,7 @@ export interface L2LogsSource {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
*/
getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]>;
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]>;

/**
* Gets unencrypted logs based on the provided filter.
Expand Down
Loading
Loading