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

fix: unexpose get note nonces on pxe #7889

Merged
merged 3 commits into from
Aug 13, 2024
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
1 change: 1 addition & 0 deletions yarn-project/aztec.js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export {
EncryptedLogOutgoingBody,
EventType,
ExtendedNote,
UniqueNote,
FunctionCall,
L1Actor,
L1ToL2Message,
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/aztec.js/src/rpc_clients/pxe_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
TxHash,
TxReceipt,
UnencryptedL2BlockL2Logs,
UniqueNote,
} from '@aztec/circuit-types';
import {
AztecAddress,
Expand Down Expand Up @@ -45,6 +46,7 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], false)
FunctionSelector,
EthAddress,
ExtendedNote,
UniqueNote,
ExtendedUnencryptedL2Log,
Fr,
GrumpkinScalar,
Expand Down
9 changes: 3 additions & 6 deletions yarn-project/aztec.js/src/wallet/base_wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
type TxExecutionRequest,
type TxHash,
type TxReceipt,
type UniqueNote,
} from '@aztec/circuit-types';
import { type NoteProcessorStats } from '@aztec/circuit-types/stats';
import {
Expand Down Expand Up @@ -120,16 +121,12 @@ export abstract class BaseWallet implements Wallet {
getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
return this.pxe.getTxReceipt(txHash);
}
getIncomingNotes(filter: IncomingNotesFilter): Promise<ExtendedNote[]> {
getIncomingNotes(filter: IncomingNotesFilter): Promise<UniqueNote[]> {
return this.pxe.getIncomingNotes(filter);
}
getOutgoingNotes(filter: OutgoingNotesFilter): Promise<ExtendedNote[]> {
getOutgoingNotes(filter: OutgoingNotesFilter): Promise<UniqueNote[]> {
return this.pxe.getOutgoingNotes(filter);
}
// TODO(#4956): Un-expose this
getNoteNonces(note: ExtendedNote): Promise<Fr[]> {
return this.pxe.getNoteNonces(note);
}
getPublicStorageAt(contract: AztecAddress, storageSlot: Fr): Promise<any> {
return this.pxe.getPublicStorageAt(contract, storageSlot);
}
Expand Down
15 changes: 3 additions & 12 deletions yarn-project/circuit-types/src/interfaces/pxe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { type AuthWitness } from '../auth_witness.js';
import { type L2Block } from '../l2_block.js';
import { type GetUnencryptedLogsResponse, type L1EventPayload, type LogFilter } from '../logs/index.js';
import { type IncomingNotesFilter } from '../notes/incoming_notes_filter.js';
import { type ExtendedNote, type OutgoingNotesFilter } from '../notes/index.js';
import { type ExtendedNote, type OutgoingNotesFilter, type UniqueNote } from '../notes/index.js';
import { type NoteProcessorStats } from '../stats/stats.js';
import { type SimulatedTx, type Tx, type TxHash, type TxReceipt } from '../tx/index.js';
import { type TxEffect } from '../tx_effect.js';
Expand Down Expand Up @@ -235,23 +235,14 @@ export interface PXE {
* @param filter - The filter to apply to the notes.
* @returns The requested notes.
*/
getIncomingNotes(filter: IncomingNotesFilter): Promise<ExtendedNote[]>;
getIncomingNotes(filter: IncomingNotesFilter): Promise<UniqueNote[]>;

/**
* Gets outgoing notes of accounts registered in this PXE based on the provided filter.
* @param filter - The filter to apply to the notes.
* @returns The requested notes.
*/
getOutgoingNotes(filter: OutgoingNotesFilter): Promise<ExtendedNote[]>;

/**
* Finds the nonce(s) for a given note.
* @param note - The note to find the nonces for.
* @returns The nonces of the note.
* @remarks More than a single nonce may be returned since there might be more than one nonce for a given note.
* TODO(#4956): Un-expose this
*/
getNoteNonces(note: ExtendedNote): Promise<Fr[]>;
getOutgoingNotes(filter: OutgoingNotesFilter): Promise<UniqueNote[]>;

/**
* Adds a note to the database.
Expand Down
14 changes: 13 additions & 1 deletion yarn-project/circuit-types/src/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { Fr } from '@aztec/foundation/fields';
import { type ContractInstanceWithAddress, SerializableContractInstance } from '@aztec/types/contracts';

import { EncryptedNoteTxL2Logs, EncryptedTxL2Logs, Note, UnencryptedTxL2Logs } from './logs/index.js';
import { ExtendedNote } from './notes/index.js';
import { ExtendedNote, UniqueNote } from './notes/index.js';
import { PublicExecutionRequest } from './public_execution_request.js';
import { NestedProcessReturnValues, PublicSimulationOutput, SimulatedTx, Tx, TxHash } from './tx/index.js';

Expand Down Expand Up @@ -255,3 +255,15 @@ export const randomExtendedNote = ({
}: Partial<ExtendedNote> = {}) => {
return new ExtendedNote(note, owner, contractAddress, storageSlot, noteTypeId, txHash);
};

export const randomUniqueNote = ({
note = Note.random(),
owner = AztecAddress.random(),
contractAddress = AztecAddress.random(),
txHash = randomTxHash(),
storageSlot = Fr.random(),
noteTypeId = NoteSelector.random(),
nonce = Fr.random(),
}: Partial<UniqueNote> = {}) => {
return new UniqueNote(note, owner, contractAddress, storageSlot, noteTypeId, txHash, nonce);
};
12 changes: 10 additions & 2 deletions yarn-project/circuit-types/src/notes/extended_note.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { randomExtendedNote } from '../mocks.js';
import { ExtendedNote } from './extended_note.js';
import { randomExtendedNote, randomUniqueNote } from '../mocks.js';
import { ExtendedNote, UniqueNote } from './extended_note.js';

describe('Extended Note', () => {
it('convert to and from buffer', () => {
Expand All @@ -8,3 +8,11 @@ describe('Extended Note', () => {
expect(ExtendedNote.fromBuffer(buf)).toEqual(extendedNote);
});
});

describe('Unique Note', () => {
it('convert to and from buffer', () => {
const uniqueNote = randomUniqueNote();
const buf = uniqueNote.toBuffer();
expect(UniqueNote.fromBuffer(buf)).toEqual(uniqueNote);
});
});
52 changes: 52 additions & 0 deletions yarn-project/circuit-types/src/notes/extended_note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,55 @@ export class ExtendedNote {
return ExtendedNote.fromBuffer(Buffer.from(hex, 'hex'));
}
}

export class UniqueNote extends ExtendedNote {
constructor(
/** The note as emitted from the Noir contract. */
note: Note,
/** The owner whose public key was used to encrypt the note. */
owner: AztecAddress,
/** The contract address this note is created in. */
contractAddress: AztecAddress,
/** The specific storage location of the note on the contract. */
storageSlot: Fr,
/** The type identifier of the note on the contract. */
noteTypeId: NoteSelector,
/** The hash of the tx the note was created in. */
txHash: TxHash,
/** The nonce of the note. */
public nonce: Fr,
) {
super(note, owner, contractAddress, storageSlot, noteTypeId, txHash);
}

override toBuffer(): Buffer {
return Buffer.concat([
this.note.toBuffer(),
this.owner.toBuffer(),
this.contractAddress.toBuffer(),
this.storageSlot.toBuffer(),
this.noteTypeId.toBuffer(),
this.txHash.buffer,
this.nonce.toBuffer(),
]);
}

static override fromBuffer(buffer: Buffer | BufferReader) {
const reader = BufferReader.asReader(buffer);

const note = Note.fromBuffer(reader);
const owner = AztecAddress.fromBuffer(reader);
const contractAddress = AztecAddress.fromBuffer(reader);
const storageSlot = Fr.fromBuffer(reader);
const noteTypeId = reader.readObject(NoteSelector);
const txHash = new TxHash(reader.readBytes(TxHash.SIZE));
const nonce = Fr.fromBuffer(reader);

return new this(note, owner, contractAddress, storageSlot, noteTypeId, txHash, nonce);
}

static override fromString(str: string) {
const hex = str.replace(/^0x/, '');
return UniqueNote.fromBuffer(Buffer.from(hex, 'hex'));
}
}
6 changes: 3 additions & 3 deletions yarn-project/circuit-types/src/tx/tx_receipt.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RevertCode } from '@aztec/circuits.js';
import { type Fr } from '@aztec/foundation/fields';

import { type ExtendedNote } from '../notes/extended_note.js';
import { type UniqueNote } from '../notes/extended_note.js';
import { type PublicDataWrite } from '../public_data_write.js';
import { TxHash } from './tx_hash.js';

Expand Down Expand Up @@ -126,11 +126,11 @@ interface DebugInfo {
* in the PXE which was used to submit the tx. You will not get notes of accounts which are not registered in
* the PXE here even though they were created in this tx.
*/
visibleIncomingNotes: ExtendedNote[];
visibleIncomingNotes: UniqueNote[];
/**
* Notes created in this tx which were successfully decoded with the outgoing keys of accounts which are registered
* in the PXE which was used to submit the tx. You will not get notes of accounts which are not registered in
* the PXE here even though they were created in this tx.
*/
visibleOutgoingNotes: ExtendedNote[];
visibleOutgoingNotes: UniqueNote[];
}
28 changes: 12 additions & 16 deletions yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
PackedValues,
TxExecutionRequest,
type TxHash,
type UniqueNote,
computeSecretHash,
deriveKeys,
} from '@aztec/aztec.js';
Expand Down Expand Up @@ -180,27 +181,22 @@ describe('e2e_crowdfunding_and_claim', () => {
]);
};

