Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
Initial
  • Loading branch information
sklppy88 committed Jun 10, 2024
1 parent ba4583e commit 2b319f4
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 75 deletions.
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/rpc_clients/pxe_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], false)
false,
'pxe',
fetch,
);
) as PXE;
30 changes: 28 additions & 2 deletions yarn-project/aztec.js/src/wallet/base_wallet.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
L1EventPayload,
type AuthWitness,
type ExtendedNote,
type FunctionCall,
Expand All @@ -17,8 +18,15 @@ import {
type TxReceipt,
} from '@aztec/circuit-types';
import { type NoteProcessorStats } from '@aztec/circuit-types/stats';
import { type AztecAddress, type CompleteAddress, type Fq, type Fr, type PartialAddress } from '@aztec/circuits.js';
import { type ContractArtifact } from '@aztec/foundation/abi';
import {
type AztecAddress,
type CompleteAddress,
type Fq,
type Fr,
type PartialAddress,
Point,
} from '@aztec/circuits.js';
import { FunctionSelector, type ContractArtifact } from '@aztec/foundation/abi';
import { type ContractClassWithId, type ContractInstanceWithAddress } from '@aztec/types/contracts';
import { type NodeInfo } from '@aztec/types/interfaces';

Expand Down Expand Up @@ -181,4 +189,22 @@ export abstract class BaseWallet implements Wallet {
getPXEInfo(): Promise<PXEInfo> {
return this.pxe.getPXEInfo();
}
getEvents<T>(from: number, limit: number, eventMetadata: EventMetadata<T>, ivpk: Point): Promise<T[]> {
return this.pxe.getEvents(from, limit, eventMetadata, ivpk);
}
}

