Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Jun 4, 2024
1 parent c0ed5bd commit 3520b06
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,11 @@ export class L1NotePayload {

/**
* Create a random L1NotePayload object (useful for testing purposes).
* @param contract - The contract address to use in the payload.
* @returns A random L1NotePayload object.
*/
static random() {
return new L1NotePayload(Note.random(), AztecAddress.random(), Fr.random(), Fr.random());
static random(contract = AztecAddress.random()) {
return new L1NotePayload(Note.random(), contract, Fr.random(), Fr.random());
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
type AztecAddress,
type GrumpkinPrivateKey,
type KeyValidationRequest,
type PublicKey,
} from '@aztec/circuits.js';
import { AztecAddress, type GrumpkinPrivateKey, type KeyValidationRequest, type PublicKey } from '@aztec/circuits.js';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

Expand Down Expand Up @@ -43,8 +38,13 @@ export class TaggedNote {
return serializeToBuffer(this.incomingTag, this.outgoingTag, this.notePayload);
}

static random(): TaggedNote {
return new TaggedNote(L1NotePayload.random());
/**
* Create a random TaggedNote (useful for testing purposes).
* @param contract - The contract address to use in the payload.
* @returns A random TaggedNote object.
*/
static random(contract = AztecAddress.random()): TaggedNote {
return new TaggedNote(L1NotePayload.random(contract));
}

public encrypt(
Expand Down
66 changes: 50 additions & 16 deletions yarn-project/pxe/src/note_processor/note_processor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@ describe('Note Processor', () => {
let noteProcessor: NoteProcessor;
let keyStore: MockProxy<KeyStore>;
let simulator: MockProxy<AcirSimulator>;

const firstBlockNum = 123;
const app = AztecAddress.random();

let ownerIvskM: GrumpkinPrivateKey;
let ownerIvpkM: PublicKey;
let ownerOvskM: GrumpkinPrivateKey;
let ownerOvKeys: KeyValidationRequest;
let account: CompleteAddress;

Expand Down Expand Up @@ -114,15 +117,16 @@ describe('Note Processor', () => {
}

beforeAll(() => {
const app = AztecAddress.random();

const ownerSk = Fr.random();
const allOwnerKeys = deriveKeys(ownerSk);
const partialAddress = Fr.random();
account = CompleteAddress.fromSecretKeyAndPartialAddress(ownerSk, partialAddress);

ownerIvskM = allOwnerKeys.masterIncomingViewingSecretKey;
const allOwnerKeys = deriveKeys(ownerSk);

ownerIvpkM = allOwnerKeys.publicKeys.masterIncomingViewingPublicKey;
ownerIvskM = allOwnerKeys.masterIncomingViewingSecretKey;

ownerOvskM = allOwnerKeys.masterOutgoingViewingSecretKey;
ownerOvKeys = new KeyValidationRequest(
allOwnerKeys.publicKeys.masterOutgoingViewingPublicKey,
computeOvskApp(allOwnerKeys.masterOutgoingViewingSecretKey, app),
Expand All @@ -137,7 +141,16 @@ describe('Note Processor', () => {
keyStore = mock<KeyStore>();
simulator = mock<AcirSimulator>();

keyStore.getMasterSecretKey.mockResolvedValue(ownerIvskM);
keyStore.getMasterSecretKey.mockImplementation((pkM: PublicKey) => {
if (pkM.equals(ownerIvpkM)) {
return Promise.resolve(ownerIvskM);
}
if (pkM.equals(ownerOvKeys.pkM)) {
return Promise.resolve(ownerOvskM);
}
throw new Error(`Unknown public key: ${pkM}`);
});

keyStore.getMasterIncomingViewingPublicKey.mockResolvedValue(account.publicKeys.masterIncomingViewingPublicKey);
keyStore.getMasterOutgoingViewingPublicKey.mockResolvedValue(account.publicKeys.masterOutgoingViewingPublicKey);

Expand All @@ -164,8 +177,15 @@ describe('Note Processor', () => {
addNotesSpy.mockReset();
});

it('should store a note that belongs to us', async () => {
const request = new MockNoteRequest(TaggedNote.random(), firstBlockNum, 0, 2, ownerIvpkM, ownerOvKeys);
it('should store an incoming note that belongs to us', async () => {
const request = new MockNoteRequest(
TaggedNote.random(app),
firstBlockNum,
0,
2,
ownerIvpkM,
KeyValidationRequest.random(),
);

const blocks = mockBlocks([request], 1);

Expand All @@ -185,12 +205,26 @@ describe('Note Processor', () => {
);
}, 25_000);

it('should store an outgoing note that belongs to us', async () => {
const request = new MockNoteRequest(TaggedNote.random(app), firstBlockNum, 0, 2, Point.random(), ownerOvKeys);

const blocks = mockBlocks([request], 1);

// TODO(#6830): pass in only the blocks
const encryptedLogs = blocks.flatMap(block => block.body.noteEncryptedLogs);
await noteProcessor.process(blocks, encryptedLogs);

expect(addNotesSpy).toHaveBeenCalledTimes(1);
// For outgoing notes, the resulting DAO does not contain index.
expect(addNotesSpy).toHaveBeenCalledWith([], [expect.objectContaining(request.note.notePayload)]);
}, 25_000);

it('should store multiple notes that belong to us', async () => {
const prependedBlocks = 2;
const requests = [
new MockNoteRequest(TaggedNote.random(), firstBlockNum + prependedBlocks, 1, 1, ownerIvpkM, ownerOvKeys),
new MockNoteRequest(TaggedNote.random(), firstBlockNum + prependedBlocks, 3, 0, ownerIvpkM, ownerOvKeys),
new MockNoteRequest(TaggedNote.random(), firstBlockNum + prependedBlocks, 3, 2, ownerIvpkM, ownerOvKeys),
new MockNoteRequest(TaggedNote.random(app), firstBlockNum + prependedBlocks, 1, 1, ownerIvpkM, ownerOvKeys),
new MockNoteRequest(TaggedNote.random(app), firstBlockNum + prependedBlocks, 3, 0, ownerIvpkM, ownerOvKeys),
new MockNoteRequest(TaggedNote.random(app), firstBlockNum + prependedBlocks, 3, 2, ownerIvpkM, ownerOvKeys),
];

const blocks = mockBlocks(requests, 4);
Expand Down Expand Up @@ -226,8 +260,8 @@ describe('Note Processor', () => {
// Both notes should be ignored because the encryption keys do not belong to owner (they are random).
const blocks = mockBlocks(
[
new MockNoteRequest(TaggedNote.random(), firstBlockNum, 1, 1, Point.random(), KeyValidationRequest.random()),
new MockNoteRequest(TaggedNote.random(), firstBlockNum, 3, 0, Point.random(), KeyValidationRequest.random()),
new MockNoteRequest(TaggedNote.random(app), firstBlockNum, 1, 1, Point.random(), KeyValidationRequest.random()),
new MockNoteRequest(TaggedNote.random(app), firstBlockNum, 3, 0, Point.random(), KeyValidationRequest.random()),
],
4,
);
Expand All @@ -240,8 +274,8 @@ describe('Note Processor', () => {
});

it('should be able to recover two note payloads containing the same note', async () => {
const note = TaggedNote.random();
const note2 = TaggedNote.random();
const note = TaggedNote.random(app);
const note2 = TaggedNote.random(app);
// All note payloads except one have the same contract address, storage slot, and the actual note.
const requests = [
new MockNoteRequest(note, firstBlockNum, 0, 0, ownerIvpkM, ownerOvKeys),
Expand Down Expand Up @@ -273,7 +307,7 @@ describe('Note Processor', () => {
});

it('advances the block number', async () => {
const request = new MockNoteRequest(TaggedNote.random(), firstBlockNum, 0, 2, ownerIvpkM, ownerOvKeys);
const request = new MockNoteRequest(TaggedNote.random(app), firstBlockNum, 0, 2, ownerIvpkM, ownerOvKeys);

const blocks = mockBlocks([request], 1);

Expand All @@ -285,7 +319,7 @@ describe('Note Processor', () => {
});

it('should restore the last block number processed and ignore the starting block', async () => {
const request = new MockNoteRequest(TaggedNote.random(), firstBlockNum, 0, 2, ownerIvpkM, ownerOvKeys);
const request = new MockNoteRequest(TaggedNote.random(app), firstBlockNum, 0, 2, ownerIvpkM, ownerOvKeys);

const blocks = mockBlocks([request], 1);

Expand Down
2 changes: 1 addition & 1 deletion yarn-project/pxe/src/note_processor/note_processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export class NoteProcessor {
throw new Error('Incoming and outgoing note payloads do not match.');
}

const payload = incomingTaggedNote.notePayload || outgoingTaggedNote.notePayload;
const payload = incomingTaggedNote?.notePayload || outgoingTaggedNote?.notePayload;

const txHash = block.body.txEffects[indexOfTxInABlock].txHash;
const { incomingNote, outgoingNote, incomingDeferredNote } = await produceNoteDaos(
Expand Down

0 comments on commit 3520b06

Please sign in to comment.