Skip to content

Commit

Permalink
Fix for parsing coerced schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
spalladino committed Nov 5, 2024
1 parent 93f6975 commit 7c88435
Show file tree
Hide file tree
Showing 43 changed files with 844 additions and 145 deletions.
13 changes: 13 additions & 0 deletions yarn-project/circuit-types/src/body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
import { computeUnbalancedMerkleRoot } from '@aztec/foundation/trees';

import { inspect } from 'util';
import { z } from 'zod';

export class Body {
constructor(public txEffects: TxEffect[]) {
Expand All @@ -18,6 +19,18 @@ export class Body {
});
}

static get schema() {
return z
.object({
txEffects: z.array(TxEffect.schema),
})
.transform(({ txEffects }) => new Body(txEffects));
}

toJSON() {
return { txEffects: this.txEffects };
}

/**
* Serializes a block body
* @returns A serialized L2 block body.
Expand Down
168 changes: 168 additions & 0 deletions yarn-project/circuit-types/src/interfaces/archiver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import {
AztecAddress,
ContractClassPublic,
ContractClassPublicSchema,
ContractDataSource,
ContractInstanceWithAddress,
EthAddress,
Fr,
FunctionSelector,
Header,
PublicFunction,
PublicFunctionSchema,
} from '@aztec/circuits.js';
import { ContractArtifact } from '@aztec/foundation/abi';
import { ApiSchemaFor, schemas } from '@aztec/foundation/schemas';

import { z } from 'zod';

import { L2Block } from '../l2_block.js';
import { L2BlockSource, L2Tips, L2TipsSchema } from '../l2_block_source.js';
import { EncryptedL2NoteLog } from '../logs/encrypted_l2_note_log.js';
import { GetUnencryptedLogsResponse, GetUnencryptedLogsResponseSchema } from '../logs/get_unencrypted_logs_response.js';
import { L2BlockL2Logs } from '../logs/l2_block_l2_logs.js';
import { L2LogsSource } from '../logs/l2_logs_source.js';
import { LogFilter, LogFilterSchema } from '../logs/log_filter.js';
import { FromLogType, LogType } from '../logs/log_type.js';
import { L1ToL2MessageSource } from '../messaging/l1_to_l2_message_source.js';
import { TxHash } from '../tx/tx_hash.js';
import { TxReceipt } from '../tx/tx_receipt.js';
import { TxEffect } from '../tx_effect.js';

export type ArchiverApi = Omit<
L2BlockSource & L2LogsSource & ContractDataSource & L1ToL2MessageSource,
'start' | 'stop'
>;

class Foo implements ArchiveSource {
getRollupAddress(): Promise<EthAddress> {
throw new Error('Method not implemented.');
}
getRegistryAddress(): Promise<EthAddress> {
throw new Error('Method not implemented.');
}
getBlockNumber(): Promise<number>;
getBlockNumber(): Promise<number> {
throw new Error('Method not implemented.');
}
getProvenBlockNumber(): Promise<number> {
throw new Error('Method not implemented.');
}
getProvenL2EpochNumber(): Promise<number | undefined> {
throw new Error('Method not implemented.');
}
getBlock(number: number): Promise<L2Block | undefined> {
throw new Error('Method not implemented.');
}
getBlockHeader(number: number | 'latest'): Promise<Header | undefined> {
throw new Error('Method not implemented.');
}
getBlocks(from: number, limit: number, proven?: boolean | undefined): Promise<L2Block[]> {
throw new Error('Method not implemented.');
}
getTxEffect(txHash: TxHash): Promise<TxEffect | undefined> {
throw new Error('Method not implemented.');
}
getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined> {
throw new Error('Method not implemented.');
}
getL2SlotNumber(): Promise<bigint> {
throw new Error('Method not implemented.');
}
getL2EpochNumber(): Promise<bigint> {
throw new Error('Method not implemented.');
}
getBlocksForEpoch(epochNumber: bigint): Promise<L2Block[]> {
throw new Error('Method not implemented.');
}
isEpochComplete(epochNumber: bigint): Promise<boolean> {
throw new Error('Method not implemented.');
}
getL2Tips(): Promise<L2Tips> {
throw new Error('Method not implemented.');
}
start(blockUntilSynced: boolean): Promise<void> {
throw new Error('Method not implemented.');
}
stop(): Promise<void> {
throw new Error('Method not implemented.');
}
getLogs<TLogType extends LogType>(
from: number,
limit: number,
logType: TLogType,
): Promise<L2BlockL2Logs<FromLogType<TLogType>>[]> {
throw new Error('Method not implemented.');
}
getLogsByTags(tags: Fr[]): Promise<EncryptedL2NoteLog[][]> {
throw new Error('Method not implemented.');
}
getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse> {
throw new Error('Method not implemented.');
}
getPublicFunction(address: AztecAddress, selector: FunctionSelector): Promise<PublicFunction | undefined> {
throw new Error('Method not implemented.');
}
getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
throw new Error('Method not implemented.');
}
getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
throw new Error('Method not implemented.');
}
getContractClassIds(): Promise<Fr[]> {
throw new Error('Method not implemented.');
}
getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
throw new Error('Method not implemented.');
}
addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
throw new Error('Method not implemented.');
}
getL1ToL2Messages(blockNumber: bigint): Promise<Fr[]> {
throw new Error('Method not implemented.');
}
getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined> {
throw new Error('Method not implemented.');
}
}

export const ArchiverApiSchema: ApiSchemaFor<ArchiverApi> = {
getRollupAddress: z.function().args().returns(schemas.EthAddress),
getRegistryAddress: z.function().args().returns(schemas.EthAddress),
getBlockNumber: z.function().args().returns(schemas.Integer),
getProvenBlockNumber: z.function().args().returns(schemas.Integer),
getProvenL2EpochNumber: z.function().args().returns(schemas.Integer.optional()),
getBlock: z.function().args(schemas.Integer).returns(L2Block.schema.optional()),
getBlockHeader: z
.function()
.args(z.union([schemas.Integer, z.literal('latest')]))
.returns(Header.schema.optional()),
getBlocks: z
.function()
.args(schemas.Integer, schemas.Integer, z.boolean().optional())
.returns(z.array(L2Block.schema)),
getTxEffect: z.function().args(TxHash.schema).returns(TxEffect.schema.optional()),
getSettledTxReceipt: z.function().args(TxHash.schema).returns(TxReceipt.schema.optional()),
getL2SlotNumber: z.function().args().returns(schemas.BigInt),
getL2EpochNumber: z.function().args().returns(schemas.BigInt),
getBlocksForEpoch: z.function().args(schemas.BigInt).returns(z.array(L2Block.schema)),
isEpochComplete: z.function().args(schemas.BigInt).returns(z.boolean()),
getL2Tips: z.function().args().returns(L2TipsSchema),
getLogs: z.function().args(schemas.Integer, schemas.Integer, LogTypeSchema).returns(z.array(L2BlockL2LogsSchema)),
getLogsByTags: z
.function()
.args(z.array(schemas.Fr))
.returns(z.array(z.array(EncryptedL2NoteLog.schema))),
getUnencryptedLogs: z.function().args(LogFilterSchema).returns(GetUnencryptedLogsResponseSchema),
getPublicFunction: z
.function()
.args(schemas.AztecAddress, schemas.FunctionSelector)
.returns(PublicFunctionSchema.optional()),
getContractClass: z.function().args(schemas.Fr).returns(ContractClassPublicSchema.optional()),
getContract: z.function().args(schemas.AztecAddress).returns(ContractInstanceWithAddressSchema.optional()),
getContractClassIds: z.function().args().returns(z.array(schemas.Fr)),
getContractArtifact: z.function().args(schemas.AztecAddress).returns(ContractArtifactSchema.optional()),
addContractArtifact: z.function().args(schemas.AztecAddress, ContractArtifactSchema).returns(z.void()),
getL1ToL2Messages: z.function().args(schemas.BigInt).returns(z.array(schemas.Fr)),
getL1ToL2MessageIndex: z.function().args(schemas.Fr).returns(schemas.BigInt.optional()),
};
20 changes: 20 additions & 0 deletions yarn-project/circuit-types/src/l2_block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { sha256, sha256ToField } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

import { z } from 'zod';

import { makeAppendOnlyTreeSnapshot, makeHeader } from './l2_block_code_to_purge.js';

/**
Expand All @@ -19,6 +21,24 @@ export class L2Block {
public body: Body,
) {}

static get schema() {
return z
.object({
archive: AppendOnlyTreeSnapshot.schema,
header: Header.schema,
body: Body.schema,
})
.transform(({ archive, header, body }) => new L2Block(archive, header, body));
}

toJSON() {
return {
archive: this.archive,
header: this.header,
body: this.body,
};
}

/**
* Deserializes a block from a buffer
* @returns A deserialized L2 block.
Expand Down
31 changes: 20 additions & 11 deletions yarn-project/circuit-types/src/l2_block_source.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { type EthAddress, type Header } from '@aztec/circuits.js';

import { z } from 'zod';

import { type L2Block } from './l2_block.js';
import { type TxHash } from './tx/tx_hash.js';
import { type TxReceipt } from './tx/tx_receipt.js';
Expand Down Expand Up @@ -130,14 +132,21 @@ export type L2BlockTag = 'latest' | 'proven' | 'finalized';
export type L2Tips = Record<L2BlockTag, L2BlockId>;

/** Identifies a block by number and hash. */
export type L2BlockId =
| {
number: 0;
hash: undefined;
}
| {
/** L2 block number. */
number: number;
/** L2 block hash. */
hash: string;
};
export type L2BlockId = z.infer<typeof L2BlockIdSchema>;

