Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Oct 21, 2024
1 parent fa7d572 commit 384a241
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { NoteSelector } from '@aztec/foundation/abi';
import { type Fq, Fr } from '@aztec/foundation/fields';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

import { type EncryptedL2NoteLog } from '../encrypted_l2_note_log.js';
import { EncryptedLogPayload } from './encrypted_log_payload.js';
import { Note } from './payload.js';

Expand Down Expand Up @@ -51,8 +50,8 @@ export class L1NotePayload {
}
}

static decryptAsIncoming(log: EncryptedL2NoteLog, sk: Fq): L1NotePayload | undefined {
const decryptedLog = EncryptedLogPayload.decryptAsIncoming(log.data, sk);
static decryptAsIncoming(log: Buffer, sk: Fq): L1NotePayload | undefined {
const decryptedLog = EncryptedLogPayload.decryptAsIncoming(log, sk);
if (!decryptedLog) {
return undefined;
}
Expand All @@ -63,8 +62,8 @@ export class L1NotePayload {
);
}

static decryptAsOutgoing(log: EncryptedL2NoteLog, sk: Fq): L1NotePayload | undefined {
const decryptedLog = EncryptedLogPayload.decryptAsOutgoing(log.data, sk);
static decryptAsOutgoing(log: Buffer, sk: Fq): L1NotePayload | undefined {
const decryptedLog = EncryptedLogPayload.decryptAsOutgoing(log, sk);
if (!decryptedLog) {
return undefined;
}
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/e2e_block_building.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ describe('e2e_block_building', () => {
// compare logs
expect(rct.status).toEqual('success');
const noteValues = tx.noteEncryptedLogs.unrollLogs().map(l => {
const notePayload = L1NotePayload.decryptAsIncoming(l, keys.masterIncomingViewingSecretKey);
const notePayload = L1NotePayload.decryptAsIncoming(l.data, keys.masterIncomingViewingSecretKey);
return notePayload?.note.items[0];
});
expect(noteValues[0]).toEqual(new Fr(10));
Expand Down
144 changes: 91 additions & 53 deletions yarn-project/pxe/src/note_processor/note_processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ export class NoteProcessor {
// Iterate over both blocks and encrypted logs.
for (const block of blocks) {
this.stats.blocks++;
const { txLogs } = block.body.noteEncryptedLogs;
const { txLogs: encryptedTxLogs } = block.body.noteEncryptedLogs;
const { txLogs: unencryptedTxLogs } = block.body.unencryptedLogs;

const dataStartIndexForBlock =
block.header.state.partial.noteHashTree.nextAvailableLeafIndex -
block.body.numberOfTxsIncludingPadded * MAX_NOTE_HASHES_PER_TX;
Expand All @@ -131,65 +133,73 @@ export class NoteProcessor {
const outgoingNotes: OutgoingNoteDao[] = [];

// Iterate over all the encrypted logs and try decrypting them. If successful, store the note.
for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) {
for (let indexOfTxInABlock = 0; indexOfTxInABlock < encryptedTxLogs.length; ++indexOfTxInABlock) {
this.stats.txs++;
const dataStartIndexForTx = dataStartIndexForBlock + indexOfTxInABlock * MAX_NOTE_HASHES_PER_TX;
const noteHashes = block.body.txEffects[indexOfTxInABlock].noteHashes;
// Note: Each tx generates a `TxL2Logs` object and for this reason we can rely on its index corresponding
// to the index of a tx in a block.
const txFunctionLogs = txLogs[indexOfTxInABlock].functionLogs;
const encryptedTxFunctionLogs = encryptedTxLogs[indexOfTxInABlock].functionLogs;
const unencryptedTxFunctionLogs = unencryptedTxLogs[indexOfTxInABlock].functionLogs;
const excludedIndices: Set<number> = new Set();
for (const functionLogs of txFunctionLogs) {
for (const log of functionLogs.logs) {
this.stats.seen++;
const incomingNotePayload = L1NotePayload.decryptAsIncoming(log, ivskM);
const outgoingNotePayload = L1NotePayload.decryptAsOutgoing(log, ovskM);

if (incomingNotePayload || outgoingNotePayload) {
if (incomingNotePayload && outgoingNotePayload && !incomingNotePayload.equals(outgoingNotePayload)) {
throw new Error(
`Incoming and outgoing note payloads do not match. Incoming: ${JSON.stringify(
incomingNotePayload,
)}, Outgoing: ${JSON.stringify(outgoingNotePayload)}`,
);
}

const payload = incomingNotePayload || outgoingNotePayload;

const txEffect = block.body.txEffects[indexOfTxInABlock];
const { incomingNote, outgoingNote, incomingDeferredNote, outgoingDeferredNote } = await produceNoteDaos(
this.simulator,
this.db,
incomingNotePayload ? this.ivpkM : undefined,
outgoingNotePayload ? this.ovpkM : undefined,
payload!,
txEffect.txHash,
noteHashes,
dataStartIndexForTx,
excludedIndices,
this.log,
txEffect.unencryptedLogs,
);

if (incomingNote) {
incomingNotes.push(incomingNote);
this.stats.decryptedIncoming++;
}
if (outgoingNote) {
outgoingNotes.push(outgoingNote);
this.stats.decryptedOutgoing++;
}
if (incomingDeferredNote) {
deferredIncomingNotes.push(incomingDeferredNote);
this.stats.deferredIncoming++;
}
if (outgoingDeferredNote) {
deferredOutgoingNotes.push(outgoingDeferredNote);
this.stats.deferredOutgoing++;
}

if (incomingNote == undefined && outgoingNote == undefined && incomingDeferredNote == undefined) {
this.stats.failed++;
// We iterate over both encrypted and unencrypted logs to decrypt the notes since partial notes are passed via
// via the unencrypted logs stream.
for (const txFunctionLogs of [encryptedTxFunctionLogs, unencryptedTxFunctionLogs]) {
for (const functionLogs of txFunctionLogs) {
for (const unprocessedLog of functionLogs.logs) {
const log = removePaddingBytes(unprocessedLog.data);
this.stats.seen++;
const incomingNotePayload = L1NotePayload.decryptAsIncoming(log, ivskM);
const outgoingNotePayload = L1NotePayload.decryptAsOutgoing(log, ovskM);

if (incomingNotePayload || outgoingNotePayload) {
if (incomingNotePayload && outgoingNotePayload && !incomingNotePayload.equals(outgoingNotePayload)) {
throw new Error(
`Incoming and outgoing note payloads do not match. Incoming: ${JSON.stringify(
incomingNotePayload,
)}, Outgoing: ${JSON.stringify(outgoingNotePayload)}`,
);
}

const payload = incomingNotePayload || outgoingNotePayload;

const txEffect = block.body.txEffects[indexOfTxInABlock];
const { incomingNote, outgoingNote, incomingDeferredNote, outgoingDeferredNote } =
await produceNoteDaos(
this.simulator,
this.db,
incomingNotePayload ? this.ivpkM : undefined,
outgoingNotePayload ? this.ovpkM : undefined,
payload!,
txEffect.txHash,
noteHashes,
dataStartIndexForTx,
excludedIndices,
this.log,
txEffect.unencryptedLogs,
);

if (incomingNote) {
incomingNotes.push(incomingNote);
this.stats.decryptedIncoming++;
}
if (outgoingNote) {
outgoingNotes.push(outgoingNote);
this.stats.decryptedOutgoing++;
}
if (incomingDeferredNote) {
deferredIncomingNotes.push(incomingDeferredNote);
this.stats.deferredIncoming++;
}
if (outgoingDeferredNote) {
deferredOutgoingNotes.push(outgoingDeferredNote);
this.stats.deferredOutgoing++;
}

if (incomingNote == undefined && outgoingNote == undefined && incomingDeferredNote == undefined) {
this.stats.failed++;
}
}
}
}
Expand Down Expand Up @@ -352,3 +362,31 @@ export class NoteProcessor {
return { incomingNotes, outgoingNotes };
}
}

/**
* When a log is emitted via the unencrypted log channel each field contains only 1 byte. OTOH when a log is emitted
* via the encrypted log channel there are no empty bytes. This function removes the padding bytes.
* @param unprocessedLog
* @returns Log with padding bytes removed.
*/
function removePaddingBytes(unprocessedLog: Buffer) {
if (unprocessedLog.length === 640160) {
// I have no idea what this log is.
return unprocessedLog;
}

// Determine whether first 31 bytes of each 32 bytes block of bytes are 0
const is1FieldPerByte = unprocessedLog.every((byte, index) => index % 32 === 31 || byte === 0);

if (is1FieldPerByte) {
// We take every 32nd byte from the log and return the result
const processedLog = Buffer.alloc(unprocessedLog.length / 32);
for (let i = 0; i < processedLog.length; i++) {
processedLog[i] = unprocessedLog[31 + i * 32];
}

return processedLog;
}

return unprocessedLog;
}

0 comments on commit 384a241

Please sign in to comment.