// Processes extended note such that it can be passed to a claim function of Claim contract
const processExtendedNote = async (extendedNote: ExtendedNote) => {
// TODO(#4956): Make fetching the nonce manually unnecessary
// To be able to perform the inclusion proof we need to fetch the nonce of the value note
const noteNonces = await pxe.getNoteNonces(extendedNote);
expect(noteNonces?.length).toEqual(1);

// Processes unique note such that it can be passed to a claim function of Claim contract
const processUniqueNote = (uniqueNote: UniqueNote) => {
return {
header: {
// eslint-disable-next-line camelcase
contract_address: extendedNote.contractAddress,
contract_address: uniqueNote.contractAddress,
// eslint-disable-next-line camelcase
storage_slot: extendedNote.storageSlot,
storage_slot: uniqueNote.storageSlot,
// eslint-disable-next-line camelcase
note_hash_counter: 0, // set as 0 as note is not transient
nonce: noteNonces[0],
nonce: uniqueNote.nonce,
},
value: extendedNote.note.items[0],
value: uniqueNote.note.items[0],
// eslint-disable-next-line camelcase
npk_m_hash: extendedNote.note.items[1],
randomness: extendedNote.note.items[2],
npk_m_hash: uniqueNote.note.items[1],
randomness: uniqueNote.note.items[2],
};
};

Expand Down Expand Up @@ -233,7 +229,7 @@ describe('e2e_crowdfunding_and_claim', () => {
expect(notes!.length).toEqual(1);

// Set the value note in a format which can be passed to claim function
valueNote = await processExtendedNote(notes![0]);
valueNote = processUniqueNote(notes![0]);
}

// 3) We claim the reward token via the Claim contract
Expand Down Expand Up @@ -304,7 +300,7 @@ describe('e2e_crowdfunding_and_claim', () => {
expect(notes!.length).toEqual(1);

// Set the value note in a format which can be passed to claim function
const anotherDonationNote = await processExtendedNote(notes![0]);
const anotherDonationNote = processUniqueNote(notes![0]);

// We create an unrelated pxe and wallet without access to the nsk_app that correlates to the npk_m specified in the proof note.
let unrelatedWallet: AccountWallet;
Expand Down Expand Up @@ -356,7 +352,7 @@ describe('e2e_crowdfunding_and_claim', () => {
const receipt = await inclusionsProofsContract.methods.create_note(owner, 5n).send().wait({ debug: true });
const { visibleIncomingNotes } = receipt.debugInfo!;
expect(visibleIncomingNotes.length).toEqual(1);
note = await processExtendedNote(visibleIncomingNotes![0]);
note = processUniqueNote(visibleIncomingNotes![0]);
}

// 3) Test the note was included
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/pxe/src/pxe_http/pxe_http_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
TxHash,
TxReceipt,
UnencryptedL2BlockL2Logs,
UniqueNote,
} from '@aztec/circuit-types';
import { FunctionSelector } from '@aztec/circuits.js';
import { NoteSelector } from '@aztec/foundation/abi';
Expand Down Expand Up @@ -48,6 +49,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer {
GrumpkinScalar,
Note,
ExtendedNote,
UniqueNote,
AuthWitness,
L2Block,
TxEffect,
Expand Down
34 changes: 25 additions & 9 deletions yarn-project/pxe/src/pxe_service/pxe_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
EncryptedTxL2Logs,
type EventMetadata,
EventType,
ExtendedNote,
type ExtendedNote,
type FunctionCall,
type GetUnencryptedLogsResponse,
type IncomingNotesFilter,
Expand All @@ -26,6 +26,7 @@ import {
type TxHash,
type TxReceipt,
UnencryptedTxL2Logs,
UniqueNote,
isNoirCallStackUnresolved,
} from '@aztec/circuit-types';
import {
Expand Down Expand Up @@ -296,7 +297,7 @@ export class PXEService implements PXE {
return await this.node.getPublicStorageAt(contract, slot, 'latest');
}

public async getIncomingNotes(filter: IncomingNotesFilter): Promise<ExtendedNote[]> {
public async getIncomingNotes(filter: IncomingNotesFilter): Promise<UniqueNote[]> {
const noteDaos = await this.db.getIncomingNotes(filter);

// TODO(#6531): Refactor --> This type conversion is ugly but I decided to keep it this way for now because
Expand All @@ -312,12 +313,20 @@ export class PXEService implements PXE {
}
owner = completeAddresses.address;
}
return new ExtendedNote(dao.note, owner, dao.contractAddress, dao.storageSlot, dao.noteTypeId, dao.txHash);
return new UniqueNote(
dao.note,
owner,
dao.contractAddress,
dao.storageSlot,
dao.noteTypeId,
dao.txHash,
dao.nonce,
);
});
return Promise.all(extendedNotes);
}

public async getOutgoingNotes(filter: OutgoingNotesFilter): Promise<ExtendedNote[]> {
public async getOutgoingNotes(filter: OutgoingNotesFilter): Promise<UniqueNote[]> {
const noteDaos = await this.db.getOutgoingNotes(filter);

// TODO(#6532): Refactor --> This type conversion is ugly but I decided to keep it this way for now because
Expand All @@ -333,7 +342,15 @@ export class PXEService implements PXE {
}
owner = completeAddresses.address;
}
return new ExtendedNote(dao.note, owner, dao.contractAddress, dao.storageSlot, dao.noteTypeId, dao.txHash);
return new UniqueNote(
dao.note,
owner,
dao.contractAddress,
dao.storageSlot,
dao.noteTypeId,
dao.txHash,
dao.nonce,
);
});
return Promise.all(extendedNotes);
}
Expand All @@ -344,7 +361,7 @@ export class PXEService implements PXE {
throw new Error(`Unknown account: ${note.owner.toString()}`);
}

const nonces = await this.getNoteNonces(note);
const nonces = await this.#getNoteNonces(note);
if (nonces.length === 0) {
throw new Error(`Cannot find the note in tx: ${note.txHash}.`);
}
Expand Down Expand Up @@ -394,7 +411,7 @@ export class PXEService implements PXE {
throw new Error(`Unknown account: ${note.owner.toString()}`);
}

const nonces = await this.getNoteNonces(note);
const nonces = await this.#getNoteNonces(note);
if (nonces.length === 0) {
throw new Error(`Cannot find the note in tx: ${note.txHash}.`);
}
Expand Down Expand Up @@ -440,9 +457,8 @@ export class PXEService implements PXE {
* @param note - The note to find the nonces for.
* @returns The nonces of the note.
* @remarks More than a single nonce may be returned since there might be more than one nonce for a given note.
* TODO(#4956): Un-expose this
*/
public async getNoteNonces(note: ExtendedNote): Promise<Fr[]> {
async #getNoteNonces(note: ExtendedNote): Promise<Fr[]> {
const tx = await this.node.getTxEffect(note.txHash);
if (!tx) {
throw new Error(`Unknown tx: ${note.txHash}`);
Expand Down
Loading