const L2BlockIdSchema = z.union([
z.object({
number: z.literal(0),
hash: z.undefined(),
}),
z.object({
number: z.number(),
hash: z.string(),
}),
]);

export const L2TipsSchema = z.object({
latest: L2BlockIdSchema,
proven: L2BlockIdSchema,
finalized: L2BlockIdSchema,
}) satisfies z.ZodType<L2Tips>;
11 changes: 11 additions & 0 deletions yarn-project/circuit-types/src/logs/encrypted_l2_note_log.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Fr, Point } from '@aztec/circuits.js';
import { randomBytes, sha256Trunc } from '@aztec/foundation/crypto';
import { schemas } from '@aztec/foundation/schemas';

import { z } from 'zod';

/**
* Represents an individual encrypted log entry.
Expand Down Expand Up @@ -29,6 +32,14 @@ export class EncryptedL2NoteLog {
};
}

static get schema() {
return z
.object({
data: schemas.HexString,
})
.transform(({ data }) => new EncryptedL2NoteLog(Buffer.from(data, 'hex')));
}

/** Converts a plain JSON object into an instance. */
public static fromJSON(obj: any) {
return new EncryptedL2NoteLog(Buffer.from(obj.data, 'hex'));
Expand Down
19 changes: 19 additions & 0 deletions yarn-project/circuit-types/src/logs/extended_unencrypted_l2_log.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BufferReader } from '@aztec/foundation/serialize';
import { type FieldsOf } from '@aztec/foundation/types';