/**
* A base class for Wallet implementations
*/
interface EventMetadata<T> {
/**
* A base class for Wallet implementations
* @param payload - asdf
*/
decode(payload: L1EventPayload): T | undefined;
/**
* A base class for Wallet implementations
*/
functionSelector: FunctionSelector;
}
14 changes: 9 additions & 5 deletions yarn-project/builder/src/contract-interface-gen/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,17 @@ function generateEvents(events: any[] | undefined) {
`;

const fieldNames = event.fields.map((field: any) => `"${field.name}"`);
const eventsType = `${eventName}: {decode: (payload: L1EventPayload | undefined) => ${eventName} | undefined }`;
const eventsType = `${eventName}: {decode: (payload: L1EventPayload | undefined) => ${eventName} | undefined, functionSelector: FunctionSelector, fieldNames: string[] }`;

// Get the last item in path
const eventDecode = `${event.path.split('::').at(-1)}: {
decode: this.decodeEvent(${event.fields.length}, '${eventName}(${event.fields
decode: this.decodeEvent(${event.fields.length}, FunctionSelector.fromSignature('${eventName}(${event.fields
.map(() => 'Field')
.join(',')})', [${fieldNames}])
.join(',')})'), [${fieldNames}]),
functionSelector: FunctionSelector.fromSignature('${eventName}(${event.fields
.map(() => 'Field')
.join(',')})'),
fieldNames: [${fieldNames}],
}`;

return {
Expand All @@ -276,13 +280,13 @@ function generateEvents(events: any[] | undefined) {
eventDefs: eventsStrings.map(({ eventDefs }) => eventDefs).join('\n'),
events: `
// Partial application is chosen is to avoid the duplication of so much codegen.
private static decodeEvent<T>(fieldsLength: number, functionSignature: string, fields: string[]): (payload: L1EventPayload | undefined) => T | undefined {
private static decodeEvent<T>(fieldsLength: number, functionSelector: FunctionSelector, fields: string[]): (payload: L1EventPayload | undefined) => T | undefined {
return (payload: L1EventPayload | undefined): T | undefined => {
if (payload === undefined) {
return undefined;
}
if (
!FunctionSelector.fromSignature(functionSignature).equals(
!functionSelector.equals(
FunctionSelector.fromField(payload.eventTypeId),
)
) {
Expand Down
20 changes: 17 additions & 3 deletions yarn-project/circuit-types/src/interfaces/pxe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { type AztecAddress, type CompleteAddress, type Fq, type Fr, type PartialAddress } from '@aztec/circuits.js';
import { type ContractArtifact } from '@aztec/foundation/abi';
import {
type AztecAddress,
type CompleteAddress,
type Fq,
type Fr,
type PartialAddress,
Point,
} from '@aztec/circuits.js';
import { FunctionSelector, type ContractArtifact } from '@aztec/foundation/abi';
import {
type ContractClassWithId,
type ContractInstanceWithAddress,
Expand All @@ -9,7 +16,7 @@ import { type NodeInfo } from '@aztec/types/interfaces';

import { type AuthWitness } from '../auth_witness.js';
import { type L2Block } from '../l2_block.js';
import { type GetUnencryptedLogsResponse, type LogFilter } from '../logs/index.js';
import { L1EventPayload, type GetUnencryptedLogsResponse, type LogFilter } from '../logs/index.js';
import { type ExtendedNote } from '../notes/index.js';
import { type NoteFilter } from '../notes/note_filter.js';
import { type NoteProcessorStats } from '../stats/stats.js';
Expand Down Expand Up @@ -355,9 +362,16 @@ export interface PXE {
* TODO(@spalladino): Same notes as above.
*/
isContractPubliclyDeployed(address: AztecAddress): Promise<boolean>;

getEvents<T>(from: number, limit: number, eventMetadata: EventMetadata<T>, ivpk: Point): Promise<T[]>;
}
// docs:end:pxe-interface

interface EventMetadata<T> {
decode(payload: L1EventPayload): T | undefined;
functionSelector: FunctionSelector;
}

/**
* Provides basic information about the running PXE.
*/
Expand Down
155 changes: 92 additions & 63 deletions yarn-project/end-to-end/src/e2e_event_logs.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { type AccountWalletWithSecretKey, type AztecNode, Fr, L1EventPayload, TaggedLog } from '@aztec/aztec.js';
import { type AccountWalletWithSecretKey, type AztecNode, Fr, L1EventPayload, TaggedLog, PXE } from '@aztec/aztec.js';
import { deriveMasterIncomingViewingSecretKey } from '@aztec/circuits.js';
import { makeTuple } from '@aztec/foundation/array';
import { TestLogContract } from '@aztec/noir-contracts.js';

import { jest } from '@jest/globals';

import { publicDeployAccounts, setup } from './fixtures/utils.js';
import { Tuple } from '@aztec/foundation/serialize';

const TIMEOUT = 120_000;

Expand All @@ -15,11 +16,12 @@ describe('Logs', () => {

let wallets: AccountWalletWithSecretKey[];
let node: AztecNode;
let pxe: PXE;

let teardown: () => Promise<void>;

beforeAll(async () => {
({ teardown, wallets, aztecNode: node } = await setup(2));
({ teardown, wallets, aztecNode: node, pxe } = await setup(2));

await publicDeployAccounts(wallets[0], wallets.slice(0, 2));

Expand All @@ -29,86 +31,113 @@ describe('Logs', () => {
afterAll(() => teardown());

describe('functionality around emitting an encrypted log', () => {
it('emits a generic encrypted log and checks for correctness', async () => {
const randomness = Fr.random();
const eventTypeId = Fr.random();
const preimage = makeTuple(6, Fr.random);
// it('emits a generic encrypted log and checks for correctness', async () => {
// const randomness = Fr.random();
// const eventTypeId = Fr.random();
// const preimage = makeTuple(6, Fr.random);

const tx = await testLogContract.methods.emit_encrypted_log(randomness, eventTypeId, preimage).send().wait();
// const tx = await testLogContract.methods.emit_encrypted_log(randomness, eventTypeId, preimage).send().wait();

const txEffect = await node.getTxEffect(tx.txHash);
// const txEffect = await node.getTxEffect(tx.txHash);

const encryptedLogs = txEffect!.encryptedLogs.unrollLogs();
expect(encryptedLogs.length).toBe(1);
// const encryptedLogs = txEffect!.encryptedLogs.unrollLogs();
// expect(encryptedLogs.length).toBe(1);

const decryptedLog = TaggedLog.decryptAsIncoming(
encryptedLogs[0],
deriveMasterIncomingViewingSecretKey(wallets[0].getSecretKey()),
L1EventPayload,
);
// const decryptedLog = TaggedLog.decryptAsIncoming(
// encryptedLogs[0],
// deriveMasterIncomingViewingSecretKey(wallets[0].getSecretKey()),
// L1EventPayload,
// );

expect(decryptedLog?.payload.contractAddress).toStrictEqual(testLogContract.address);
expect(decryptedLog?.payload.randomness).toStrictEqual(randomness);
expect(decryptedLog?.payload.eventTypeId).toStrictEqual(eventTypeId);
expect(decryptedLog?.payload.event.items).toStrictEqual(preimage);
});
// expect(decryptedLog?.payload.contractAddress).toStrictEqual(testLogContract.address);
// expect(decryptedLog?.payload.randomness).toStrictEqual(randomness);
// expect(decryptedLog?.payload.eventTypeId).toStrictEqual(eventTypeId);
// expect(decryptedLog?.payload.event.items).toStrictEqual(preimage);
// });

it('emits multiple events as encrypted logs and decodes them', async () => {
const randomness = makeTuple(2, Fr.random);
const preimage = makeTuple(4, Fr.random);
// it('emits multiple events as encrypted logs and decodes them', async () => {
// const randomness = makeTuple(2, Fr.random);
// const preimage = makeTuple(4, Fr.random);

const tx = await testLogContract.methods.emit_encrypted_events(randomness, preimage).send().wait();
// const tx = await testLogContract.methods.emit_encrypted_events(randomness, preimage).send().wait();

const txEffect = await node.getTxEffect(tx.txHash);
// const txEffect = await node.getTxEffect(tx.txHash);

const encryptedLogs = txEffect!.encryptedLogs.unrollLogs();
expect(encryptedLogs.length).toBe(2);
// const encryptedLogs = txEffect!.encryptedLogs.unrollLogs();
// expect(encryptedLogs.length).toBe(2);

const decryptedLog0 = TaggedLog.decryptAsIncoming(
encryptedLogs[0],
deriveMasterIncomingViewingSecretKey(wallets[0].getSecretKey()),
L1EventPayload,
);
// const decryptedLog0 = TaggedLog.decryptAsIncoming(
// encryptedLogs[0],
// deriveMasterIncomingViewingSecretKey(wallets[0].getSecretKey()),
// L1EventPayload,
// );

expect(decryptedLog0?.payload.contractAddress).toStrictEqual(testLogContract.address);
expect(decryptedLog0?.payload.randomness).toStrictEqual(randomness[0]);
expect(decryptedLog0?.payload.eventTypeId).toStrictEqual(
new Fr(0x00000000000000000000000000000000000000000000000000000000aa533f60),
);
// expect(decryptedLog0?.payload.contractAddress).toStrictEqual(testLogContract.address);
// expect(decryptedLog0?.payload.randomness).toStrictEqual(randomness[0]);
// expect(decryptedLog0?.payload.eventTypeId).toStrictEqual(
// new Fr(0x00000000000000000000000000000000000000000000000000000000aa533f60),
// );

// We decode our event into the event type
const event0 = TestLogContract.events.ExampleEvent0.decode(decryptedLog0!.payload);
// // We decode our event into the event type
// const event0 = TestLogContract.events.ExampleEvent0.decode(decryptedLog0!.payload);

// We check that the event was decoded correctly
expect(event0?.value0).toStrictEqual(preimage[0]);
expect(event0?.value1).toStrictEqual(preimage[1]);
// // We check that the event was decoded correctly
// expect(event0?.value0).toStrictEqual(preimage[0]);
// expect(event0?.value1).toStrictEqual(preimage[1]);

// We check that an event that does not match, is not decoded correctly due to an event type id mismatch
const badEvent0 = TestLogContract.events.ExampleEvent1.decode(decryptedLog0!.payload);
expect(badEvent0).toBe(undefined);
// // We check that an event that does not match, is not decoded correctly due to an event type id mismatch
// const badEvent0 = TestLogContract.events.ExampleEvent1.decode(decryptedLog0!.payload);
// expect(badEvent0).toBe(undefined);

const decryptedLog1 = TaggedLog.decryptAsIncoming(
encryptedLogs[1],
deriveMasterIncomingViewingSecretKey(wallets[0].getSecretKey()),
L1EventPayload,
);
// const decryptedLog1 = TaggedLog.decryptAsIncoming(
// encryptedLogs[1],
// deriveMasterIncomingViewingSecretKey(wallets[0].getSecretKey()),
// L1EventPayload,
// );

expect(decryptedLog1?.payload.contractAddress).toStrictEqual(testLogContract.address);
expect(decryptedLog1?.payload.randomness).toStrictEqual(randomness[1]);
expect(decryptedLog1?.payload.eventTypeId).toStrictEqual(
new Fr(0x00000000000000000000000000000000000000000000000000000000d1be0447),
);
// expect(decryptedLog1?.payload.contractAddress).toStrictEqual(testLogContract.address);
// expect(decryptedLog1?.payload.randomness).toStrictEqual(randomness[1]);
// expect(decryptedLog1?.payload.eventTypeId).toStrictEqual(
// new Fr(0x00000000000000000000000000000000000000000000000000000000d1be0447),
// );

// We check our second event, which is a different type
const event1 = TestLogContract.events.ExampleEvent1.decode(decryptedLog1!.payload);
// // We check our second event, which is a different type
// const event1 = TestLogContract.events.ExampleEvent1.decode(decryptedLog1!.payload);

// We expect the fields to have been populated correctly
expect(event1?.value2).toStrictEqual(preimage[2]);
expect(event1?.value3).toStrictEqual(preimage[3]);
// // We expect the fields to have been populated correctly
// expect(event1?.value2).toStrictEqual(preimage[2]);
// expect(event1?.value3).toStrictEqual(preimage[3]);

// // Again, trying to decode another event with mismatching data does not yield anything
// const badEvent1 = TestLogContract.events.ExampleEvent1.decode(decryptedLog0!.payload);
// expect(badEvent1).toBe(undefined);
// });

it('emits multiple events as encrypted logs and decodes them', async () => {
const randomness = makeTuple(5, makeTuple.bind(undefined, 2, Fr.random)) as Tuple<Tuple<Fr, 2>, 5>;
const preimage = makeTuple(5, makeTuple.bind(undefined, 4, Fr.random)) as Tuple<Tuple<Fr, 4>, 5>;

let i = 0;
const firstTx = await testLogContract.methods.emit_encrypted_events(randomness[i], preimage[i]).send().wait();
await Promise.all([...new Array(3)].map(() => testLogContract.methods.emit_encrypted_events(randomness[++i], preimage[i]).send().wait()));
const lastTx = await testLogContract.methods.emit_encrypted_events(randomness[++i], preimage[i]).send().wait();

const collectedEvent0s = await pxe.getEvents(
firstTx.blockNumber!,
lastTx.blockNumber! - firstTx.blockNumber! + 1,
TestLogContract.events.ExampleEvent0,
wallets[0].getCompleteAddress().publicKeys.masterIncomingViewingPublicKey,
);

const collectedEvent1s = await pxe.getEvents(
firstTx.blockNumber!,
lastTx.blockNumber! - firstTx.blockNumber! + 1,
TestLogContract.events.ExampleEvent1,
wallets[0].getCompleteAddress().publicKeys.masterIncomingViewingPublicKey,
);

// Again, trying to decode another event with mismatching data does not yield anything
const badEvent1 = TestLogContract.events.ExampleEvent0.decode(decryptedLog1!.payload);
expect(badEvent1).toBe(undefined);
console.log(collectedEvent0s);
console.log(collectedEvent1s);
});
});
});
Loading

0 comments on commit 2b319f4

Please sign in to comment.