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
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,21 @@ export class LogStore {
const txHash = txEffect.txHash;
const dataStartIndexForTx = dataStartIndexForBlock + txIndex * MAX_NOTE_HASHES_PER_TX;

txEffect.privateLogs.forEach(log => {
txEffect.privateLogs.forEach((log, logIndex) => {
const tag = log.fields[0];
this.#log.debug(`Found private log with tag ${tag.toString()} in block ${block.number}`);

const currentLogs = taggedLogs.get(tag.toString()) ?? [];
currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, block.number, log).toBuffer());
currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, logIndex, block.number, log).toBuffer());
taggedLogs.set(tag.toString(), currentLogs);
});

txEffect.publicLogs.forEach(log => {
txEffect.publicLogs.forEach((log, logIndex) => {
const tag = log.log[0];
this.#log.debug(`Found public log with tag ${tag.toString()} in block ${block.number}`);

const currentLogs = taggedLogs.get(tag.toString()) ?? [];
currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, block.number, log).toBuffer());
currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, logIndex, block.number, log).toBuffer());
taggedLogs.set(tag.toString(), currentLogs);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ describe('PXEOracleInterface', () => {
for (const sender of senders) {
const tag = await computeSiloedTagForIndex(sender, recipient.address, contractAddress, tagIndex);
const blockNumber = 1;
const log = new TxScopedL2Log(TxHash.random(), 0, blockNumber, PrivateLog.random(tag));
const log = new TxScopedL2Log(TxHash.random(), 0, 0, blockNumber, PrivateLog.random(tag));
logs[tag.toString()] = [log];
}
// Accumulated logs intended for recipient: NUM_SENDERS
Expand All @@ -112,7 +112,7 @@ describe('PXEOracleInterface', () => {
// Compute the tag as sender (knowledge of preaddress and ivsk)
const firstSender = senders[0];
const tag = await computeSiloedTagForIndex(firstSender, recipient.address, contractAddress, tagIndex);
const log = new TxScopedL2Log(TxHash.random(), 1, 0, PrivateLog.random(tag));
const log = new TxScopedL2Log(TxHash.random(), 1, 0, 0, PrivateLog.random(tag));
logs[tag.toString()].push(log);
// Accumulated logs intended for recipient: NUM_SENDERS + 1

Expand All @@ -122,7 +122,7 @@ describe('PXEOracleInterface', () => {
const sender = senders[i];
const tag = await computeSiloedTagForIndex(sender, recipient.address, contractAddress, tagIndex + 1);
const blockNumber = 2;
const log = new TxScopedL2Log(TxHash.random(), 0, blockNumber, PrivateLog.random(tag));
const log = new TxScopedL2Log(TxHash.random(), 0, 0, blockNumber, PrivateLog.random(tag));
logs[tag.toString()] = [log];
}
// Accumulated logs intended for recipient: NUM_SENDERS + 1 + NUM_SENDERS / 2
Expand All @@ -135,7 +135,7 @@ describe('PXEOracleInterface', () => {
const randomRecipient = await computeAddress(keys.publicKeys, partialAddress);
const tag = await computeSiloedTagForIndex(sender, randomRecipient, contractAddress, tagIndex);
const blockNumber = 3;
const log = new TxScopedL2Log(TxHash.random(), 0, blockNumber, PrivateLog.random(tag));
const log = new TxScopedL2Log(TxHash.random(), 0, 0, blockNumber, PrivateLog.random(tag));
logs[tag.toString()] = [log];
}
// Accumulated logs intended for recipient: NUM_SENDERS + 1 + NUM_SENDERS / 2
Expand Down Expand Up @@ -406,7 +406,7 @@ describe('PXEOracleInterface', () => {
typeof PUBLIC_LOG_DATA_SIZE_IN_FIELDS
>;
const log = new PublicLog(await AztecAddress.random(), logContent);
const scopedLog = new TxScopedL2Log(TxHash.random(), 1, 0, log);
const scopedLog = new TxScopedL2Log(TxHash.random(), 1, 0, 0, log);

logs[tag.toString()] = [scopedLog];
aztecNode.getLogsByTags.mockImplementation(tags => {
Expand Down Expand Up @@ -457,7 +457,7 @@ describe('PXEOracleInterface', () => {
function mockTaggedLogs(numLogs: number) {
return Array(numLogs)
.fill(0)
.map(() => new TxScopedL2Log(TxHash.random(), 0, 0, PrivateLog.random(Fr.random())));
.map(() => new TxScopedL2Log(TxHash.random(), 0, 0, 0, PrivateLog.random(Fr.random())));
}

it('should call processLog on multiple logs', async () => {
Expand Down
24 changes: 2 additions & 22 deletions yarn-project/pxe/src/pxe_oracle_interface/pxe_oracle_interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { type L1_TO_L2_MSG_TREE_HEIGHT, MAX_NOTE_HASHES_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
import { timesParallel } from '@aztec/foundation/collection';
import { randomInt } from '@aztec/foundation/crypto';
import { Fr, Point } from '@aztec/foundation/fields';
import { createLogger } from '@aztec/foundation/log';
import type { KeyStore } from '@aztec/key-store';
Expand All @@ -27,13 +26,7 @@ import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdli
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
import { computeAddressSecret, computeAppTaggingSecret } from '@aztec/stdlib/keys';
import {
IndexedTaggingSecret,
LogWithTxData,
PrivateLog,
TxScopedL2Log,
deriveEcdhSharedSecret,
} from '@aztec/stdlib/logs';
import { IndexedTaggingSecret, LogWithTxData, TxScopedL2Log, deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
import { Note, type NoteStatus } from '@aztec/stdlib/note';
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
Expand Down Expand Up @@ -613,27 +606,14 @@ export class PXEOracleInterface implements ExecutionDataProvider {
throw new Error(`Could not find tx effect for tx hash ${scopedLog.txHash}`);
}

// TODO(#13155): Handle multiple found indexes for the same log.
let logIndexInTx = txEffect.data.privateLogs.findIndex(log => log.equals(scopedLog.log as PrivateLog));

// TODO(#13137): The following is a workaround to disable the logIndexInTx check for TXE tests as TXE currently
// returns nonsensical tx effects and the tx has is incremented from 0 up (so it never crosses a 1000).
if (scopedLog.txHash.toBigInt() < 1000n) {
logIndexInTx = randomInt(10);
}

if (logIndexInTx === -1) {
throw new Error(`Could not find log in tx effect for tx hash ${scopedLog.txHash}`);
}

// This will trigger calls to the deliverNote oracle
await this.callProcessLog(
contractAddress,
scopedLog.log.toFields(),
scopedLog.txHash,
txEffect.data.noteHashes,
txEffect.data.nullifiers[0],
logIndexInTx,
scopedLog.logIndexInTx,
recipient,
simulator,
);
Expand Down
17 changes: 13 additions & 4 deletions yarn-project/stdlib/src/logs/tx_scoped_l2_log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export class TxScopedL2Log {
* with the log so the noteHashIndex can be reconstructed after decryption.
*/
public dataStartIndexForTx: number,
/*
* The index of the log in the transaction. Note that public and private logs are in separate arrays in the tx
* effect and for this reason these indices are independent (a private and public log can have the same index).
*/
public logIndexInTx: number,
/*
* The block this log is included in
*/
Expand All @@ -36,12 +41,13 @@ export class TxScopedL2Log {
.object({
txHash: TxHash.schema,
dataStartIndexForTx: z.number(),
logIndexInTx: z.number(),
blockNumber: z.number(),
log: z.union([PrivateLog.schema, PublicLog.schema]),
})
.transform(
({ txHash, dataStartIndexForTx, blockNumber, log }) =>
new TxScopedL2Log(txHash, dataStartIndexForTx, blockNumber, log),
({ txHash, dataStartIndexForTx, logIndexInTx, blockNumber, log }) =>
new TxScopedL2Log(txHash, dataStartIndexForTx, logIndexInTx, blockNumber, log),
);
}

Expand All @@ -50,6 +56,7 @@ export class TxScopedL2Log {
return Buffer.concat([
this.txHash.toBuffer(),
numToUInt32BE(this.dataStartIndexForTx),
numToUInt32BE(this.logIndexInTx),
numToUInt32BE(this.blockNumber),
boolToBuffer(isFromPublic),
this.log.toBuffer(),
Expand All @@ -60,23 +67,25 @@ export class TxScopedL2Log {
const reader = BufferReader.asReader(buffer);
const txHash = reader.readObject(TxHash);
const dataStartIndexForTx = reader.readNumber();
const logIndexInTx = reader.readNumber();
const blockNumber = reader.readNumber();
const isFromPublic = reader.readBoolean();
const log = isFromPublic ? PublicLog.fromBuffer(reader) : PrivateLog.fromBuffer(reader);

return new TxScopedL2Log(txHash, dataStartIndexForTx, blockNumber, log);
return new TxScopedL2Log(txHash, dataStartIndexForTx, logIndexInTx, blockNumber, log);
}

static async random() {
const isFromPublic = Math.random() < 0.5;
const log = isFromPublic ? await PublicLog.random() : PrivateLog.random();
return new TxScopedL2Log(TxHash.random(), 1, 1, log);
return new TxScopedL2Log(TxHash.random(), 1, 1, 1, log);
}

equals(other: TxScopedL2Log) {
return (
this.txHash.equals(other.txHash) &&
this.dataStartIndexForTx === other.dataStartIndexForTx &&
this.logIndexInTx === other.logIndexInTx &&
this.blockNumber === other.blockNumber &&
((this.log instanceof PublicLog && other.log instanceof PublicLog) ||
(this.log instanceof PrivateLog && other.log instanceof PrivateLog)) &&
Expand Down
45 changes: 23 additions & 22 deletions yarn-project/txe/src/node/txe_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import type {
SequencerConfig,
WorldStateSyncStatus,
} from '@aztec/stdlib/interfaces/server';
import { type LogFilter, type PrivateLog, type PublicLog, TxScopedL2Log } from '@aztec/stdlib/logs';
import { type LogFilter, type PrivateLog, TxScopedL2Log } from '@aztec/stdlib/logs';
import {
MerkleTreeId,
type NullifierMembershipWitness,
Expand Down Expand Up @@ -98,12 +98,12 @@ export class TXENode implements AztecNode {
}

/**
* Sets a tx effect and receipt for a given block number.
* Processes a tx effect and receipt for a given block number.
* @param blockNumber - The block number that this tx effect resides.
* @param txHash - The transaction hash of the transaction.
* @param effect - The tx effect to set.
*/
async setTxEffect(blockNumber: number, txHash: TxHash, effect: TxEffect) {
async processTxEffect(blockNumber: number, txHash: TxHash, effect: TxEffect) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed to have a guarantee that the private and public logs are in the correct order and to achieve that made sense to correctly set them on the TxEffect and than have this 1 function process the tx effect instead of the separate 3.

// We are not creating real blocks on which membership proofs can be constructed - we instead define its hash as
// simply the hash of the block number.
const blockHash = await poseidon2Hash([blockNumber]);
Expand All @@ -127,44 +127,45 @@ export class TXENode implements AztecNode {
blockNumber,
),
);
}

/**
* Adds private logs to the txe node, given a block
* @param blockNumber - The block number at which to add the private logs.
* @param privateLogs - The privateLogs that contain the private logs to be added.
*/
addPrivateLogsByTags(blockNumber: number, privateLogs: PrivateLog[]) {
privateLogs.forEach(log => {
// Store the private logs
effect.privateLogs.forEach((log, logIndexInTx) => {
const tag = log.fields[0];
this.#logger.verbose(`Found private log with tag ${tag.toString()} in block ${this.getBlockNumber()}`);

const currentLogs = this.#logsByTags.get(tag.toString()) ?? [];
const scopedLog = new TxScopedL2Log(new TxHash(new Fr(blockNumber)), this.#noteIndex, blockNumber, log);
const scopedLog = new TxScopedL2Log(
new TxHash(new Fr(blockNumber)),
this.#noteIndex,
logIndexInTx,
blockNumber,
log,
);
currentLogs.push(scopedLog);
this.#logsByTags.set(tag.toString(), currentLogs);
});

this.#noteIndex += privateLogs.length;
}
this.#noteIndex += effect.privateLogs.length;

/**
* Adds public logs to the txe node, given a block
* @param blockNumber - The block number at which to add the public logs.
* @param publicLogs - The public logs to be added.
*/
addPublicLogsByTags(blockNumber: number, publicLogs: PublicLog[]) {
publicLogs.forEach(log => {
// Store the public logs
effect.publicLogs.forEach((log, logIndexInTx) => {
const tag = log.log[0];
this.#logger.verbose(`Found public log with tag ${tag.toString()} in block ${this.getBlockNumber()}`);

const currentLogs = this.#logsByTags.get(tag.toString()) ?? [];
const scopedLog = new TxScopedL2Log(new TxHash(new Fr(blockNumber)), this.#noteIndex, blockNumber, log);
const scopedLog = new TxScopedL2Log(
new TxHash(new Fr(blockNumber)),
this.#noteIndex,
logIndexInTx,
blockNumber,
log,
);

currentLogs.push(scopedLog);
this.#logsByTags.set(tag.toString(), currentLogs);
});
}

/**
* Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag).
* @param tags - The tags to filter the logs by.
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/txe/src/oracle/txe_oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,8 @@ export class TXE implements TypedOracle {
}

txEffect.publicDataWrites = this.publicDataWrites;
txEffect.privateLogs = this.privateLogs;
txEffect.publicLogs = this.publicLogs;

const body = new Body([txEffect]);

Expand Down Expand Up @@ -771,9 +773,7 @@ export class TXE implements TypedOracle {
}
}

await this.node.setTxEffect(blockNumber, new TxHash(new Fr(blockNumber)), txEffect);
this.node.addPrivateLogsByTags(this.blockNumber, this.privateLogs);
this.node.addPublicLogsByTags(this.blockNumber, this.publicLogs);
await this.node.processTxEffect(blockNumber, new TxHash(new Fr(blockNumber)), txEffect);

const stateReference = await fork.getStateReference();
const archiveInfo = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
Expand Down