import isEqual from 'lodash.isequal';
import { z } from 'zod';

import { LogId } from './log_id.js';
import { UnencryptedL2Log } from './unencrypted_l2_log.js';
Expand All @@ -16,6 +18,23 @@ export class ExtendedUnencryptedL2Log {
public readonly log: UnencryptedL2Log,
) {}

toJSON() {
return { id: this.id, log: this.log };
}

static get schema() {
return z
.object({
id: LogId.schema,
log: UnencryptedL2Log.schema,
})
.transform(ExtendedUnencryptedL2Log.from);
}

static from(fields: FieldsOf<ExtendedUnencryptedL2Log>) {
return new ExtendedUnencryptedL2Log(fields.id, fields.log);
}

/**
* Serializes log to a buffer.
* @returns A buffer containing the serialized log.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { type ExtendedUnencryptedL2Log } from './extended_unencrypted_l2_log.js';
import { z } from 'zod';

/**
* It provides documentation for the GetUnencryptedLogsResponse type.
*/
import { ExtendedUnencryptedL2Log } from './extended_unencrypted_l2_log.js';

/** Response for the getUnencryptedLogs archiver call. */
export type GetUnencryptedLogsResponse = {
/**
* An array of ExtendedUnencryptedL2Log elements.
*/
/** An array of ExtendedUnencryptedL2Log elements. */
logs: ExtendedUnencryptedL2Log[];

/**
* Indicates if a limit has been reached.
*/
/** Indicates if a limit has been reached. */
maxLogsHit: boolean;
};

export const GetUnencryptedLogsResponseSchema = z.object({
logs: z.array(ExtendedUnencryptedL2Log.schema),
maxLogsHit: z.boolean(),
}) satisfies z.ZodType<GetUnencryptedLogsResponse, any, any>;
15 changes: 13 additions & 2 deletions yarn-project/circuit-types/src/logs/log_filter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { type AztecAddress } from '@aztec/circuits.js';
import { schemas } from '@aztec/foundation/schemas';

import { type TxHash } from '../tx/tx_hash.js';
import { type LogId } from './log_id.js';
import { z } from 'zod';

import { TxHash } from '../tx/tx_hash.js';
import { LogId } from './log_id.js';

/**
* Log filter used to fetch L2 logs.
Expand All @@ -19,3 +22,11 @@ export type LogFilter = {
/** The contract address to filter logs by. */
contractAddress?: AztecAddress;
};

export const LogFilterSchema = z.object({
txHash: TxHash.schema.optional(),
fromBlock: schemas.Integer.optional(),
toBlock: schemas.Integer.optional(),
afterLog: LogId.schema.optional(),
contractAddress: schemas.AztecAddress.optional(),
});
Loading

0 comments on commit 7c88435

Please sign in to comment.