From d5d0773916ff45ef1e5d2d96a0d9a163c9a98dd7 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 13 Nov 2024 16:24:37 -0300 Subject: [PATCH] chore: Delete old serialization methods Cleans up several toJSON and fromJSON methods that are no longer needed since we moved to schemas. Also drops hex serialization for most complex entities, such as circuit inputs and outputs, and replaces it with base64. --- .../archiver/kv_archiver_store/block_store.ts | 4 +- .../memory_archiver_store.ts | 3 +- .../archiver/src/test/mock_l2_block_source.ts | 12 +- .../aztec-node/src/aztec-node/server.test.ts | 2 + yarn-project/bot/src/factory.ts | 6 +- .../circuit-types/src/auth_witness.ts | 6 +- yarn-project/circuit-types/src/body.ts | 7 +- .../src/interfaces/nullifier_tree.ts | 16 --- yarn-project/circuit-types/src/l2_block.ts | 15 +-- .../src/logs/encrypted_l2_log.ts | 15 +-- .../src/logs/encrypted_l2_note_log.ts | 14 +-- .../circuit-types/src/logs/event_metadata.ts | 24 ---- .../src/logs/extended_unencrypted_l2_log.ts | 10 +- .../src/logs/function_l2_logs.test.ts | 4 +- .../src/logs/function_l2_logs.ts | 38 ------ .../src/logs/l1_payload/payload.ts | 34 +++-- .../src/logs/l2_block_l2_logs.test.ts | 8 -- .../src/logs/l2_block_l2_logs.ts | 42 +------ yarn-project/circuit-types/src/logs/log_id.ts | 8 -- .../circuit-types/src/logs/tx_l2_logs.test.ts | 4 +- .../circuit-types/src/logs/tx_l2_logs.ts | 40 ------ .../src/logs/unencrypted_l2_log.test.ts | 9 ++ .../src/logs/unencrypted_l2_log.ts | 15 +-- .../src/messaging/l1_to_l2_message.ts | 3 +- .../src/notes/extended_note.test.ts | 36 ++++-- .../circuit-types/src/notes/extended_note.ts | 44 +++++-- .../src/p2p/consensus_payload.ts | 2 +- .../src/private_execution_result.ts | 119 +----------------- .../epoch_proof_quote.test.ts | 3 +- .../prover_coordination/epoch_proof_quote.ts | 14 +-- .../epoch_proof_quote_payload.ts | 21 +--- .../circuit-types/src/public_data_witness.ts | 5 +- .../src/public_execution_request.ts | 7 -- .../src/sibling_path/sibling_path.test.ts | 19 +++ .../src/sibling_path/sibling_path.ts | 18 +-- .../circuit-types/src/simulation_error.ts | 11 +- .../circuit-types/src/tx/block_hash.ts | 29 +++++ yarn-project/circuit-types/src/tx/index.ts | 1 + .../src/tx/public_simulation_output.test.ts | 11 ++ .../src/tx/public_simulation_output.ts | 37 ------ .../circuit-types/src/tx/simulated_tx.test.ts | 31 +++-- .../circuit-types/src/tx/simulated_tx.ts | 53 ++------ yarn-project/circuit-types/src/tx/tx.test.ts | 8 ++ yarn-project/circuit-types/src/tx/tx.ts | 67 +++------- .../circuit-types/src/tx/tx_receipt.test.ts | 9 +- .../circuit-types/src/tx/tx_receipt.ts | 36 +----- yarn-project/circuit-types/src/tx_effect.ts | 57 +++++++-- .../circuit-types/src/tx_execution_request.ts | 5 +- .../src/contract/interfaces/contract_class.ts | 8 +- .../__snapshots__/revert_code.test.ts.snap | 44 ++----- .../circuits.js/src/structs/avm/avm.ts | 37 +++--- .../src/structs/avm/avm_accumulated_data.ts | 5 +- .../structs/avm/avm_circuit_public_inputs.ts | 5 +- .../src/structs/client_ivc_proof.ts | 7 +- .../src/structs/complete_address.ts | 3 +- .../src/structs/content_commitment.ts | 18 +-- .../circuits.js/src/structs/function_data.ts | 23 ++-- yarn-project/circuits.js/src/structs/gas.ts | 8 -- .../circuits.js/src/structs/gas_fees.ts | 11 -- .../src/structs/global_variables.ts | 29 +---- .../circuits.js/src/structs/header.ts | 16 +-- .../kernel/combined_accumulated_data.ts | 11 +- .../kernel/kernel_circuit_public_inputs.ts | 11 +- .../kernel/private_accumulated_data.ts | 5 +- .../private_kernel_circuit_public_inputs.ts | 6 +- .../kernel/private_kernel_empty_inputs.ts | 13 +- ...ivate_kernel_tail_circuit_public_inputs.ts | 6 +- ..._to_public_kernel_circuit_public_inputs.ts | 5 +- .../structs/kernel/public_accumulated_data.ts | 9 +- .../public_kernel_circuit_private_inputs.ts | 5 +- .../public_kernel_circuit_public_inputs.ts | 5 +- ...blic_kernel_tail_circuit_private_inputs.ts | 5 +- .../kernel/vm_circuit_public_inputs.ts | 5 +- .../src/structs/parity/base_parity_inputs.ts | 13 +- .../structs/parity/parity_public_inputs.ts | 13 +- .../src/structs/parity/root_parity_input.ts | 9 +- .../src/structs/parity/root_parity_inputs.ts | 13 +- .../src/structs/partial_state_reference.ts | 8 -- .../structs/private_circuit_public_inputs.ts | 14 +-- .../structs/private_validation_requests.ts | 5 +- yarn-project/circuits.js/src/structs/proof.ts | 5 +- .../src/structs/public_data_write.ts | 6 +- .../src/structs/public_validation_requests.ts | 9 +- .../src/structs/recursive_proof.ts | 11 +- .../src/structs/revert_code.test.ts | 6 +- .../circuits.js/src/structs/revert_code.ts | 11 +- .../rollup/append_only_tree_snapshot.ts | 11 +- .../base_or_merge_rollup_public_inputs.ts | 13 +- .../src/structs/rollup/base_rollup_hints.ts | 5 +- .../src/structs/rollup/block_merge_rollup.ts | 11 +- ...block_root_or_block_merge_public_inputs.ts | 13 +- .../src/structs/rollup/block_root_rollup.ts | 13 +- .../rollup/empty_block_root_rollup_inputs.ts | 15 +-- .../src/structs/rollup/merge_rollup.ts | 15 +-- .../rollup/private_base_rollup_inputs.ts | 13 +- .../rollup/public_base_rollup_inputs.ts | 16 +-- .../src/structs/rollup/root_rollup.ts | 27 ++-- .../src/structs/rollup/tube_inputs.ts | 11 +- .../src/structs/rollup_validation_requests.ts | 5 +- .../circuits.js/src/structs/shared.ts | 5 - .../src/structs/state_reference.ts | 4 - .../src/structs/trees/nullifier_leaf.ts | 16 --- .../circuits.js/src/structs/tx_context.ts | 8 -- .../src/structs/verification_key.ts | 15 +-- .../src/structs/vk_witness_data.ts | 5 +- .../circuits.js/src/types/public_keys.ts | 3 +- yarn-project/cli-wallet/src/cmds/cancel_tx.ts | 2 +- yarn-project/cli-wallet/src/cmds/send.ts | 2 +- yarn-project/cli/src/utils/inspect.ts | 2 +- .../src/e2e_prover/e2e_prover_test.ts | 2 +- .../e2e_prover_coordination.test.ts | 2 +- yarn-project/foundation/src/abi/abi.ts | 2 +- .../foundation/src/abi/event_selector.ts | 10 +- .../foundation/src/abi/function_selector.ts | 10 +- .../foundation/src/abi/note_selector.ts | 10 +- yarn-project/foundation/src/abi/selector.ts | 3 +- .../foundation/src/aztec-address/index.ts | 10 +- .../foundation/src/buffer/buffer32.ts | 20 +-- .../secp256k1-signer/secp256k1_signer.test.ts | 6 +- .../foundation/src/eth-address/index.ts | 17 +-- .../src/eth-signature/eth_signature.test.ts | 26 ++-- .../src/eth-signature/eth_signature.ts | 29 +++-- yarn-project/foundation/src/fields/fields.ts | 20 +-- yarn-project/foundation/src/fields/point.ts | 20 ++- .../foundation/src/schemas/schemas.ts | 74 ++++------- yarn-project/foundation/src/schemas/utils.ts | 30 +++-- .../src/serialize/type_registry.test.ts | 90 +++++++++++++ .../foundation/src/serialize/type_registry.ts | 34 ++++- yarn-project/foundation/src/string/index.ts | 4 + .../src/mem_pools/attestation_pool/mocks.ts | 2 +- .../global_variable_builder/global_builder.ts | 2 +- .../src/publisher/l1-publisher.ts | 2 +- yarn-project/txe/src/util/encoding.ts | 3 +- 133 files changed, 908 insertions(+), 1155 deletions(-) create mode 100644 yarn-project/circuit-types/src/sibling_path/sibling_path.test.ts create mode 100644 yarn-project/circuit-types/src/tx/block_hash.ts create mode 100644 yarn-project/circuit-types/src/tx/public_simulation_output.test.ts create mode 100644 yarn-project/foundation/src/serialize/type_registry.test.ts diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/block_store.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/block_store.ts index a4a3ba3281c..25c74ea9e4f 100644 --- a/yarn-project/archiver/src/archiver/kv_archiver_store/block_store.ts +++ b/yarn-project/archiver/src/archiver/kv_archiver_store/block_store.ts @@ -1,4 +1,4 @@ -import { Body, L2Block, type TxEffect, type TxHash, TxReceipt } from '@aztec/circuit-types'; +import { Body, L2Block, L2BlockHash, type TxEffect, type TxHash, TxReceipt } from '@aztec/circuit-types'; import { AppendOnlyTreeSnapshot, type AztecAddress, Header, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { type AztecKVStore, type AztecMap, type AztecSingleton, type Range } from '@aztec/kv-store'; @@ -199,7 +199,7 @@ export class BlockStore { TxReceipt.statusFromRevertCode(tx.revertCode), '', tx.transactionFee.toBigInt(), - block.data.hash().toBuffer(), + L2BlockHash.fromField(block.data.hash()), block.data.number, ); } diff --git a/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts b/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts index 14637a80a10..05eefea6487 100644 --- a/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts +++ b/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts @@ -6,6 +6,7 @@ import { type GetUnencryptedLogsResponse, type InboxLeaf, type L2Block, + L2BlockHash, type L2BlockL2Logs, type LogFilter, LogId, @@ -353,7 +354,7 @@ export class MemoryArchiverStore implements ArchiverDataStore { TxReceipt.statusFromRevertCode(txEffect.revertCode), '', txEffect.transactionFee.toBigInt(), - block.data.hash().toBuffer(), + L2BlockHash.fromField(block.data.hash()), block.data.number, ), ); diff --git a/yarn-project/archiver/src/test/mock_l2_block_source.ts b/yarn-project/archiver/src/test/mock_l2_block_source.ts index 86ffce4ae50..eeabb3072e1 100644 --- a/yarn-project/archiver/src/test/mock_l2_block_source.ts +++ b/yarn-project/archiver/src/test/mock_l2_block_source.ts @@ -1,4 +1,12 @@ -import { L2Block, type L2BlockSource, type L2Tips, type TxHash, TxReceipt, TxStatus } from '@aztec/circuit-types'; +import { + L2Block, + L2BlockHash, + type L2BlockSource, + type L2Tips, + type TxHash, + TxReceipt, + TxStatus, +} from '@aztec/circuit-types'; import { EthAddress, type Header } from '@aztec/circuits.js'; import { DefaultL1ContractsConfig } from '@aztec/ethereum'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -138,7 +146,7 @@ export class MockL2BlockSource implements L2BlockSource { TxStatus.SUCCESS, '', txEffect.transactionFee.toBigInt(), - block.hash().toBuffer(), + L2BlockHash.fromField(block.hash()), block.number, ), ); diff --git a/yarn-project/aztec-node/src/aztec-node/server.test.ts b/yarn-project/aztec-node/src/aztec-node/server.test.ts index 09b1a2e081a..27aee37d9bd 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.test.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.test.ts @@ -139,12 +139,14 @@ describe('aztec node', () => { maxBlockNumber: new MaxBlockNumber(true, new Fr(1)), getSize: () => 1, toBuffer: () => Fr.ZERO.toBuffer(), + toString: () => Fr.ZERO.toString(), }; validMaxBlockNumberMetadata.data.rollupValidationRequests = { maxBlockNumber: new MaxBlockNumber(true, new Fr(5)), getSize: () => 1, toBuffer: () => Fr.ZERO.toBuffer(), + toString: () => Fr.ZERO.toString(), }; lastBlockNumber = 3; diff --git a/yarn-project/bot/src/factory.ts b/yarn-project/bot/src/factory.ts index b05e840fdb2..2a72653005a 100644 --- a/yarn-project/bot/src/factory.ts +++ b/yarn-project/bot/src/factory.ts @@ -70,7 +70,7 @@ export class BotFactory { this.log.info(`Initializing account at ${account.getAddress().toString()}`); const sentTx = account.deploy(); const txHash = await sentTx.getTxHash(); - this.log.info(`Sent tx with hash ${txHash.to0xString()}`); + this.log.info(`Sent tx with hash ${txHash.toString()}`); if (this.config.flushSetupTransactions) { this.log.verbose('Flushing transactions'); await this.node!.flushTxs(); @@ -117,7 +117,7 @@ export class BotFactory { this.log.info(`Deploying token contract at ${address.toString()}`); const sentTx = deploy.send(deployOpts); const txHash = await sentTx.getTxHash(); - this.log.info(`Sent tx with hash ${txHash.to0xString()}`); + this.log.info(`Sent tx with hash ${txHash.toString()}`); if (this.config.flushSetupTransactions) { this.log.verbose('Flushing transactions'); await this.node!.flushTxs(); @@ -164,7 +164,7 @@ export class BotFactory { } const sentTx = new BatchCall(token.wallet, calls).send(); const txHash = await sentTx.getTxHash(); - this.log.info(`Sent tx with hash ${txHash.to0xString()}`); + this.log.info(`Sent tx with hash ${txHash.toString()}`); if (this.config.flushSetupTransactions) { this.log.verbose('Flushing transactions'); await this.node!.flushTxs(); diff --git a/yarn-project/circuit-types/src/auth_witness.ts b/yarn-project/circuit-types/src/auth_witness.ts index f661817edbd..ea135a2d5dd 100644 --- a/yarn-project/circuit-types/src/auth_witness.ts +++ b/yarn-project/circuit-types/src/auth_witness.ts @@ -2,6 +2,7 @@ import { Vector } from '@aztec/circuits.js'; import { Fr } from '@aztec/foundation/fields'; import { hexSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; /** * An authentication witness. Used to authorize an action by a user. @@ -37,12 +38,11 @@ export class AuthWitness { } toString() { - return '0x' + this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(str: string) { - const hex = str.replace(/^0x/, ''); - return AuthWitness.fromBuffer(Buffer.from(hex, 'hex')); + return AuthWitness.fromBuffer(hexToBuffer(str)); } static random() { diff --git a/yarn-project/circuit-types/src/body.ts b/yarn-project/circuit-types/src/body.ts index 283060a1af4..b7b5a503459 100644 --- a/yarn-project/circuit-types/src/body.ts +++ b/yarn-project/circuit-types/src/body.ts @@ -1,3 +1,4 @@ +import { type ZodFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { computeUnbalancedMerkleRoot } from '@aztec/foundation/trees'; @@ -16,7 +17,7 @@ export class Body { }); } - static get schema() { + static get schema(): ZodFor { return z .object({ txEffects: z.array(TxEffect.schema), @@ -24,10 +25,6 @@ export class Body { .transform(({ txEffects }) => new Body(txEffects)); } - toJSON() { - return { txEffects: this.txEffects }; - } - /** * Serializes a block body * @returns A serialized L2 block body. diff --git a/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts b/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts index bfc6097ab09..ec46c4d99e9 100644 --- a/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts +++ b/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts @@ -54,20 +54,4 @@ export class NullifierMembershipWitness { public toFields(): Fr[] { return [new Fr(this.index), ...this.leafPreimage.toFields(), ...this.siblingPath.toFields()]; } - - public toJSON() { - return { - index: '0x' + this.index.toString(16), - leafPreimage: this.leafPreimage.toJSON(), - siblingPath: this.siblingPath.toString(), - }; - } - - static fromJSON(json: any): NullifierMembershipWitness { - return new NullifierMembershipWitness( - BigInt(json.index), - NullifierLeafPreimage.fromJSON(json.leafPreimage), - SiblingPath.fromString(json.siblingPath), - ); - } } diff --git a/yarn-project/circuit-types/src/l2_block.ts b/yarn-project/circuit-types/src/l2_block.ts index f889a0148cb..c5b1cb38769 100644 --- a/yarn-project/circuit-types/src/l2_block.ts +++ b/yarn-project/circuit-types/src/l2_block.ts @@ -1,7 +1,8 @@ -import { AppendOnlyTreeSnapshot, Header, STRING_ENCODING } from '@aztec/circuits.js'; +import { AppendOnlyTreeSnapshot, Header } from '@aztec/circuits.js'; import { sha256, sha256ToField } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { z } from 'zod'; @@ -31,14 +32,6 @@ export class L2Block { .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. @@ -66,7 +59,7 @@ export class L2Block { * @returns Deserialized L2 block. */ static fromString(str: string): L2Block { - return L2Block.fromBuffer(Buffer.from(str, STRING_ENCODING)); + return L2Block.fromBuffer(hexToBuffer(str)); } /** @@ -74,7 +67,7 @@ export class L2Block { * @returns A serialized L2 block as a string. */ toString(): string { - return this.toBuffer().toString(STRING_ENCODING); + return bufferToHex(this.toBuffer()); } /** diff --git a/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts b/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts index f59b98fa6a6..da67376b042 100644 --- a/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts +++ b/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts @@ -25,23 +25,10 @@ export class EncryptedL2Log { static get schema() { return z - .object({ data: schemas.BufferHex, maskedContractAddress: schemas.Fr }) + .object({ data: schemas.Buffer, maskedContractAddress: schemas.Fr }) .transform(({ data, maskedContractAddress }) => new EncryptedL2Log(data, maskedContractAddress)); } - /** Returns a JSON-friendly representation of the log. */ - public toJSON(): object { - return { - data: this.data.toString('hex'), - maskedContractAddress: this.maskedContractAddress.toString(), - }; - } - - /** Converts a plain JSON object into an instance. */ - public static fromJSON(obj: any) { - return new EncryptedL2Log(Buffer.from(obj.data, 'hex'), Fr.fromString(obj.maskedContractAddress)); - } - /** * Deserializes log from a buffer. * @param buffer - The buffer containing the log. diff --git a/yarn-project/circuit-types/src/logs/encrypted_l2_note_log.ts b/yarn-project/circuit-types/src/logs/encrypted_l2_note_log.ts index 23f5a2a99b1..62d4d7ff62d 100644 --- a/yarn-project/circuit-types/src/logs/encrypted_l2_note_log.ts +++ b/yarn-project/circuit-types/src/logs/encrypted_l2_note_log.ts @@ -25,20 +25,8 @@ export class EncryptedL2NoteLog { return this.data; } - /** Returns a JSON-friendly representation of the log. */ - public toJSON(): object { - return { data: this.data.toString('hex') }; - } - 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')); + return z.object({ data: schemas.Buffer }).transform(({ data }) => new EncryptedL2NoteLog(data)); } /** diff --git a/yarn-project/circuit-types/src/logs/event_metadata.ts b/yarn-project/circuit-types/src/logs/event_metadata.ts index b63d8b8bba5..8e3d094f23c 100644 --- a/yarn-project/circuit-types/src/logs/event_metadata.ts +++ b/yarn-project/circuit-types/src/logs/event_metadata.ts @@ -49,37 +49,13 @@ export class EventMetadata { }; } - /** - * Serializes the metadata to a JSON-friendly format - */ - public toJSON() { - return { - type: 'event_metadata', // TODO(palla/schemas): Remove this type property - eventSelector: this.eventSelector, - abiType: this.abiType, - fieldNames: this.fieldNames, - }; - } - static get schema() { return z .object({ eventSelector: schemas.EventSelector, abiType: AbiTypeSchema, fieldNames: z.array(z.string()), - type: z.literal('event_metadata').optional(), }) .transform(obj => new EventMetadata(obj)); } - - /** - * Creates an EventMetadata instance from a JSON representation - */ - public static fromJSON(json: any): EventMetadata { - return new EventMetadata({ - eventSelector: EventSelector.fromString(json.eventSelector), - abiType: json.abiType, - fieldNames: json.fieldNames, - }); - } } diff --git a/yarn-project/circuit-types/src/logs/extended_unencrypted_l2_log.ts b/yarn-project/circuit-types/src/logs/extended_unencrypted_l2_log.ts index b571879aacd..9bdab9deeb4 100644 --- a/yarn-project/circuit-types/src/logs/extended_unencrypted_l2_log.ts +++ b/yarn-project/circuit-types/src/logs/extended_unencrypted_l2_log.ts @@ -1,4 +1,5 @@ import { BufferReader } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import isEqual from 'lodash.isequal'; @@ -22,10 +23,6 @@ export class ExtendedUnencryptedL2Log { return new ExtendedUnencryptedL2Log(LogId.random(), UnencryptedL2Log.random()); } - toJSON() { - return { id: this.id, log: this.log }; - } - static get schema() { return z .object({ @@ -52,7 +49,7 @@ export class ExtendedUnencryptedL2Log { * @returns A string containing the serialized log. */ public toString(): string { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -92,7 +89,6 @@ export class ExtendedUnencryptedL2Log { * @returns An `ExtendedUnencryptedL2Log` object. */ public static fromString(data: string): ExtendedUnencryptedL2Log { - const buffer = Buffer.from(data, 'hex'); - return ExtendedUnencryptedL2Log.fromBuffer(buffer); + return ExtendedUnencryptedL2Log.fromBuffer(hexToBuffer(data)); } } diff --git a/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts b/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts index 5effe039a0c..901a6424176 100644 --- a/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts +++ b/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts @@ -19,8 +19,8 @@ function shouldBehaveLikeFunctionL2Logs( it('can encode L2Logs to JSON and back', () => { const l2Logs = FunctionL2Logs.random(3); - const buffer = JSON.stringify(l2Logs.toJSON()); - const recovered = FunctionL2Logs.fromJSON(JSON.parse(buffer)); + const buffer = JSON.stringify(l2Logs); + const recovered = FunctionL2Logs.schema.parse(JSON.parse(buffer)); expect(recovered).toEqual(l2Logs); }); diff --git a/yarn-project/circuit-types/src/logs/function_l2_logs.ts b/yarn-project/circuit-types/src/logs/function_l2_logs.ts index e3127e63cd6..2171fb2c17e 100644 --- a/yarn-project/circuit-types/src/logs/function_l2_logs.ts +++ b/yarn-project/circuit-types/src/logs/function_l2_logs.ts @@ -62,14 +62,6 @@ export abstract class FunctionL2Logs l.hash())); return sha256Trunc(preimage); } - - /** - * Convert a FunctionL2Logs class object to a plain JSON object. - * @returns A plain object with FunctionL2Logs properties. - */ - public toJSON() { - return { logs: this.logs }; - } } export class EncryptedNoteFunctionL2Logs extends FunctionL2Logs { @@ -118,16 +110,6 @@ export class EncryptedNoteFunctionL2Logs extends FunctionL2Logs { @@ -176,16 +158,6 @@ export class EncryptedFunctionL2Logs extends FunctionL2Logs { } return new EncryptedFunctionL2Logs(logs); } - - /** - * Convert a plain JSON object to a FunctionL2Logs class object. - * @param obj - A plain FunctionL2Logs JSON object. - * @returns A FunctionL2Logs class object. - */ - public static fromJSON(obj: any) { - const logs = obj.logs.map(EncryptedL2Log.fromJSON); - return new EncryptedFunctionL2Logs(logs); - } } export class UnencryptedFunctionL2Logs extends FunctionL2Logs { @@ -234,14 +206,4 @@ export class UnencryptedFunctionL2Logs extends FunctionL2Logs } return new UnencryptedFunctionL2Logs(logs); } - - /** - * Convert a plain JSON object to a FunctionL2Logs class object. - * @param obj - A plain FunctionL2Logs JSON object. - * @returns A FunctionL2Logs class object. - */ - public static fromJSON(obj: any) { - const logs = obj.logs.map(UnencryptedL2Log.fromJSON); - return new UnencryptedFunctionL2Logs(logs); - } } diff --git a/yarn-project/circuit-types/src/logs/l1_payload/payload.ts b/yarn-project/circuit-types/src/logs/l1_payload/payload.ts index cc460a2a3cd..4bcad7408fc 100644 --- a/yarn-project/circuit-types/src/logs/l1_payload/payload.ts +++ b/yarn-project/circuit-types/src/logs/l1_payload/payload.ts @@ -1,8 +1,9 @@ import { Vector } from '@aztec/circuits.js'; import { randomInt } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { schemas } from '@aztec/foundation/schemas'; import { BufferReader } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; /** * The Note class represents a Note emitted from a Noir contract as a vector of Fr (finite field) elements. @@ -11,11 +12,11 @@ import { BufferReader } from '@aztec/foundation/serialize'; */ export class Payload extends Vector { toJSON() { - return this.toString(); + return this.toBuffer(); } static get schema() { - return hexSchemaFor(Payload); + return schemas.Buffer.transform(Payload.fromBuffer); } /** @@ -49,7 +50,7 @@ export class Payload extends Vector { * @returns A hex string with the vector length as first element. */ override toString() { - return '0x' + this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -58,8 +59,7 @@ export class Payload extends Vector { * @returns A Note instance. */ static fromString(str: string) { - const hex = str.replace(/^0x/, ''); - return Payload.fromBuffer(Buffer.from(hex, 'hex')); + return Payload.fromBuffer(hexToBuffer(str)); } get length() { @@ -71,6 +71,24 @@ export class Payload extends Vector { } } -export class Event extends Payload {} +export class Event extends Payload { + static override get schema() { + return schemas.Buffer.transform(Event.fromBuffer); + } + + static override fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new Event(reader.readVector(Fr)); + } +} -export class Note extends Payload {} +export class Note extends Payload { + static override get schema() { + return schemas.Buffer.transform(Note.fromBuffer); + } + + static override fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new Note(reader.readVector(Fr)); + } +} diff --git a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts index 540e118b99f..5947af04c18 100644 --- a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts +++ b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts @@ -34,14 +34,6 @@ function shouldBehaveLikeL2BlockL2Logs( } }); - it('serializes to and from JSON via fromJSON', () => { - const l2Logs = L2BlockL2Logs.random(3, 4, 2); - const json = jsonStringify(l2Logs); - const recovered = L2BlockL2Logs.fromJSON(JSON.parse(json)); - expect(recovered).toEqual(l2Logs); - expect(recovered).toBeInstanceOf(L2BlockL2Logs); - }); - it('serializes to and from JSON via schema', () => { const l2Logs = L2BlockL2Logs.random(3, 4, 2); const json = jsonStringify(l2Logs); diff --git a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.ts b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.ts index 9d858041460..7ae8173d845 100644 --- a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.ts +++ b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.ts @@ -1,5 +1,6 @@ import { type ZodFor } from '@aztec/foundation/schemas'; import { BufferReader, prefixBufferWithLength } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import isEqual from 'lodash.isequal'; import { z } from 'zod'; @@ -59,7 +60,7 @@ export abstract class L2BlockL2Logs EncryptedNoteTxL2Logs.fromJSON(log)); - return new EncryptedNoteL2BlockL2Logs(txLogs); - } - /** * Deserializes logs from a buffer. * @param buffer - The buffer containing the serialized logs. @@ -133,8 +124,7 @@ export class EncryptedNoteL2BlockL2Logs extends L2BlockL2Logs { return 'Encrypted'; } - /** - * Convert a plain JSON object to a L2BlockL2Logs class object. - * @param obj - A plain L2BlockL2Logs JSON object. - * @returns A L2BlockL2Logs class object. - */ - public static fromJSON(obj: any) { - const txLogs = obj.txLogs.map((log: any) => EncryptedTxL2Logs.fromJSON(log)); - return new EncryptedL2BlockL2Logs(txLogs); - } - /** * Deserializes logs from a buffer. * @param buffer - The buffer containing the serialized logs. @@ -214,8 +194,7 @@ export class EncryptedL2BlockL2Logs extends L2BlockL2Logs { * @returns A new `L2BlockL2Logs` object. */ public static fromString(data: string): EncryptedL2BlockL2Logs { - const buffer = Buffer.from(data, 'hex'); - return EncryptedL2BlockL2Logs.fromBuffer(buffer); + return EncryptedL2BlockL2Logs.fromBuffer(hexToBuffer(data)); } /** @@ -264,16 +243,6 @@ export class UnencryptedL2BlockL2Logs extends L2BlockL2Logs { return 'Unencrypted'; } - /** - * Convert a plain JSON object to a L2BlockL2Logs class object. - * @param obj - A plain L2BlockL2Logs JSON object. - * @returns A L2BlockL2Logs class object. - */ - public static fromJSON(obj: any) { - const txLogs = obj.txLogs.map((log: any) => UnencryptedTxL2Logs.fromJSON(log)); - return new UnencryptedL2BlockL2Logs(txLogs); - } - /** * Deserializes logs from a buffer. * @param buffer - The buffer containing the serialized logs. @@ -295,8 +264,7 @@ export class UnencryptedL2BlockL2Logs extends L2BlockL2Logs { * @returns A new `L2BlockL2Logs` object. */ public static fromString(data: string): UnencryptedL2BlockL2Logs { - const buffer = Buffer.from(data, 'hex'); - return UnencryptedL2BlockL2Logs.fromBuffer(buffer); + return UnencryptedL2BlockL2Logs.fromBuffer(hexToBuffer(data)); } /** diff --git a/yarn-project/circuit-types/src/logs/log_id.ts b/yarn-project/circuit-types/src/logs/log_id.ts index 731763b1f07..fe718fb3821 100644 --- a/yarn-project/circuit-types/src/logs/log_id.ts +++ b/yarn-project/circuit-types/src/logs/log_id.ts @@ -50,14 +50,6 @@ export class LogId { .transform(({ blockNumber, txIndex, logIndex }) => new LogId(blockNumber, txIndex, logIndex)); } - toJSON() { - return { - blockNumber: this.blockNumber, - txIndex: this.txIndex, - logIndex: this.logIndex, - }; - } - /** * Serializes log id to a buffer. * @returns A buffer containing the serialized log id. diff --git a/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts b/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts index 61ea3137a8e..d92f98208bf 100644 --- a/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts +++ b/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts @@ -18,8 +18,8 @@ function shouldBehaveLikeTxL2Logs( it('can encode TxL2Logs to JSON and back', () => { const l2Logs = TxL2Logs.random(4, 2); - const buffer = jsonStringify(l2Logs.toJSON()); - const recovered = TxL2Logs.fromJSON(JSON.parse(buffer)); + const buffer = jsonStringify(l2Logs); + const recovered = TxL2Logs.schema.parse(JSON.parse(buffer)); expect(recovered).toEqual(l2Logs); }); diff --git a/yarn-project/circuit-types/src/logs/tx_l2_logs.ts b/yarn-project/circuit-types/src/logs/tx_l2_logs.ts index 6ffd7cbc5dc..a5836da6713 100644 --- a/yarn-project/circuit-types/src/logs/tx_l2_logs.ts +++ b/yarn-project/circuit-types/src/logs/tx_l2_logs.ts @@ -75,16 +75,6 @@ export abstract class TxL2Logs log.toJSON()), - }; - } - /** * Unrolls logs from this tx. * @returns Unrolled logs. @@ -208,16 +198,6 @@ export class UnencryptedTxL2Logs extends TxL2Logs { return new UnencryptedTxL2Logs(functionLogs); } - /** - * Convert a plain JSON object to a TxL2Logs class object. - * @param obj - A plain TxL2Logs JSON object. - * @returns A TxL2Logs class object. - */ - public static fromJSON(obj: any) { - const functionLogs = obj.functionLogs.map((log: any) => UnencryptedFunctionL2Logs.fromJSON(log)); - return new UnencryptedTxL2Logs(functionLogs); - } - /** * Computes unencrypted logs hash as is done in the kernel and decoder contract. * @param logs - Logs to be hashed. @@ -302,16 +282,6 @@ export class EncryptedNoteTxL2Logs extends TxL2Logs { return new EncryptedNoteTxL2Logs(functionLogs); } - /** - * Convert a plain JSON object to a TxL2Logs class object. - * @param obj - A plain TxL2Logs JSON object. - * @returns A TxL2Logs class object. - */ - public static fromJSON(obj: any) { - const functionLogs = obj.functionLogs.map((log: any) => EncryptedNoteFunctionL2Logs.fromJSON(log)); - return new EncryptedNoteTxL2Logs(functionLogs); - } - /** * Computes encrypted logs hash as is done in the kernel and decoder contract. * @param logs - Logs to be hashed. @@ -395,16 +365,6 @@ export class EncryptedTxL2Logs extends TxL2Logs { return new EncryptedTxL2Logs(functionLogs); } - /** - * Convert a plain JSON object to a TxL2Logs class object. - * @param obj - A plain TxL2Logs JSON object. - * @returns A TxL2Logs class object. - */ - public static fromJSON(obj: any) { - const functionLogs = obj.functionLogs.map((log: any) => EncryptedFunctionL2Logs.fromJSON(log)); - return new EncryptedTxL2Logs(functionLogs); - } - /** * Computes encrypted logs hash as is done in the kernel and decoder contract. * @param logs - Logs to be hashed. diff --git a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.test.ts b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.test.ts index 60f89766d9d..32cba56c991 100644 --- a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.test.ts +++ b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.test.ts @@ -9,4 +9,13 @@ describe('UnencryptedL2Log', () => { expect(recovered).toEqual(l2Logs); }); + + it('can encode to JSON and back', () => { + const l2Logs = UnencryptedL2Log.random(); + + const buffer = JSON.stringify(l2Logs); + const recovered = UnencryptedL2Log.schema.parse(JSON.parse(buffer)); + + expect(recovered).toEqual(l2Logs); + }); }); diff --git a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts index b43778409a9..942dad32db2 100644 --- a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts +++ b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts @@ -48,23 +48,10 @@ export class UnencryptedL2Log { static get schema() { return z - .object({ contractAddress: schemas.AztecAddress, data: schemas.BufferHex }) + .object({ contractAddress: schemas.AztecAddress, data: schemas.Buffer }) .transform(({ contractAddress, data }) => new UnencryptedL2Log(contractAddress, data)); } - /** Returns a JSON-friendly representation of the log. */ - public toJSON(): object { - return { - contractAddress: this.contractAddress.toString(), - data: this.data.toString('hex'), - }; - } - - /** Converts a plain JSON object into an instance. */ - public static fromJSON(obj: any) { - return new UnencryptedL2Log(AztecAddress.fromString(obj.contractAddress), Buffer.from(obj.data, 'hex')); - } - /** * Deserializes log from a buffer. * @param buffer - The buffer or buffer reader containing the log. diff --git a/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts b/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts index 6d8ada947b9..380b26249ce 100644 --- a/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts +++ b/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts @@ -4,6 +4,7 @@ import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { sha256ToField } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex } from '@aztec/foundation/string'; import { type AztecNode } from '../interfaces/aztec-node.js'; import { MerkleTreeId } from '../merkle_tree_id.js'; @@ -55,7 +56,7 @@ export class L1ToL2Message { } toString(): string { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(data: string): L1ToL2Message { diff --git a/yarn-project/circuit-types/src/notes/extended_note.test.ts b/yarn-project/circuit-types/src/notes/extended_note.test.ts index 25a2280b527..2aa52f54d38 100644 --- a/yarn-project/circuit-types/src/notes/extended_note.test.ts +++ b/yarn-project/circuit-types/src/notes/extended_note.test.ts @@ -1,18 +1,38 @@ import { randomExtendedNote, randomUniqueNote } from '../mocks.js'; import { ExtendedNote, UniqueNote } from './extended_note.js'; -describe('Extended Note', () => { +describe('ExtendedNote', () => { + let note: ExtendedNote; + + beforeEach(() => { + note = randomExtendedNote(); + }); + it('convert to and from buffer', () => { - const extendedNote = randomExtendedNote(); - const buf = extendedNote.toBuffer(); - expect(ExtendedNote.fromBuffer(buf)).toEqual(extendedNote); + const buf = note.toBuffer(); + expect(ExtendedNote.fromBuffer(buf)).toEqual(note); + }); + + it('convert to and from JSON', () => { + const json = JSON.stringify(note); + expect(ExtendedNote.schema.parse(JSON.parse(json))).toEqual(note); }); }); -describe('Unique Note', () => { +describe('UniqueNote', () => { + let note: UniqueNote; + + beforeEach(() => { + note = randomUniqueNote(); + }); + it('convert to and from buffer', () => { - const uniqueNote = randomUniqueNote(); - const buf = uniqueNote.toBuffer(); - expect(UniqueNote.fromBuffer(buf)).toEqual(uniqueNote); + const buf = note.toBuffer(); + expect(UniqueNote.fromBuffer(buf)).toEqual(note); + }); + + it('convert to and from JSON', () => { + const json = JSON.stringify(note); + expect(UniqueNote.schema.parse(JSON.parse(json))).toEqual(note); }); }); diff --git a/yarn-project/circuit-types/src/notes/extended_note.ts b/yarn-project/circuit-types/src/notes/extended_note.ts index a3c3506cdbb..cac982b01b8 100644 --- a/yarn-project/circuit-types/src/notes/extended_note.ts +++ b/yarn-project/circuit-types/src/notes/extended_note.ts @@ -1,7 +1,10 @@ import { AztecAddress, Fr } from '@aztec/circuits.js'; import { NoteSelector } from '@aztec/foundation/abi'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { schemas } from '@aztec/foundation/schemas'; import { BufferReader } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; + +import { z } from 'zod'; import { Note } from '../logs/l1_payload/payload.js'; import { TxHash } from '../tx/tx_hash.js'; @@ -49,21 +52,27 @@ export class ExtendedNote { return new this(note, owner, contractAddress, storageSlot, noteTypeId, txHash); } - toJSON() { - return this.toString(); - } - static get schema() { - return hexSchemaFor(ExtendedNote); + return z + .object({ + note: Note.schema, + owner: schemas.AztecAddress, + contractAddress: schemas.AztecAddress, + storageSlot: schemas.Fr, + noteTypeId: schemas.NoteSelector, + txHash: TxHash.schema, + }) + .transform(({ note, owner, contractAddress, storageSlot, noteTypeId, txHash }) => { + return new ExtendedNote(note, owner, contractAddress, storageSlot, noteTypeId, txHash); + }); } toString() { - return '0x' + this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(str: string) { - const hex = str.replace(/^0x/, ''); - return ExtendedNote.fromBuffer(Buffer.from(hex, 'hex')); + return ExtendedNote.fromBuffer(hexToBuffer(str)); } static random() { @@ -99,7 +108,19 @@ export class UniqueNote extends ExtendedNote { } static override get schema() { - return hexSchemaFor(UniqueNote); + return z + .object({ + note: Note.schema, + owner: schemas.AztecAddress, + contractAddress: schemas.AztecAddress, + storageSlot: schemas.Fr, + noteTypeId: schemas.NoteSelector, + txHash: TxHash.schema, + nonce: schemas.Fr, + }) + .transform(({ note, owner, contractAddress, storageSlot, noteTypeId, txHash, nonce }) => { + return new UniqueNote(note, owner, contractAddress, storageSlot, noteTypeId, txHash, nonce); + }); } override toBuffer(): Buffer { @@ -141,7 +162,6 @@ export class UniqueNote extends ExtendedNote { } static override fromString(str: string) { - const hex = str.replace(/^0x/, ''); - return UniqueNote.fromBuffer(Buffer.from(hex, 'hex')); + return UniqueNote.fromBuffer(hexToBuffer(str)); } } diff --git a/yarn-project/circuit-types/src/p2p/consensus_payload.ts b/yarn-project/circuit-types/src/p2p/consensus_payload.ts index f6b70a5f354..def6f04e890 100644 --- a/yarn-project/circuit-types/src/p2p/consensus_payload.ts +++ b/yarn-project/circuit-types/src/p2p/consensus_payload.ts @@ -26,7 +26,7 @@ export class ConsensusPayload implements Signable { getPayloadToSign(domainSeperator: SignatureDomainSeperator): Buffer { const abi = parseAbiParameters('uint8, bytes32, bytes32[]'); - const txArray = this.txHashes.map(tx => tx.to0xString()); + const txArray = this.txHashes.map(tx => tx.toString()); const encodedData = encodeAbiParameters(abi, [domainSeperator, this.archive.toString(), txArray] as const); return Buffer.from(encodedData.slice(2), 'hex'); diff --git a/yarn-project/circuit-types/src/private_execution_result.ts b/yarn-project/circuit-types/src/private_execution_result.ts index 8bb57866b84..713c6f7f77e 100644 --- a/yarn-project/circuit-types/src/private_execution_result.ts +++ b/yarn-project/circuit-types/src/private_execution_result.ts @@ -3,7 +3,7 @@ import { NoteSelector } from '@aztec/foundation/abi'; import { times } from '@aztec/foundation/collection'; import { randomBytes, randomInt } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; -import { type ZodFor, hexSchemaFor, mapSchema, schemas } from '@aztec/foundation/schemas'; +import { type ZodFor, mapSchema, schemas } from '@aztec/foundation/schemas'; import { type FieldsOf } from '@aztec/foundation/types'; import { z } from 'zod'; @@ -46,22 +46,6 @@ export class NoteAndSlot { return new NoteAndSlot(fields.note, fields.storageSlot, fields.noteTypeId); } - toJSON() { - return { - note: this.note.toBuffer().toString('hex'), - storageSlot: this.storageSlot.toBuffer().toString('hex'), - noteTypeId: this.noteTypeId.toString(), - }; - } - - public static fromJSON(json: any): NoteAndSlot { - return new NoteAndSlot( - Note.fromBuffer(Buffer.from(json.note, 'hex')), - Fr.fromString(json.storageSlot), - NoteSelector.fromString(json.noteTypeId), - ); - } - static random() { return new NoteAndSlot(Note.random(), Fr.random(), NoteSelector.random()); } @@ -115,18 +99,6 @@ export class CountedNoteLog extends CountedLog { .transform(({ log, counter, noteHashCounter }) => new CountedNoteLog(log, counter, noteHashCounter)); } - toJSON() { - return { - log: this.log.toJSON(), - counter: this.counter, - noteHashCounter: this.noteHashCounter, - }; - } - - static fromJSON(json: any) { - return new CountedNoteLog(EncryptedL2NoteLog.fromJSON(json.log), json.counter, json.noteHashCounter); - } - static random() { return new CountedNoteLog(EncryptedL2NoteLog.random(), randomInt(10), randomInt(10)); } @@ -138,7 +110,7 @@ export class CountedPublicExecutionRequest { static get schema() { return z .object({ - request: hexSchemaFor(PublicExecutionRequest), // TODO(palla/schema) Use PublicExecutionRequest.schema, + request: PublicExecutionRequest.schema, counter: schemas.Integer, }) .transform(CountedPublicExecutionRequest.from); @@ -152,20 +124,6 @@ export class CountedPublicExecutionRequest { return this.request.isEmpty() && !this.counter; } - toJSON() { - return { - request: this.request.toBuffer().toString('hex'), - counter: this.counter, - }; - } - - static fromJSON(json: any) { - return new CountedPublicExecutionRequest( - PublicExecutionRequest.fromBuffer(Buffer.from(json.request, 'hex')), - json.counter, - ); - } - static random() { return new CountedPublicExecutionRequest(PublicExecutionRequest.random(), 0); } @@ -220,8 +178,8 @@ export class PrivateExecutionResult { static get schema(): ZodFor { return z .object({ - acir: schemas.BufferHex, - vk: schemas.BufferHex, + acir: schemas.Buffer, + vk: schemas.Buffer, partialWitness: mapSchema(z.coerce.number(), z.string()), publicInputs: PrivateCircuitPublicInputs.schema, noteHashLeafIndexMap: mapSchema(schemas.BigInt, schemas.BigInt), @@ -230,7 +188,7 @@ export class PrivateExecutionResult { returnValues: z.array(schemas.Fr), nestedExecutions: z.array(z.lazy(() => PrivateExecutionResult.schema)), enqueuedPublicFunctionCalls: z.array(CountedPublicExecutionRequest.schema), - publicTeardownFunctionCall: hexSchemaFor(PublicExecutionRequest), // TODO(palla/schema) Use PublicExecutionRequest.schema + publicTeardownFunctionCall: PublicExecutionRequest.schema, noteEncryptedLogs: z.array(CountedNoteLog.schema), encryptedLogs: z.array(CountedLog.schemaFor(EncryptedL2Log)), unencryptedLogs: z.array(CountedLog.schemaFor(UnencryptedL2Log)), @@ -257,34 +215,6 @@ export class PrivateExecutionResult { ); } - toJSON(): any { - return { - acir: this.acir.toString('hex'), - vk: this.vk.toString('hex'), - partialWitness: Array.from(this.partialWitness.entries()), - publicInputs: this.publicInputs.toJSON(), - noteHashLeafIndexMap: Array.from(this.noteHashLeafIndexMap.entries()).map(([key, value]) => [ - key.toString(), - value.toString(), - ]), - newNotes: this.newNotes.map(note => note.toJSON()), - noteHashNullifierCounterMap: Array.from(this.noteHashNullifierCounterMap.entries()), - returnValues: this.returnValues.map(fr => fr.toBuffer().toString('hex')), - nestedExecutions: this.nestedExecutions.map(exec => exec.toJSON()), - enqueuedPublicFunctionCalls: this.enqueuedPublicFunctionCalls.map(call => call.toJSON()), - publicTeardownFunctionCall: this.publicTeardownFunctionCall.toBuffer().toString('hex'), - noteEncryptedLogs: this.noteEncryptedLogs.map(log => log.toJSON()), - encryptedLogs: this.encryptedLogs.map(countedLog => ({ - log: countedLog.log.toJSON(), - counter: countedLog.counter, - })), - unencryptedLogs: this.unencryptedLogs.map(countedLog => ({ - log: countedLog.log.toJSON(), - counter: countedLog.counter, - })), - }; - } - static random(nested = 1): PrivateExecutionResult { return new PrivateExecutionResult( randomBytes(4), @@ -303,45 +233,6 @@ export class PrivateExecutionResult { [new CountedLog(UnencryptedL2Log.random(), randomInt(10))], ); } - - static fromJSON(json: any): PrivateExecutionResult { - return new PrivateExecutionResult( - Buffer.from(json.acir, 'hex'), - Buffer.from(json.vk, 'hex'), - Array.isArray(json.partialWitness) - ? new Map(json.partialWitness.map(([key, value]: any[]) => [Number(key), value as string])) - : new Map(), - PrivateCircuitPublicInputs.fromJSON(json.publicInputs), - Array.isArray(json.noteHashLeafIndexMap) - ? new Map(json.noteHashLeafIndexMap.map(([key, value]: any[]) => [BigInt(key), BigInt(value)])) - : new Map(), - Array.isArray(json.newNotes) ? json.newNotes.map((note: any) => NoteAndSlot.fromJSON(note)) : [], - Array.isArray(json.noteHashNullifierCounterMap) - ? new Map(json.noteHashNullifierCounterMap.map(([key, value]: any[]) => [Number(key), Number(value)])) - : new Map(), - json.returnValues.map((fr: any) => new Fr(Buffer.from(fr, 'hex'))), - Array.isArray(json.nestedExecutions) - ? json.nestedExecutions.map((exec: any) => PrivateExecutionResult.fromJSON(exec)) - : [], - Array.isArray(json.enqueuedPublicFunctionCalls) - ? json.enqueuedPublicFunctionCalls.map((call: any) => CountedPublicExecutionRequest.fromJSON(call)) - : [], - PublicExecutionRequest.fromBuffer(Buffer.from(json.publicTeardownFunctionCall, 'hex')), - Array.isArray(json.noteEncryptedLogs) - ? json.noteEncryptedLogs.map((json: any) => CountedNoteLog.fromJSON(json)) - : [], - Array.isArray(json.encryptedLogs) - ? json.encryptedLogs.map( - (json: any) => new CountedLog(EncryptedL2Log.fromJSON(json.log), json.counter), - ) - : [], - Array.isArray(json.unencryptedLogs) - ? json.unencryptedLogs.map( - (json: any) => new CountedLog(UnencryptedL2Log.fromJSON(json.log), json.counter), - ) - : [], - ); - } } export function collectNoteHashLeafIndexMap( diff --git a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.test.ts b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.test.ts index 78f68edee04..5de9bda3b80 100644 --- a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.test.ts +++ b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.test.ts @@ -1,5 +1,6 @@ import { EthAddress } from '@aztec/circuits.js'; import { Signature } from '@aztec/foundation/eth-signature'; +import { jsonStringify } from '@aztec/foundation/json-rpc'; import { EpochProofQuote } from './epoch_proof_quote.js'; import { EpochProofQuotePayload } from './epoch_proof_quote_payload.js'; @@ -30,7 +31,7 @@ describe('epoch proof quote', () => { }); it('should serialize and deserialize from JSON', () => { - const deserialised = EpochProofQuote.fromJSON(quote.toJSON()); + const deserialised = EpochProofQuote.schema.parse(jsonStringify(quote)); checkEquivalence(quote, deserialised); }); }); diff --git a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts index d6f7222cf8b..454d01aa585 100644 --- a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts +++ b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts @@ -1,7 +1,6 @@ import { Buffer32 } from '@aztec/foundation/buffer'; import { type Secp256k1Signer, keccak256 } from '@aztec/foundation/crypto'; import { Signature } from '@aztec/foundation/eth-signature'; -import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { type FieldsOf } from '@aztec/foundation/types'; @@ -44,26 +43,15 @@ export class EpochProofQuote extends Gossipable { return new EpochProofQuote(reader.readObject(EpochProofQuotePayload), reader.readObject(Signature)); } - toJSON() { - return { - payload: this.payload.toJSON(), - signature: this.signature.to0xString(), - }; - } - static get schema() { return z .object({ payload: EpochProofQuotePayload.schema, - signature: schemas.Signature, + signature: Signature.schema, }) .transform(({ payload, signature }) => new EpochProofQuote(payload, signature)); } - static fromJSON(obj: any) { - return EpochProofQuote.schema.parse(obj); - } - // TODO: https://github.com/AztecProtocol/aztec-packages/issues/8911 /** * Creates a new quote with a signature. diff --git a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts index 7f1e87eee87..60c06e39501 100644 --- a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts +++ b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts @@ -3,6 +3,7 @@ import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { type FieldsOf } from '@aztec/foundation/types'; +import omit from 'lodash.omit'; import { inspect } from 'util'; import { z } from 'zod'; @@ -82,31 +83,21 @@ export class EpochProofQuotePayload { } toJSON() { - return { - epochToProve: this.epochToProve.toString(), - validUntilSlot: this.validUntilSlot.toString(), - bondAmount: this.bondAmount.toString(), - prover: this.prover.toString(), - basisPointFee: this.basisPointFee, - }; + return omit(this, 'asBuffer', 'size'); } static get schema() { return z .object({ - epochToProve: z.coerce.bigint(), - validUntilSlot: z.coerce.bigint(), - bondAmount: z.coerce.bigint(), + epochToProve: schemas.BigInt, + validUntilSlot: schemas.BigInt, + bondAmount: schemas.BigInt, prover: schemas.EthAddress, - basisPointFee: z.number(), + basisPointFee: schemas.Integer, }) .transform(EpochProofQuotePayload.from); } - static fromJSON(obj: any): EpochProofQuotePayload { - return EpochProofQuotePayload.schema.parse(obj); - } - toViemArgs(): { epochToProve: bigint; validUntilSlot: bigint; diff --git a/yarn-project/circuit-types/src/public_data_witness.ts b/yarn-project/circuit-types/src/public_data_witness.ts index cdc33705231..41e43418b9a 100644 --- a/yarn-project/circuit-types/src/public_data_witness.ts +++ b/yarn-project/circuit-types/src/public_data_witness.ts @@ -2,6 +2,7 @@ import { Fr, PUBLIC_DATA_TREE_HEIGHT, PublicDataTreeLeafPreimage } from '@aztec/ import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { z } from 'zod'; @@ -63,7 +64,7 @@ export class PublicDataWitness { * Returns a string representation of the TxEffect object. */ toString(): string { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static random() { @@ -95,6 +96,6 @@ export class PublicDataWitness { * @returns An instance of PublicDataWitness. */ static fromString(str: string) { - return PublicDataWitness.fromBuffer(Buffer.from(str, 'hex')); + return PublicDataWitness.fromBuffer(hexToBuffer(str)); } } diff --git a/yarn-project/circuit-types/src/public_execution_request.ts b/yarn-project/circuit-types/src/public_execution_request.ts index df60e8e8213..a1ba37e40e3 100644 --- a/yarn-project/circuit-types/src/public_execution_request.ts +++ b/yarn-project/circuit-types/src/public_execution_request.ts @@ -40,13 +40,6 @@ export class PublicExecutionRequest { .transform(PublicExecutionRequest.from); } - toJSON() { - return { - callContext: this.callContext, - args: this.args, - }; - } - static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new PublicExecutionRequest(CallContext.fromBuffer(reader), reader.readVector(Fr)); diff --git a/yarn-project/circuit-types/src/sibling_path/sibling_path.test.ts b/yarn-project/circuit-types/src/sibling_path/sibling_path.test.ts new file mode 100644 index 00000000000..d48e32e820b --- /dev/null +++ b/yarn-project/circuit-types/src/sibling_path/sibling_path.test.ts @@ -0,0 +1,19 @@ +import { jsonStringify } from '@aztec/foundation/json-rpc'; + +import { SiblingPath } from './sibling_path.js'; + +describe('SiblingPath', () => { + it('serializes to JSON', () => { + const path = SiblingPath.random(10); + const json = jsonStringify(path); + expect(SiblingPath.schema.parse(JSON.parse(json))).toEqual(path); + }); + + it('validates length', () => { + const path = SiblingPath.random(10); + const json = jsonStringify(path); + expect(() => SiblingPath.schemaFor(12).parse(JSON.parse(json))).toThrow( + expect.objectContaining({ name: 'ZodError' }), + ); + }); +}); diff --git a/yarn-project/circuit-types/src/sibling_path/sibling_path.ts b/yarn-project/circuit-types/src/sibling_path/sibling_path.ts index a18d02ce951..96738dab368 100644 --- a/yarn-project/circuit-types/src/sibling_path/sibling_path.ts +++ b/yarn-project/circuit-types/src/sibling_path/sibling_path.ts @@ -1,12 +1,13 @@ import { makeTuple } from '@aztec/foundation/array'; import { Fr } from '@aztec/foundation/fields'; -import { hexSchema, hexSchemaFor } from '@aztec/foundation/schemas'; +import { schemas } from '@aztec/foundation/schemas'; import { type Tuple, assertLength, deserializeArrayFromVector, serializeArrayOfBufferableToVector, } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type Hasher } from '@aztec/types/interfaces'; /** @@ -37,17 +38,18 @@ export class SiblingPath { } static get schema() { - return hexSchemaFor(SiblingPath); + return schemas.Buffer.transform(b => SiblingPath.fromBuffer(b)); } static schemaFor(size: N) { - return hexSchema - .transform(str => SiblingPath.fromString(str) as SiblingPath) - .refine(path => path.pathSize === size, 'Unexpected size'); + return schemas.Buffer.transform(b => SiblingPath.fromBuffer(b) as SiblingPath).refine( + path => path.pathSize === size, + path => ({ message: `Expected sibling path size ${size} but got ${path.pathSize}` }), + ); } toJSON() { - return this.toString(); + return this.toBuffer(); } /** @@ -137,7 +139,7 @@ export class SiblingPath { * @returns A hex string representation of the sibling path. */ public toString(): string { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -146,7 +148,7 @@ export class SiblingPath { * @returns A SiblingPath object. */ public static fromString(repr: string): SiblingPath { - return SiblingPath.fromBuffer(Buffer.from(repr, 'hex')); + return SiblingPath.fromBuffer(hexToBuffer(repr)); } /** diff --git a/yarn-project/circuit-types/src/simulation_error.ts b/yarn-project/circuit-types/src/simulation_error.ts index 70cd960217a..3e84bbdb60e 100644 --- a/yarn-project/circuit-types/src/simulation_error.ts +++ b/yarn-project/circuit-types/src/simulation_error.ts @@ -1,4 +1,4 @@ -import { AztecAddress, Fr, FunctionSelector } from '@aztec/circuits.js'; +import { AztecAddress, type Fr, FunctionSelector } from '@aztec/circuits.js'; import { type OpcodeLocation } from '@aztec/foundation/abi'; import { schemas } from '@aztec/foundation/schemas'; @@ -220,15 +220,6 @@ export class SimulationError extends Error { }; } - static fromJSON(obj: ReturnType) { - return new SimulationError( - obj.originalMessage, - obj.functionErrorStack, - obj.revertData.map(serializedFr => Fr.fromString(serializedFr)), - obj.noirErrorStack, - ); - } - static get schema() { return z .object({ diff --git a/yarn-project/circuit-types/src/tx/block_hash.ts b/yarn-project/circuit-types/src/tx/block_hash.ts new file mode 100644 index 00000000000..010b2e6ca16 --- /dev/null +++ b/yarn-project/circuit-types/src/tx/block_hash.ts @@ -0,0 +1,29 @@ +import { Fr } from '@aztec/circuits.js'; +import { Buffer32 } from '@aztec/foundation/buffer'; +import { schemas } from '@aztec/foundation/schemas'; + +/** Hash of an L2 block. */ +export class L2BlockHash extends Buffer32 { + constructor( + /** The buffer containing the hash. */ + hash: Buffer, + ) { + super(hash); + } + + static override random() { + return new L2BlockHash(Fr.random().toBuffer()); + } + + static get schema() { + return schemas.BufferHex.transform(value => new L2BlockHash(value)); + } + + static zero() { + return new L2BlockHash(Buffer32.ZERO.toBuffer()); + } + + static override fromField(hash: Fr) { + return new L2BlockHash(hash.toBuffer()); + } +} diff --git a/yarn-project/circuit-types/src/tx/index.ts b/yarn-project/circuit-types/src/tx/index.ts index bc94339f36b..30cae14ee88 100644 --- a/yarn-project/circuit-types/src/tx/index.ts +++ b/yarn-project/circuit-types/src/tx/index.ts @@ -7,3 +7,4 @@ export * from './tx_hash.js'; export * from './tx_receipt.js'; export * from './validator/tx_validator.js'; export * from './validator/empty_validator.js'; +export * from './block_hash.js'; diff --git a/yarn-project/circuit-types/src/tx/public_simulation_output.test.ts b/yarn-project/circuit-types/src/tx/public_simulation_output.test.ts new file mode 100644 index 00000000000..8582164a408 --- /dev/null +++ b/yarn-project/circuit-types/src/tx/public_simulation_output.test.ts @@ -0,0 +1,11 @@ +import { jsonStringify } from '@aztec/foundation/json-rpc'; + +import { PublicSimulationOutput } from './public_simulation_output.js'; + +describe('PublicSimulationOutput', () => { + it('serializes to JSON', () => { + const output = PublicSimulationOutput.random(); + const json = jsonStringify(output); + expect(PublicSimulationOutput.schema.parse(JSON.parse(json))).toEqual(output); + }); +}); diff --git a/yarn-project/circuit-types/src/tx/public_simulation_output.ts b/yarn-project/circuit-types/src/tx/public_simulation_output.ts index a6748c071aa..98ca5e8fc60 100644 --- a/yarn-project/circuit-types/src/tx/public_simulation_output.ts +++ b/yarn-project/circuit-types/src/tx/public_simulation_output.ts @@ -1,5 +1,4 @@ import { CombinedConstantData, Fr, Gas } from '@aztec/circuits.js'; -import { mapValues } from '@aztec/foundation/collection'; import { type ZodFor, schemas } from '@aztec/foundation/schemas'; import times from 'lodash.times'; @@ -31,20 +30,6 @@ export class NestedProcessReturnValues { .transform(({ values, nested }) => new NestedProcessReturnValues(values, nested)); } - toJSON(): any { - return { - values: this.values?.map(fr => fr.toString()), - nested: this.nested.map(n => n.toJSON()), - }; - } - - static fromJSON(json: any): NestedProcessReturnValues { - return new NestedProcessReturnValues( - json.values?.map(Fr.fromString), - json.nested?.map((n: any) => NestedProcessReturnValues.fromJSON(n)), - ); - } - static empty() { return new NestedProcessReturnValues([]); } @@ -90,28 +75,6 @@ export class PublicSimulationOutput { ); } - toJSON() { - return { - revertReason: this.revertReason, - constants: this.constants.toBuffer().toString('hex'), - txEffect: this.txEffect.toBuffer().toString('hex'), - publicReturnValues: this.publicReturnValues.map(returns => returns?.toJSON()), - gasUsed: mapValues(this.gasUsed, gas => gas?.toJSON()), - }; - } - - static fromJSON(json: any): PublicSimulationOutput { - return new PublicSimulationOutput( - json.revertReason, - CombinedConstantData.fromBuffer(Buffer.from(json.constants, 'hex')), - TxEffect.fromBuffer(Buffer.from(json.txEffect, 'hex')), - Array.isArray(json.publicReturnValues) - ? json.publicReturnValues.map((returns: any) => NestedProcessReturnValues.fromJSON(returns)) - : [], - mapValues(json.gasUsed, gas => Gas.fromJSON(gas)), - ); - } - static random() { return new PublicSimulationOutput( SimulationError.random(), diff --git a/yarn-project/circuit-types/src/tx/simulated_tx.test.ts b/yarn-project/circuit-types/src/tx/simulated_tx.test.ts index 035bab4f517..a12a51e3452 100644 --- a/yarn-project/circuit-types/src/tx/simulated_tx.test.ts +++ b/yarn-project/circuit-types/src/tx/simulated_tx.test.ts @@ -1,18 +1,33 @@ +import { jsonStringify } from '@aztec/foundation/json-rpc'; + import { mockSimulatedTx } from '../mocks.js'; -import { TxSimulationResult } from './simulated_tx.js'; +import { TxProvingResult, TxSimulationResult } from './simulated_tx.js'; describe('simulated_tx', () => { - let simulatedTx: TxSimulationResult; - beforeEach(() => { - simulatedTx = mockSimulatedTx(); - }); - describe('json', () => { + describe('TxSimulationResult', () => { + let simulatedTx: TxSimulationResult; + beforeEach(() => { + simulatedTx = mockSimulatedTx(); + }); + it('convert to and from json', () => { - expect(TxSimulationResult.fromJSON(JSON.parse(JSON.stringify(simulatedTx.toJSON())))).toEqual(simulatedTx); + expect(TxSimulationResult.schema.parse(JSON.parse(jsonStringify(simulatedTx)))).toEqual(simulatedTx); }); + it('convert undefined effects to and from json', () => { simulatedTx.publicOutput = undefined; - expect(TxSimulationResult.fromJSON(JSON.parse(JSON.stringify(simulatedTx.toJSON())))).toEqual(simulatedTx); + expect(TxSimulationResult.schema.parse(JSON.parse(jsonStringify(simulatedTx)))).toEqual(simulatedTx); + }); + }); + + describe('TxProvingResult', () => { + let tx: TxProvingResult; + beforeEach(() => { + tx = TxProvingResult.random(); + }); + + it('convert to and from json', () => { + expect(TxProvingResult.schema.parse(JSON.parse(jsonStringify(tx)))).toEqual(tx); }); }); }); diff --git a/yarn-project/circuit-types/src/tx/simulated_tx.ts b/yarn-project/circuit-types/src/tx/simulated_tx.ts index f3af028d0c5..56c2984df75 100644 --- a/yarn-project/circuit-types/src/tx/simulated_tx.ts +++ b/yarn-project/circuit-types/src/tx/simulated_tx.ts @@ -48,19 +48,6 @@ export class PrivateSimulationResult { ); return tx; } - - public toJSON() { - return { - privateExecutionResult: this.privateExecutionResult.toJSON(), - publicInputs: this.publicInputs.toBuffer().toString('hex'), - }; - } - - public static fromJSON(obj: any) { - const privateExecutionResult = PrivateExecutionResult.fromJSON(obj.privateExecutionResult); - const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(Buffer.from(obj.publicInputs, 'hex')); - return new PrivateSimulationResult(privateExecutionResult, publicInputs); - } } export class TxSimulationResult extends PrivateSimulationResult { @@ -119,21 +106,12 @@ export class TxSimulationResult extends PrivateSimulationResult { ); } - public override toJSON() { - return { - privateExecutionResult: this.privateExecutionResult.toJSON(), - publicInputs: this.publicInputs.toBuffer().toString('hex'), - publicOutput: this.publicOutput ? this.publicOutput.toJSON() : undefined, - profileResult: this.profileResult, - }; - } - - public static override fromJSON(obj: any) { - const privateExecutionResult = PrivateExecutionResult.fromJSON(obj.privateExecutionResult); - const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(Buffer.from(obj.publicInputs, 'hex')); - const publicOuput = obj.publicOutput ? PublicSimulationOutput.fromJSON(obj.publicOutput) : undefined; - const profileResult = obj.profileResult; - return new TxSimulationResult(privateExecutionResult, publicInputs, publicOuput, profileResult); + static random() { + return new TxSimulationResult( + PrivateExecutionResult.random(), + PrivateKernelTailCircuitPublicInputs.empty(), + PublicSimulationOutput.random(), + ); } } @@ -177,19 +155,12 @@ export class TxProvingResult { return new TxProvingResult(fields.privateExecutionResult, fields.publicInputs, fields.clientIvcProof); } - public toJSON() { - return { - privateExecutionResult: this.privateExecutionResult, - publicInputs: this.publicInputs, - clientIvcProof: this.clientIvcProof, - }; - } - - public static fromJSON(obj: any) { - const privateExecutionResult = PrivateExecutionResult.fromJSON(obj.privateExecutionResult); - const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(Buffer.from(obj.publicInputs, 'hex')); - const clientIvcProof = ClientIvcProof.fromBuffer(Buffer.from(obj.clientIvcProof, 'hex')); - return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof); + static random() { + return new TxProvingResult( + PrivateExecutionResult.random(), + PrivateKernelTailCircuitPublicInputs.empty(), + ClientIvcProof.empty(), + ); } } diff --git a/yarn-project/circuit-types/src/tx/tx.test.ts b/yarn-project/circuit-types/src/tx/tx.test.ts index 3cfe2c1a4eb..0710303b16b 100644 --- a/yarn-project/circuit-types/src/tx/tx.test.ts +++ b/yarn-project/circuit-types/src/tx/tx.test.ts @@ -1,3 +1,5 @@ +import { jsonStringify } from '@aztec/foundation/json-rpc'; + import { mockTx } from '../mocks.js'; import { Tx } from './tx.js'; @@ -7,4 +9,10 @@ describe('Tx', () => { const buf = tx.toBuffer(); expect(Tx.fromBuffer(buf)).toEqual(tx); }); + + it('convert to and from json', () => { + const tx = mockTx(); + const json = jsonStringify(tx); + expect(Tx.schema.parse(JSON.parse(json))).toEqual(tx); + }); }); diff --git a/yarn-project/circuit-types/src/tx/tx.ts b/yarn-project/circuit-types/src/tx/tx.ts index 9123fb2e6f6..59d1d02478f 100644 --- a/yarn-project/circuit-types/src/tx/tx.ts +++ b/yarn-project/circuit-types/src/tx/tx.ts @@ -6,8 +6,8 @@ import { } from '@aztec/circuits.js'; import { type Buffer32 } from '@aztec/foundation/buffer'; import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection'; -import { hexSchema } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { type FieldsOf } from '@aztec/foundation/types'; import { z } from 'zod'; @@ -125,61 +125,28 @@ export class Tx extends Gossipable { } static get schema() { - // TODO(palla/schemas): Use the nested objects schemas as opposed to the toBuffers return z .object({ - data: hexSchema, // PrivateKernelTailCircuitPublicInputs.schema, - clientIvcProof: hexSchema, // ClientIvcProof.schema, - noteEncryptedLogs: hexSchema, // EncryptedNoteTxL2Logs.schema, - encryptedLogs: hexSchema, // EncryptedTxL2Logs.schema, - unencryptedLogs: hexSchema, // UnencryptedTxL2Logs.schema, - enqueuedPublicFunctionCalls: z.array(hexSchema), // z.array(PublicExecutionRequest.schema), - publicTeardownFunctionCall: hexSchema, // PublicExecutionRequest.schema, + data: PrivateKernelTailCircuitPublicInputs.schema, + clientIvcProof: ClientIvcProof.schema, + noteEncryptedLogs: EncryptedNoteTxL2Logs.schema, + encryptedLogs: EncryptedTxL2Logs.schema, + unencryptedLogs: UnencryptedTxL2Logs.schema, + enqueuedPublicFunctionCalls: z.array(PublicExecutionRequest.schema), + publicTeardownFunctionCall: PublicExecutionRequest.schema, }) - .transform(Tx.fromJSON); + .transform(Tx.from); } - /** - * Convert a Tx class object to a plain JSON object. - * @returns A plain object with Tx properties. - */ - public toJSON() { - return { - data: this.data.toBuffer().toString('hex'), - noteEncryptedLogs: this.noteEncryptedLogs.toBuffer().toString('hex'), - encryptedLogs: this.encryptedLogs.toBuffer().toString('hex'), - unencryptedLogs: this.unencryptedLogs.toBuffer().toString('hex'), - clientIvcProof: this.clientIvcProof.toBuffer().toString('hex'), - enqueuedPublicFunctionCalls: this.enqueuedPublicFunctionCalls.map(f => f.toBuffer().toString('hex')) ?? [], - publicTeardownFunctionCall: this.publicTeardownFunctionCall.toBuffer().toString('hex'), - }; - } - - /** - * Convert a plain JSON object to a Tx class object. - * @param obj - A plain Tx JSON object. - * @returns A Tx class object. - */ - public static fromJSON(obj: any) { - const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(Buffer.from(obj.data, 'hex')); - const noteEncryptedLogs = EncryptedNoteTxL2Logs.fromBuffer(Buffer.from(obj.noteEncryptedLogs, 'hex')); - const encryptedLogs = EncryptedTxL2Logs.fromBuffer(Buffer.from(obj.encryptedLogs, 'hex')); - const unencryptedLogs = UnencryptedTxL2Logs.fromBuffer(Buffer.from(obj.unencryptedLogs, 'hex')); - const clientIvcProof = ClientIvcProof.fromBuffer(Buffer.from(obj.clientIvcProof, 'hex')); - const enqueuedPublicFunctionCalls = obj.enqueuedPublicFunctionCalls - ? obj.enqueuedPublicFunctionCalls.map((x: string) => PublicExecutionRequest.fromBuffer(Buffer.from(x, 'hex'))) - : []; - const publicTeardownFunctionCall = PublicExecutionRequest.fromBuffer( - Buffer.from(obj.publicTeardownFunctionCall, 'hex'), - ); + static from(fields: FieldsOf) { return new Tx( - publicInputs, - clientIvcProof, - noteEncryptedLogs, - encryptedLogs, - unencryptedLogs, - enqueuedPublicFunctionCalls, - publicTeardownFunctionCall, + fields.data, + fields.clientIvcProof, + fields.noteEncryptedLogs, + fields.encryptedLogs, + fields.unencryptedLogs, + fields.enqueuedPublicFunctionCalls, + fields.publicTeardownFunctionCall, ); } diff --git a/yarn-project/circuit-types/src/tx/tx_receipt.test.ts b/yarn-project/circuit-types/src/tx/tx_receipt.test.ts index 2eac60ece2e..b55ec33b7a8 100644 --- a/yarn-project/circuit-types/src/tx/tx_receipt.test.ts +++ b/yarn-project/circuit-types/src/tx/tx_receipt.test.ts @@ -1,3 +1,6 @@ +import { jsonStringify } from '@aztec/foundation/json-rpc'; + +import { L2BlockHash } from './block_hash.js'; import { TxHash } from './tx_hash.js'; import { TxReceipt, TxStatus } from './tx_receipt.js'; @@ -8,16 +11,16 @@ describe('TxReceipt', () => { TxStatus.SUCCESS, 'error', BigInt(1), - Buffer.from('blockHash'), + L2BlockHash.random(), undefined, ); - expect(TxReceipt.fromJSON(receipt.toJSON())).toEqual(receipt); + expect(TxReceipt.schema.parse(JSON.parse(jsonStringify(receipt)))).toEqual(receipt); }); it('serializes and deserializes from json with undefined fields', () => { const receipt = new TxReceipt(TxHash.random(), TxStatus.DROPPED, 'error', undefined, undefined, undefined); - expect(TxReceipt.fromJSON(receipt.toJSON())).toEqual(receipt); + expect(TxReceipt.schema.parse(JSON.parse(jsonStringify(receipt)))).toEqual(receipt); }); }); diff --git a/yarn-project/circuit-types/src/tx/tx_receipt.ts b/yarn-project/circuit-types/src/tx/tx_receipt.ts index 3d92c79adf6..0831d7fc67f 100644 --- a/yarn-project/circuit-types/src/tx/tx_receipt.ts +++ b/yarn-project/circuit-types/src/tx/tx_receipt.ts @@ -6,6 +6,7 @@ import { type FieldsOf } from '@aztec/foundation/types'; import { z } from 'zod'; import { UniqueNote } from '../notes/extended_note.js'; +import { L2BlockHash } from './block_hash.js'; import { TxHash } from './tx_hash.js'; /** @@ -37,7 +38,7 @@ export class TxReceipt { /** The transaction fee paid for the transaction. */ public transactionFee?: bigint, /** The hash of the block containing the transaction. */ - public blockHash?: Buffer, + public blockHash?: L2BlockHash, /** The block number in which the transaction was included. */ public blockNumber?: number, /** Information useful for testing/debugging, set when test flag is set to true in `waitOpts`. */ @@ -48,29 +49,13 @@ export class TxReceipt { return new TxReceipt(TxHash.zero(), TxStatus.DROPPED, ''); } - /** - * Convert a Tx class object to a plain JSON object. - * @returns A plain object with Tx properties. - */ - public toJSON() { - return { - txHash: this.txHash.toString(), - status: this.status.toString(), - error: this.error, - blockHash: this.blockHash?.toString('hex'), - blockNumber: this.blockNumber, - transactionFee: this.transactionFee?.toString(), - ...(this.debugInfo && { debugInfo: this.debugInfo }), - }; - } - static get schema() { return z .object({ txHash: TxHash.schema, status: z.nativeEnum(TxStatus), error: z.string(), - blockHash: schemas.BufferHex.optional(), + blockHash: L2BlockHash.schema.optional(), blockNumber: z.number().optional(), transactionFee: schemas.BigInt.optional(), debugInfo: DebugInfoSchema.optional(), @@ -90,21 +75,6 @@ export class TxReceipt { ); } - /** - * Convert a plain JSON object to a Tx class object. - * @param obj - A plain Tx JSON object. - * @returns A Tx class object. - */ - public static fromJSON(obj: any) { - const txHash = TxHash.fromString(obj.txHash); - const status = obj.status as TxStatus; - const error = obj.error; - const transactionFee = obj.transactionFee ? BigInt(obj.transactionFee) : undefined; - const blockHash = obj.blockHash ? Buffer.from(obj.blockHash, 'hex') : undefined; - const blockNumber = obj.blockNumber ? Number(obj.blockNumber) : undefined; - return new TxReceipt(txHash, status, error, transactionFee, blockHash, blockNumber); - } - public static statusFromRevertCode(revertCode: RevertCode) { if (revertCode.equals(RevertCode.OK)) { return TxStatus.SUCCESS; diff --git a/yarn-project/circuit-types/src/tx_effect.ts b/yarn-project/circuit-types/src/tx_effect.ts index 59939e32183..3cd3e535f6f 100644 --- a/yarn-project/circuit-types/src/tx_effect.ts +++ b/yarn-project/circuit-types/src/tx_effect.ts @@ -7,17 +7,22 @@ import { PublicDataWrite, RevertCode, } from '@aztec/circuits.js'; -import { makeTuple } from '@aztec/foundation/array'; +import { type FieldsOf, makeTuple } from '@aztec/foundation/array'; import { padArrayEnd } from '@aztec/foundation/collection'; import { sha256Trunc } from '@aztec/foundation/crypto'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { jsonStringify } from '@aztec/foundation/json-rpc'; +import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, serializeArrayOfBufferableToVector, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; +import { z } from 'zod'; import { EncryptedNoteTxL2Logs, EncryptedTxL2Logs, UnencryptedTxL2Logs } from './logs/index.js'; import { TxHash } from './tx/tx_hash.js'; +export { RevertCodeEnum } from '@aztec/circuits.js'; + export class TxEffect { constructor( /** @@ -250,21 +255,47 @@ export class TxEffect { } /** Returns a hex representation of the TxEffect object. */ - toString(): string { - return this.toBuffer().toString('hex'); + toString() { + return bufferToHex(this.toBuffer()); } - toJSON() { - return this.toString(); + static from(fields: Omit, 'txHash'>) { + return new TxEffect( + fields.revertCode, + fields.transactionFee, + fields.noteHashes, + fields.nullifiers, + fields.l2ToL1Msgs, + fields.publicDataWrites, + fields.noteEncryptedLogsLength, + fields.encryptedLogsLength, + fields.unencryptedLogsLength, + fields.noteEncryptedLogs, + fields.encryptedLogs, + fields.unencryptedLogs, + ); } static get schema() { - return hexSchemaFor(TxEffect); + return z + .object({ + revertCode: RevertCode.schema, + transactionFee: schemas.Fr, + noteHashes: z.array(schemas.Fr), + nullifiers: z.array(schemas.Fr), + l2ToL1Msgs: z.array(schemas.Fr), + publicDataWrites: z.array(PublicDataWrite.schema), + noteEncryptedLogsLength: schemas.Fr, + encryptedLogsLength: schemas.Fr, + unencryptedLogsLength: schemas.Fr, + noteEncryptedLogs: EncryptedNoteTxL2Logs.schema, + encryptedLogs: EncryptedTxL2Logs.schema, + unencryptedLogs: UnencryptedTxL2Logs.schema, + }) + .transform(TxEffect.from); } [inspect.custom]() { - // print out the non-empty fields - return `TxEffect { revertCode: ${this.revertCode}, transactionFee: ${this.transactionFee}, @@ -275,9 +306,9 @@ export class TxEffect { noteEncryptedLogsLength: ${this.noteEncryptedLogsLength}, encryptedLogsLength: ${this.encryptedLogsLength}, unencryptedLogsLength: ${this.unencryptedLogsLength}, - noteEncryptedLogs: ${JSON.stringify(this.noteEncryptedLogs.toJSON())}, - encryptedLogs: ${JSON.stringify(this.encryptedLogs.toJSON())}, - unencryptedLogs: ${JSON.stringify(this.unencryptedLogs.toJSON())} + noteEncryptedLogs: ${jsonStringify(this.noteEncryptedLogs)}, + encryptedLogs: ${jsonStringify(this.encryptedLogs)}, + unencryptedLogs: ${jsonStringify(this.unencryptedLogs)} }`; } @@ -287,7 +318,7 @@ export class TxEffect { * @returns An instance of TxEffect. */ static fromString(str: string) { - return TxEffect.fromBuffer(Buffer.from(str, 'hex')); + return TxEffect.fromBuffer(hexToBuffer(str)); } get txHash(): TxHash { diff --git a/yarn-project/circuit-types/src/tx_execution_request.ts b/yarn-project/circuit-types/src/tx_execution_request.ts index 9588de8c160..2a99636da2e 100644 --- a/yarn-project/circuit-types/src/tx_execution_request.ts +++ b/yarn-project/circuit-types/src/tx_execution_request.ts @@ -1,6 +1,7 @@ import { AztecAddress, Fr, FunctionData, FunctionSelector, TxContext, TxRequest, Vector } from '@aztec/circuits.js'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { z } from 'zod'; @@ -101,7 +102,7 @@ export class TxExecutionRequest { * @returns The string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -127,7 +128,7 @@ export class TxExecutionRequest { * @returns The deserialized TxRequest object. */ static fromString(str: string): TxExecutionRequest { - return TxExecutionRequest.fromBuffer(Buffer.from(str, 'hex')); + return TxExecutionRequest.fromBuffer(hexToBuffer(str)); } static random() { diff --git a/yarn-project/circuits.js/src/contract/interfaces/contract_class.ts b/yarn-project/circuits.js/src/contract/interfaces/contract_class.ts index 82d0a4960a2..002c3ac4f75 100644 --- a/yarn-project/circuits.js/src/contract/interfaces/contract_class.ts +++ b/yarn-project/circuits.js/src/contract/interfaces/contract_class.ts @@ -45,7 +45,7 @@ export interface ExecutablePrivateFunction extends PrivateFunction { } const ExecutablePrivateFunctionSchema = PrivateFunctionSchema.and( - z.object({ bytecode: schemas.BufferB64 }), + z.object({ bytecode: schemas.Buffer }), ) satisfies ZodFor; /** Public function definition within a contract class. */ @@ -58,7 +58,7 @@ export interface PublicFunction { export const PublicFunctionSchema = z.object({ selector: schemas.FunctionSelector, - bytecode: schemas.BufferB64, + bytecode: schemas.Buffer, }) satisfies ZodFor; /** Unconstrained function definition. */ @@ -72,7 +72,7 @@ export interface UnconstrainedFunction { const UnconstrainedFunctionSchema = z.object({ /** lala */ selector: schemas.FunctionSelector, - bytecode: schemas.BufferB64, + bytecode: schemas.Buffer, }) satisfies ZodFor; /** Sibling paths and sibling commitments for proving membership of a private function within a contract class. */ @@ -124,7 +124,7 @@ export const ContractClassSchema = z.object({ artifactHash: schemas.Fr, privateFunctions: z.array(PrivateFunctionSchema), publicFunctions: z.array(PublicFunctionSchema), - packedBytecode: schemas.BufferB64, + packedBytecode: schemas.Buffer, }) satisfies ZodFor; /** Commitments to fields of a contract class. */ diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/revert_code.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/revert_code.test.ts.snap index a4fdeb08c29..5cc25a3728b 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/revert_code.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/revert_code.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`revert_code should serialize properly 1`] = ` +exports[`revert_code should serialize RevertCode<0> properly 1`] = ` { "data": [ 0, @@ -40,7 +40,7 @@ exports[`revert_code should serialize properly 1`] = ` } `; -exports[`revert_code should serialize properly 2`] = ` +exports[`revert_code should serialize RevertCode<0> properly 2`] = ` { "data": [ 0, @@ -49,14 +49,9 @@ exports[`revert_code should serialize properly 2`] = ` } `; -exports[`revert_code should serialize properly 3`] = ` -{ - "type": "Fr", - "value": "0x0000000000000000000000000000000000000000000000000000000000000000", -} -`; +exports[`revert_code should serialize RevertCode<0> properly 3`] = `"0x0000000000000000000000000000000000000000000000000000000000000000"`; -exports[`revert_code should serialize properly 4`] = ` +exports[`revert_code should serialize RevertCode<1> properly 1`] = ` { "data": [ 0, @@ -96,7 +91,7 @@ exports[`revert_code should serialize properly 4`] = ` } `; -exports[`revert_code should serialize properly 5`] = ` +exports[`revert_code should serialize RevertCode<1> properly 2`] = ` { "data": [ 1, @@ -105,14 +100,9 @@ exports[`revert_code should serialize properly 5`] = ` } `; -exports[`revert_code should serialize properly 6`] = ` -{ - "type": "Fr", - "value": "0x0000000000000000000000000000000000000000000000000000000000000001", -} -`; +exports[`revert_code should serialize RevertCode<1> properly 3`] = `"0x0000000000000000000000000000000000000000000000000000000000000001"`; -exports[`revert_code should serialize properly 7`] = ` +exports[`revert_code should serialize RevertCode<2> properly 1`] = ` { "data": [ 0, @@ -152,7 +142,7 @@ exports[`revert_code should serialize properly 7`] = ` } `; -exports[`revert_code should serialize properly 8`] = ` +exports[`revert_code should serialize RevertCode<2> properly 2`] = ` { "data": [ 2, @@ -161,14 +151,9 @@ exports[`revert_code should serialize properly 8`] = ` } `; -exports[`revert_code should serialize properly 9`] = ` -{ - "type": "Fr", - "value": "0x0000000000000000000000000000000000000000000000000000000000000002", -} -`; +exports[`revert_code should serialize RevertCode<2> properly 3`] = `"0x0000000000000000000000000000000000000000000000000000000000000002"`; -exports[`revert_code should serialize properly 10`] = ` +exports[`revert_code should serialize RevertCode<3> properly 1`] = ` { "data": [ 0, @@ -208,7 +193,7 @@ exports[`revert_code should serialize properly 10`] = ` } `; -exports[`revert_code should serialize properly 11`] = ` +exports[`revert_code should serialize RevertCode<3> properly 2`] = ` { "data": [ 3, @@ -217,9 +202,4 @@ exports[`revert_code should serialize properly 11`] = ` } `; -exports[`revert_code should serialize properly 12`] = ` -{ - "type": "Fr", - "value": "0x0000000000000000000000000000000000000000000000000000000000000003", -} -`; +exports[`revert_code should serialize RevertCode<3> properly 3`] = `"0x0000000000000000000000000000000000000000000000000000000000000003"`; diff --git a/yarn-project/circuits.js/src/structs/avm/avm.ts b/yarn-project/circuits.js/src/structs/avm/avm.ts index b4020f36511..30c37a7b132 100644 --- a/yarn-project/circuits.js/src/structs/avm/avm.ts +++ b/yarn-project/circuits.js/src/structs/avm/avm.ts @@ -1,8 +1,9 @@ import { PublicDataTreeLeafPreimage } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { type ContractClassIdPreimage } from '../../contract/contract_class_id.js'; @@ -34,7 +35,7 @@ export class AvmEnqueuedCallHint { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -79,7 +80,7 @@ export class AvmEnqueuedCallHint { * @returns The deserialized instance. */ static fromString(str: string): AvmEnqueuedCallHint { - return AvmEnqueuedCallHint.fromBuffer(Buffer.from(str, 'hex')); + return AvmEnqueuedCallHint.fromBuffer(hexToBuffer(str)); } } @@ -100,7 +101,7 @@ export class AvmKeyValueHint { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -145,7 +146,7 @@ export class AvmKeyValueHint { * @returns The deserialized instance. */ static fromString(str: string): AvmKeyValueHint { - return AvmKeyValueHint.fromBuffer(Buffer.from(str, 'hex')); + return AvmKeyValueHint.fromBuffer(hexToBuffer(str)); } } @@ -182,7 +183,7 @@ export class AvmExternalCallHint { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -245,7 +246,7 @@ export class AvmExternalCallHint { * @returns The deserialized instance. */ static fromString(str: string): AvmExternalCallHint { - return AvmExternalCallHint.fromBuffer(Buffer.from(str, 'hex')); + return AvmExternalCallHint.fromBuffer(hexToBuffer(str)); } } @@ -272,7 +273,7 @@ export class AvmContractInstanceHint { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -341,7 +342,7 @@ export class AvmContractInstanceHint { * @returns The deserialized instance. */ static fromString(str: string): AvmContractInstanceHint { - return AvmContractInstanceHint.fromBuffer(Buffer.from(str, 'hex')); + return AvmContractInstanceHint.fromBuffer(hexToBuffer(str)); } } @@ -369,7 +370,7 @@ export class AvmContractBytecodeHints { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -434,7 +435,7 @@ export class AvmContractBytecodeHints { * @returns The deserialized instance. */ static fromString(str: string): AvmContractBytecodeHints { - return AvmContractBytecodeHints.fromBuffer(Buffer.from(str, 'hex')); + return AvmContractBytecodeHints.fromBuffer(hexToBuffer(str)); } } @@ -914,7 +915,7 @@ export class AvmExecutionHints { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -1026,7 +1027,7 @@ export class AvmExecutionHints { * @returns The deserialized instance. */ static fromString(str: string): AvmCircuitInputs { - return AvmCircuitInputs.fromBuffer(Buffer.from(str, 'hex')); + return AvmCircuitInputs.fromBuffer(hexToBuffer(str)); } } @@ -1061,7 +1062,7 @@ export class AvmCircuitInputs { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static empty(): AvmCircuitInputs { @@ -1114,16 +1115,16 @@ export class AvmCircuitInputs { * @returns The deserialized instance. */ static fromString(str: string): AvmCircuitInputs { - return AvmCircuitInputs.fromBuffer(Buffer.from(str, 'hex')); + return AvmCircuitInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(AvmCircuitInputs); + return bufferSchemaFor(AvmCircuitInputs); } } diff --git a/yarn-project/circuits.js/src/structs/avm/avm_accumulated_data.ts b/yarn-project/circuits.js/src/structs/avm/avm_accumulated_data.ts index 2e01efc6ee2..c68d93b13e4 100644 --- a/yarn-project/circuits.js/src/structs/avm/avm_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/avm/avm_accumulated_data.ts @@ -2,6 +2,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; @@ -83,11 +84,11 @@ export class AvmAccumulatedData { } static fromString(str: string) { - return this.fromBuffer(Buffer.from(str, 'hex')); + return this.fromBuffer(hexToBuffer(str)); } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static empty() { diff --git a/yarn-project/circuits.js/src/structs/avm/avm_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/avm/avm_circuit_public_inputs.ts index 0ff41750b69..8877b4b8003 100644 --- a/yarn-project/circuits.js/src/structs/avm/avm_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/avm/avm_circuit_public_inputs.ts @@ -1,6 +1,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; @@ -80,11 +81,11 @@ export class AvmCircuitPublicInputs { } static fromString(str: string) { - return AvmCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return AvmCircuitPublicInputs.fromBuffer(hexToBuffer(str)); } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromFields(fields: Fr[] | FieldReader) { diff --git a/yarn-project/circuits.js/src/structs/client_ivc_proof.ts b/yarn-project/circuits.js/src/structs/client_ivc_proof.ts index 737870e5080..a35b8f6c84f 100644 --- a/yarn-project/circuits.js/src/structs/client_ivc_proof.ts +++ b/yarn-project/circuits.js/src/structs/client_ivc_proof.ts @@ -1,4 +1,4 @@ -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import * as fs from 'fs/promises'; @@ -67,12 +67,11 @@ export class ClientIvcProof { } static get schema() { - // TODO(palla/schemas): Consider using a b64 schema instead - return hexSchemaFor(ClientIvcProof); + return bufferSchemaFor(ClientIvcProof); } toJSON() { - return '0x' + this.toBuffer().toString('hex'); + return this.toBuffer(); } static fromBuffer(buffer: Buffer | BufferReader): ClientIvcProof { diff --git a/yarn-project/circuits.js/src/structs/complete_address.ts b/yarn-project/circuits.js/src/structs/complete_address.ts index 04d083ae50c..5fbd1132e40 100644 --- a/yarn-project/circuits.js/src/structs/complete_address.ts +++ b/yarn-project/circuits.js/src/structs/complete_address.ts @@ -2,6 +2,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { hexSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex } from '@aztec/foundation/string'; import { computePartialAddress } from '../contract/contract_address.js'; import { computeAddress, computePreaddress, deriveKeys } from '../keys/index.js'; @@ -141,6 +142,6 @@ export class CompleteAddress { * @returns A hexadecimal string representation of the CompleteAddress. */ toString(): string { - return `0x${this.toBuffer().toString('hex')}`; + return bufferToHex(this.toBuffer()); } } diff --git a/yarn-project/circuits.js/src/structs/content_commitment.ts b/yarn-project/circuits.js/src/structs/content_commitment.ts index 578a6831ff5..8e2e9680ba2 100644 --- a/yarn-project/circuits.js/src/structs/content_commitment.ts +++ b/yarn-project/circuits.js/src/structs/content_commitment.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex } from '@aztec/foundation/string'; import { z } from 'zod'; @@ -34,24 +35,15 @@ export class ContentCommitment { return z .object({ numTxs: schemas.Fr, - txsEffectsHash: schemas.BufferHex, - inHash: schemas.BufferHex, - outHash: schemas.BufferHex, + txsEffectsHash: schemas.Buffer, + inHash: schemas.Buffer, + outHash: schemas.Buffer, }) .transform( ({ numTxs, txsEffectsHash, inHash, outHash }) => new ContentCommitment(numTxs, txsEffectsHash, inHash, outHash), ); } - toJSON() { - return { - numTxs: this.numTxs, - txsEffectsHash: this.txsEffectsHash.toString('hex'), - inHash: this.inHash.toString('hex'), - outHash: this.outHash.toString('hex'), - }; - } - getSize() { return this.toBuffer().length; } @@ -113,7 +105,7 @@ export class ContentCommitment { } public toString(): string { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(str: string): ContentCommitment { diff --git a/yarn-project/circuits.js/src/structs/function_data.ts b/yarn-project/circuits.js/src/structs/function_data.ts index 02f58a2deaa..afc63a96d21 100644 --- a/yarn-project/circuits.js/src/structs/function_data.ts +++ b/yarn-project/circuits.js/src/structs/function_data.ts @@ -1,7 +1,10 @@ import { type FunctionAbi, FunctionSelector, FunctionType } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; +import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { z } from 'zod'; + import { FUNCTION_DATA_LENGTH } from '../constants.gen.js'; import { type ContractFunctionDao } from '../types/contract_function_dao.js'; @@ -21,6 +24,15 @@ export class FunctionData { ); } + static get schema() { + return z + .object({ + selector: schemas.FunctionSelector, + isPrivate: z.boolean(), + }) + .transform(({ selector, isPrivate }) => new FunctionData(selector, isPrivate)); + } + /** * Serialize this as a buffer. * @returns The buffer. @@ -88,15 +100,4 @@ export class FunctionData { return new FunctionData(selector, isPrivate); } - - public toJSON() { - return { - selector: this.selector.toString(), - isPrivate: this.isPrivate, - }; - } - - public static fromJSON(json: any) { - return new FunctionData(FunctionSelector.fromString(json.selector), json.isPrivate); - } } diff --git a/yarn-project/circuits.js/src/structs/gas.ts b/yarn-project/circuits.js/src/structs/gas.ts index 4dc6f24f087..7952b2cbbbd 100644 --- a/yarn-project/circuits.js/src/structs/gas.ts +++ b/yarn-project/circuits.js/src/structs/gas.ts @@ -93,12 +93,4 @@ export class Gas { const reader = FieldReader.asReader(fields); return new Gas(reader.readU32(), reader.readU32()); } - - toJSON() { - return { daGas: this.daGas, l2Gas: this.l2Gas }; - } - - static fromJSON(json: any) { - return new Gas(json.daGas, json.l2Gas); - } } diff --git a/yarn-project/circuits.js/src/structs/gas_fees.ts b/yarn-project/circuits.js/src/structs/gas_fees.ts index 6cab097c0ce..dcaabb12da8 100644 --- a/yarn-project/circuits.js/src/structs/gas_fees.ts +++ b/yarn-project/circuits.js/src/structs/gas_fees.ts @@ -83,17 +83,6 @@ export class GasFees { return serializeToFields(this.feePerDaGas, this.feePerL2Gas); } - static fromJSON(obj: any) { - return new GasFees(Fr.fromString(obj.feePerDaGas), Fr.fromString(obj.feePerL2Gas)); - } - - toJSON() { - return { - feePerDaGas: this.feePerDaGas.toString(), - feePerL2Gas: this.feePerL2Gas.toString(), - }; - } - [inspect.custom]() { return `GasFees { feePerDaGas=${this.feePerDaGas} feePerL2Gas=${this.feePerL2Gas} }`; } diff --git a/yarn-project/circuits.js/src/structs/global_variables.ts b/yarn-project/circuits.js/src/structs/global_variables.ts index f49badfe8ff..914dc7b5fb6 100644 --- a/yarn-project/circuits.js/src/structs/global_variables.ts +++ b/yarn-project/circuits.js/src/structs/global_variables.ts @@ -1,6 +1,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; +import { jsonStringify } from '@aztec/foundation/json-rpc'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; import { type FieldsOf } from '@aztec/foundation/types'; @@ -84,19 +85,6 @@ export class GlobalVariables { ); } - static fromJSON(obj: any): GlobalVariables { - return new GlobalVariables( - Fr.fromString(obj.chainId), - Fr.fromString(obj.version), - Fr.fromString(obj.blockNumber), - Fr.fromString(obj.slotNumber), - Fr.fromString(obj.timestamp), - EthAddress.fromString(obj.coinbase), - AztecAddress.fromString(obj.feeRecipient), - GasFees.fromJSON(obj.gasFees), - ); - } - static fromFields(fields: Fr[] | FieldReader): GlobalVariables { const reader = FieldReader.asReader(fields); @@ -140,19 +128,6 @@ export class GlobalVariables { return fields; } - toJSON() { - return { - chainId: this.chainId.toString(), - version: this.version.toString(), - blockNumber: this.blockNumber.toString(), - slotNumber: this.slotNumber.toString(), - timestamp: this.timestamp.toString(), - coinbase: this.coinbase.toString(), - feeRecipient: this.feeRecipient.toString(), - gasFees: this.gasFees.toJSON(), - }; - } - /** * A trimmed version of the JSON representation of the global variables, * tailored for human consumption. @@ -163,7 +138,7 @@ export class GlobalVariables { slotNumber: this.slotNumber.toNumber(), timestamp: this.timestamp.toString(), coinbase: this.coinbase.toString(), - gasFees: this.gasFees.toJSON(), + gasFees: jsonStringify(this.gasFees), }; } diff --git a/yarn-project/circuits.js/src/structs/header.ts b/yarn-project/circuits.js/src/structs/header.ts index f31f85a2ef9..3a6220e9b94 100644 --- a/yarn-project/circuits.js/src/structs/header.ts +++ b/yarn-project/circuits.js/src/structs/header.ts @@ -2,6 +2,7 @@ import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { inspect } from 'util'; @@ -40,16 +41,6 @@ export class Header { .transform(Header.from); } - toJSON() { - return { - lastArchive: this.lastArchive, - contentCommitment: this.contentCommitment, - state: this.state, - globalVariables: this.globalVariables, - totalFees: this.totalFees, - }; - } - static getFields(fields: FieldsOf
) { // Note: The order here must match the order in the HeaderLib solidity library. return [ @@ -140,12 +131,11 @@ export class Header { * @returns Encoded string. */ public toString(): string { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(str: string): Header { - const buffer = Buffer.from(str.replace(/^0x/i, ''), 'hex'); - return Header.fromBuffer(buffer); + return Header.fromBuffer(hexToBuffer(str)); } hash(): Fr { diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts index a66c8742fa1..e9e33a073ac 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts @@ -1,8 +1,9 @@ import { type FieldsOf, makeTuple } from '@aztec/foundation/array'; import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; @@ -102,11 +103,11 @@ export class CombinedAccumulatedData { } static get schema() { - return hexSchemaFor(CombinedAccumulatedData); + return bufferSchemaFor(CombinedAccumulatedData); } toJSON() { - return this.toString(); + return this.toBuffer(); } toBuffer() { @@ -114,7 +115,7 @@ export class CombinedAccumulatedData { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -144,7 +145,7 @@ export class CombinedAccumulatedData { * @returns Deserialized object. */ static fromString(str: string) { - return CombinedAccumulatedData.fromBuffer(Buffer.from(str, 'hex')); + return CombinedAccumulatedData.fromBuffer(hexToBuffer(str)); } static empty() { diff --git a/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts index 2ec58bdd269..e5abfe011f1 100644 --- a/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts @@ -1,6 +1,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { Gas } from '../gas.js'; import { PartialStateReference } from '../partial_state_reference.js'; @@ -89,20 +90,20 @@ export class KernelCircuitPublicInputs { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(str: string) { - return KernelCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return KernelCircuitPublicInputs.fromBuffer(hexToBuffer(str)); } /** Returns a hex representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(KernelCircuitPublicInputs); + return bufferSchemaFor(KernelCircuitPublicInputs); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts index cc9a5aeab5f..08d739c0b3b 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts @@ -1,5 +1,6 @@ import { makeTuple } from '@aztec/foundation/array'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { MAX_ENCRYPTED_LOGS_PER_TX, @@ -75,7 +76,7 @@ export class PrivateAccumulatedData { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -103,7 +104,7 @@ export class PrivateAccumulatedData { * @returns Deserialized object. */ static fromString(str: string) { - return PrivateAccumulatedData.fromBuffer(Buffer.from(str, 'hex')); + return PrivateAccumulatedData.fromBuffer(hexToBuffer(str)); } static empty() { diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts index 1db065b1464..1839ce2c98d 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts @@ -1,6 +1,6 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { PrivateValidationRequests } from '../private_validation_requests.js'; @@ -40,11 +40,11 @@ export class PrivateKernelCircuitPublicInputs { ) {} static get schema() { - return hexSchemaFor(PrivateKernelCircuitPublicInputs); + return bufferSchemaFor(PrivateKernelCircuitPublicInputs); } toJSON() { - return '0x' + this.toBuffer().toString('hex'); + return this.toBuffer(); } toBuffer() { diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_empty_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_empty_inputs.ts index 85340aa1aff..4e225a1deab 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_empty_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_empty_inputs.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { type RECURSIVE_PROOF_LENGTH } from '../../constants.gen.js'; @@ -22,7 +23,7 @@ export class PrivateKernelEmptyInputData { } toString(): string { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromBuffer(buf: Buffer) { @@ -37,7 +38,7 @@ export class PrivateKernelEmptyInputData { } static fromString(str: string): PrivateKernelEmptyInputData { - return PrivateKernelEmptyInputData.fromBuffer(Buffer.from(str, 'hex')); + return PrivateKernelEmptyInputData.fromBuffer(hexToBuffer(str)); } static from(fields: FieldsOf) { @@ -50,14 +51,14 @@ export class PrivateKernelEmptyInputData { ); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(PrivateKernelEmptyInputData); + return bufferSchemaFor(PrivateKernelEmptyInputData); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts index 7ce5ae26c0d..d21a7590db9 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts @@ -1,6 +1,6 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { countAccumulatedItems, mergeAccumulatedData } from '../../utils/index.js'; @@ -131,11 +131,11 @@ export class PrivateKernelTailCircuitPublicInputs { } static get schema() { - return hexSchemaFor(PrivateKernelTailCircuitPublicInputs); + return bufferSchemaFor(PrivateKernelTailCircuitPublicInputs); } toJSON() { - return '0x' + this.toBuffer().toString('hex'); + return this.toBuffer(); } getSize() { diff --git a/yarn-project/circuits.js/src/structs/kernel/private_to_public_kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_to_public_kernel_circuit_public_inputs.ts index 7a93e0cee96..ed837be8084 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_to_public_kernel_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_to_public_kernel_circuit_public_inputs.ts @@ -1,5 +1,6 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { Gas } from '../gas.js'; import { PublicCallRequest } from '../public_call_request.js'; @@ -56,10 +57,10 @@ export class PrivateToPublicKernelCircuitPublicInputs { } static fromString(str: string) { - return PrivateToPublicKernelCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return PrivateToPublicKernelCircuitPublicInputs.fromBuffer(hexToBuffer(str)); } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts index 4a366853ebf..9ad329ca1ce 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts @@ -2,6 +2,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection'; import { type Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; @@ -99,7 +100,7 @@ export class PublicAccumulatedData { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } isEmpty(): boolean { @@ -196,7 +197,7 @@ export class PublicAccumulatedData { * @returns Deserialized object. */ static fromString(str: string) { - return this.fromBuffer(Buffer.from(str, 'hex')); + return this.fromBuffer(hexToBuffer(str)); } static empty() { @@ -257,7 +258,7 @@ export class PublicAccumulatedDataArrayLengths { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } isEmpty(): boolean { @@ -312,7 +313,7 @@ export class PublicAccumulatedDataArrayLengths { * @returns Deserialized object. */ static fromString(str: string) { - return this.fromBuffer(Buffer.from(str, 'hex')); + return this.fromBuffer(hexToBuffer(str)); } static empty() { diff --git a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts index 8d6cf987007..0e23e07f2c7 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts @@ -1,4 +1,5 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { EnqueuedCallData } from './enqueued_call_data.js'; import { PublicKernelData } from './public_kernel_data.js'; @@ -31,7 +32,7 @@ export class PublicKernelCircuitPrivateInputs { * @returns - Hex string representation of the object. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -52,7 +53,7 @@ export class PublicKernelCircuitPrivateInputs { * @returns - Deserialized object. */ static fromString(str: string) { - return PublicKernelCircuitPrivateInputs.fromBuffer(Buffer.from(str, 'hex')); + return PublicKernelCircuitPrivateInputs.fromBuffer(hexToBuffer(str)); } /** diff --git a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_public_inputs.ts index 04214ea5b02..01ada99ca31 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_public_inputs.ts @@ -1,6 +1,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { type Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; @@ -68,11 +69,11 @@ export class PublicKernelCircuitPublicInputs { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(str: string) { - return PublicKernelCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return PublicKernelCircuitPublicInputs.fromBuffer(hexToBuffer(str)); } /** diff --git a/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.ts index c0bb9b4d82f..44f49e6d05a 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.ts @@ -1,4 +1,5 @@ import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { L1_TO_L2_MSG_TREE_HEIGHT, @@ -60,11 +61,11 @@ export class PublicKernelTailCircuitPrivateInputs { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(str: string) { - return PublicKernelTailCircuitPrivateInputs.fromBuffer(Buffer.from(str, 'hex')); + return PublicKernelTailCircuitPrivateInputs.fromBuffer(hexToBuffer(str)); } static fromBuffer(buffer: Buffer | BufferReader) { diff --git a/yarn-project/circuits.js/src/structs/kernel/vm_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/vm_circuit_public_inputs.ts index 7182981a3cb..544abefd141 100644 --- a/yarn-project/circuits.js/src/structs/kernel/vm_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/vm_circuit_public_inputs.ts @@ -1,6 +1,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; @@ -53,11 +54,11 @@ export class VMCircuitPublicInputs { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(str: string) { - return VMCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return VMCircuitPublicInputs.fromBuffer(hexToBuffer(str)); } static fromBuffer(buffer: Buffer | BufferReader) { diff --git a/yarn-project/circuits.js/src/structs/parity/base_parity_inputs.ts b/yarn-project/circuits.js/src/structs/parity/base_parity_inputs.ts index 44a6804c840..a02b44025a3 100644 --- a/yarn-project/circuits.js/src/structs/parity/base_parity_inputs.ts +++ b/yarn-project/circuits.js/src/structs/parity/base_parity_inputs.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUM_MSGS_PER_BASE_PARITY } from '../../constants.gen.js'; @@ -30,7 +31,7 @@ export class BaseParityInputs { /** Serializes the inputs to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -48,16 +49,16 @@ export class BaseParityInputs { * @returns - The deserialized inputs. */ static fromString(str: string) { - return BaseParityInputs.fromBuffer(Buffer.from(str, 'hex')); + return BaseParityInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(BaseParityInputs); + return bufferSchemaFor(BaseParityInputs); } } diff --git a/yarn-project/circuits.js/src/structs/parity/parity_public_inputs.ts b/yarn-project/circuits.js/src/structs/parity/parity_public_inputs.ts index d0cd63e2565..1f2f3551c02 100644 --- a/yarn-project/circuits.js/src/structs/parity/parity_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/parity/parity_public_inputs.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; export class ParityPublicInputs { @@ -30,12 +31,12 @@ export class ParityPublicInputs { * @returns The inputs serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** @@ -72,10 +73,10 @@ export class ParityPublicInputs { * @returns A new ParityPublicInputs instance. */ static fromString(str: string) { - return ParityPublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return ParityPublicInputs.fromBuffer(hexToBuffer(str)); } static get schema() { - return hexSchemaFor(ParityPublicInputs); + return bufferSchemaFor(ParityPublicInputs); } } diff --git a/yarn-project/circuits.js/src/structs/parity/root_parity_input.ts b/yarn-project/circuits.js/src/structs/parity/root_parity_input.ts index aa26e28386e..e9b159b4387 100644 --- a/yarn-project/circuits.js/src/structs/parity/root_parity_input.ts +++ b/yarn-project/circuits.js/src/structs/parity/root_parity_input.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { VK_TREE_HEIGHT } from '../../constants.gen.js'; @@ -25,7 +26,7 @@ export class RootParityInput { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static from( @@ -55,16 +56,16 @@ export class RootParityInput { str: string, expectedSize?: PROOF_LENGTH, ): RootParityInput { - return RootParityInput.fromBuffer(Buffer.from(str, 'hex'), expectedSize); + return RootParityInput.fromBuffer(hexToBuffer(str), expectedSize); } /** Returns a hex representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string with expected size. */ static schemaFor(expectedSize?: N) { - return schemas.HexString.transform(str => RootParityInput.fromString(str, expectedSize)); + return schemas.Buffer.transform(buf => RootParityInput.fromBuffer(buf, expectedSize)); } } diff --git a/yarn-project/circuits.js/src/structs/parity/root_parity_inputs.ts b/yarn-project/circuits.js/src/structs/parity/root_parity_inputs.ts index aa74c1092f2..2b09078c755 100644 --- a/yarn-project/circuits.js/src/structs/parity/root_parity_inputs.ts +++ b/yarn-project/circuits.js/src/structs/parity/root_parity_inputs.ts @@ -1,5 +1,6 @@ -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { NUM_BASE_PARITY_PER_ROOT_PARITY, RECURSIVE_PROOF_LENGTH } from '../../constants.gen.js'; import { RootParityInput } from './root_parity_input.js'; @@ -26,7 +27,7 @@ export class RootParityInputs { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -50,16 +51,16 @@ export class RootParityInputs { * @returns A new RootParityInputs instance. */ static fromString(str: string) { - return RootParityInputs.fromBuffer(Buffer.from(str, 'hex')); + return RootParityInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(RootParityInputs); + return bufferSchemaFor(RootParityInputs); } } diff --git a/yarn-project/circuits.js/src/structs/partial_state_reference.ts b/yarn-project/circuits.js/src/structs/partial_state_reference.ts index fe484113835..7e212e71262 100644 --- a/yarn-project/circuits.js/src/structs/partial_state_reference.ts +++ b/yarn-project/circuits.js/src/structs/partial_state_reference.ts @@ -19,14 +19,6 @@ export class PartialStateReference { public readonly publicDataTree: AppendOnlyTreeSnapshot, ) {} - toJSON() { - return { - noteHashTree: this.noteHashTree, - nullifierTree: this.nullifierTree, - publicDataTree: this.publicDataTree, - }; - } - static get schema() { return z .object({ diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index fbd2ae24520..a557557c12c 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -1,6 +1,6 @@ import { makeTuple } from '@aztec/foundation/array'; import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, @@ -323,18 +323,10 @@ export class PrivateCircuitPublicInputs { } public toJSON() { - return this.toBuffer().toString('hex'); - } - - public static fromJSON(value: any) { - return PrivateCircuitPublicInputs.fromBuffer(Buffer.from(value, 'hex')); - } - - public static fromString(str: string) { - return PrivateCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return this.toBuffer(); } static get schema() { - return hexSchemaFor(PrivateCircuitPublicInputs); + return bufferSchemaFor(PrivateCircuitPublicInputs); } } diff --git a/yarn-project/circuits.js/src/structs/private_validation_requests.ts b/yarn-project/circuits.js/src/structs/private_validation_requests.ts index f026fbfacaf..3b8da4dc030 100644 --- a/yarn-project/circuits.js/src/structs/private_validation_requests.ts +++ b/yarn-project/circuits.js/src/structs/private_validation_requests.ts @@ -2,6 +2,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection'; import { type Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; @@ -69,7 +70,7 @@ export class PrivateValidationRequests { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromFields(fields: Fr[] | FieldReader) { @@ -105,7 +106,7 @@ export class PrivateValidationRequests { * @returns Deserialized object. */ static fromString(str: string) { - return PrivateValidationRequests.fromBuffer(Buffer.from(str, 'hex')); + return PrivateValidationRequests.fromBuffer(hexToBuffer(str)); } static empty() { diff --git a/yarn-project/circuits.js/src/structs/proof.ts b/yarn-project/circuits.js/src/structs/proof.ts index 57b57606df4..ec6af85223c 100644 --- a/yarn-project/circuits.js/src/structs/proof.ts +++ b/yarn-project/circuits.js/src/structs/proof.ts @@ -1,5 +1,6 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { AGGREGATION_OBJECT_LENGTH } from '../constants.gen.js'; @@ -61,7 +62,7 @@ export class Proof { * @returns The hex string representation of the proof data. */ public toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } public withoutPublicInputs(): Buffer { @@ -89,7 +90,7 @@ export class Proof { * @returns - A new Proof instance. */ static fromString(str: string) { - return Proof.fromBuffer(Buffer.from(str, 'hex')); + return Proof.fromBuffer(hexToBuffer(str)); } /** Returns whether this proof is actually empty. */ diff --git a/yarn-project/circuits.js/src/structs/public_data_write.ts b/yarn-project/circuits.js/src/structs/public_data_write.ts index 7f4c2e49ca4..001d14a7878 100644 --- a/yarn-project/circuits.js/src/structs/public_data_write.ts +++ b/yarn-project/circuits.js/src/structs/public_data_write.ts @@ -1,7 +1,7 @@ -import { STRING_ENCODING } from '@aztec/circuits.js'; import { Fr } from '@aztec/foundation/fields'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { z } from 'zod'; @@ -55,11 +55,11 @@ export class PublicDataWrite { } static fromString(str: string) { - return PublicDataWrite.fromBuffer(Buffer.from(str, STRING_ENCODING)); + return PublicDataWrite.fromBuffer(hexToBuffer(str)); } toString() { - return this.toBuffer().toString(STRING_ENCODING); + return bufferToHex(this.toBuffer()); } static empty() { diff --git a/yarn-project/circuits.js/src/structs/public_validation_requests.ts b/yarn-project/circuits.js/src/structs/public_validation_requests.ts index 4d45328914c..8aa2d354b70 100644 --- a/yarn-project/circuits.js/src/structs/public_validation_requests.ts +++ b/yarn-project/circuits.js/src/structs/public_validation_requests.ts @@ -2,6 +2,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection'; import { type Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; @@ -71,7 +72,7 @@ export class PublicValidationRequests { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromFields(fields: Fr[] | FieldReader) { @@ -109,7 +110,7 @@ export class PublicValidationRequests { * @returns Deserialized object. */ static fromString(str: string) { - return PublicValidationRequests.fromBuffer(Buffer.from(str, 'hex')); + return PublicValidationRequests.fromBuffer(hexToBuffer(str)); } static empty() { @@ -184,7 +185,7 @@ export class PublicValidationRequestArrayLengths { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromFields(fields: Fr[] | FieldReader) { @@ -220,7 +221,7 @@ export class PublicValidationRequestArrayLengths { * @returns Deserialized object. */ static fromString(str: string) { - return PublicValidationRequestArrayLengths.fromBuffer(Buffer.from(str, 'hex')); + return PublicValidationRequestArrayLengths.fromBuffer(hexToBuffer(str)); } static empty() { diff --git a/yarn-project/circuits.js/src/structs/recursive_proof.ts b/yarn-project/circuits.js/src/structs/recursive_proof.ts index ce5a3b0dcae..d1329ee857a 100644 --- a/yarn-project/circuits.js/src/structs/recursive_proof.ts +++ b/yarn-project/circuits.js/src/structs/recursive_proof.ts @@ -2,6 +2,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { Fr } from '@aztec/foundation/fields'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { Proof, makeEmptyProof } from './proof.js'; @@ -73,7 +74,7 @@ export class RecursiveProof { * @returns The hex string representation of the proof data. */ public toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -82,17 +83,17 @@ export class RecursiveProof { * @returns - A new Proof instance. */ static fromString(str: string, expectedSize?: N): RecursiveProof { - return RecursiveProof.fromBuffer(Buffer.from(str, 'hex'), expectedSize); + return RecursiveProof.fromBuffer(hexToBuffer(str), expectedSize); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string with expected size. */ static schemaFor(expectedSize?: N) { - return schemas.HexString.transform(str => RecursiveProof.fromString(str, expectedSize)); + return schemas.Buffer.transform(b => RecursiveProof.fromBuffer(b, expectedSize)); } } diff --git a/yarn-project/circuits.js/src/structs/revert_code.test.ts b/yarn-project/circuits.js/src/structs/revert_code.test.ts index e2188f7a93a..1fafefb47c4 100644 --- a/yarn-project/circuits.js/src/structs/revert_code.test.ts +++ b/yarn-project/circuits.js/src/structs/revert_code.test.ts @@ -1,10 +1,11 @@ import { Fr } from '@aztec/foundation/fields'; +import { jsonStringify } from '@aztec/foundation/json-rpc'; import { RevertCode } from './revert_code.js'; describe('revert_code', () => { it.each([RevertCode.OK, RevertCode.APP_LOGIC_REVERTED, RevertCode.TEARDOWN_REVERTED, RevertCode.BOTH_REVERTED])( - 'should serialize properly', + 'should serialize %s properly', revertCode => { expect(revertCode.getSerializedLength()).toBe(1); @@ -20,6 +21,9 @@ describe('revert_code', () => { expect(field).toMatchSnapshot(); expect(RevertCode.fromField(field)).toEqual(revertCode); expect(RevertCode.fromFields([field])).toEqual(revertCode); + + const json = jsonStringify(revertCode); + expect(RevertCode.schema.parse(JSON.parse(json))).toEqual(revertCode); }, ); diff --git a/yarn-project/circuits.js/src/structs/revert_code.ts b/yarn-project/circuits.js/src/structs/revert_code.ts index 55ac00d331c..7e4357f05ae 100644 --- a/yarn-project/circuits.js/src/structs/revert_code.ts +++ b/yarn-project/circuits.js/src/structs/revert_code.ts @@ -2,8 +2,9 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader } from '@aztec/foundation/serialize'; import { inspect } from 'util'; +import { z } from 'zod'; -enum RevertCodeEnum { +export enum RevertCodeEnum { OK = 0, APP_LOGIC_REVERTED = 1, TEARDOWN_REVERTED = 2, @@ -55,6 +56,14 @@ export class RevertCode { } } + public toJSON() { + return this.code; + } + + static get schema() { + return z.nativeEnum(RevertCodeEnum).transform(value => new RevertCode(value)); + } + /** * Having different serialization methods allows for * decoupling the serialization for producing the content commitment hash diff --git a/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts b/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts index b4c71e37be1..5a97560f2e9 100644 --- a/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts +++ b/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts @@ -1,11 +1,12 @@ import { Fr } from '@aztec/foundation/fields'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { inspect } from 'util'; import { z } from 'zod'; -import { STRING_ENCODING, type UInt32 } from '../shared.js'; +import { type UInt32 } from '../shared.js'; /** * Snapshot of an append only tree. @@ -39,10 +40,6 @@ export class AppendOnlyTreeSnapshot { .transform(({ root, nextAvailableLeafIndex }) => new AppendOnlyTreeSnapshot(root, nextAvailableLeafIndex)); } - toJSON() { - return { root: this.root, nextAvailableLeafIndex: this.nextAvailableLeafIndex }; - } - getSize() { return this.root.size + 4; } @@ -56,7 +53,7 @@ export class AppendOnlyTreeSnapshot { } toString(): string { - return this.toBuffer().toString(STRING_ENCODING); + return bufferToHex(this.toBuffer()); } static fromBuffer(buffer: Buffer | BufferReader): AppendOnlyTreeSnapshot { @@ -65,7 +62,7 @@ export class AppendOnlyTreeSnapshot { } static fromString(str: string): AppendOnlyTreeSnapshot { - return AppendOnlyTreeSnapshot.fromBuffer(Buffer.from(str, STRING_ENCODING)); + return AppendOnlyTreeSnapshot.fromBuffer(hexToBuffer(str)); } static fromFields(fields: Fr[] | FieldReader): AppendOnlyTreeSnapshot { diff --git a/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts index 981d1f0faa6..c42337e1c0f 100644 --- a/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { PartialStateReference } from '../partial_state_reference.js'; import { RollupTypes } from '../shared.js'; @@ -108,7 +109,7 @@ export class BaseOrMergeRollupPublicInputs { * @returns - The hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -117,16 +118,16 @@ export class BaseOrMergeRollupPublicInputs { * @returns A new BaseOrMergeRollupPublicInputs instance. */ static fromString(str: string) { - return BaseOrMergeRollupPublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return BaseOrMergeRollupPublicInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(BaseOrMergeRollupPublicInputs); + return bufferSchemaFor(BaseOrMergeRollupPublicInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup/base_rollup_hints.ts b/yarn-project/circuits.js/src/structs/rollup/base_rollup_hints.ts index 15364ffb636..a1b64d5466d 100644 --- a/yarn-project/circuits.js/src/structs/rollup/base_rollup_hints.ts +++ b/yarn-project/circuits.js/src/structs/rollup/base_rollup_hints.ts @@ -1,5 +1,6 @@ import { makeTuple } from '@aztec/foundation/array'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { @@ -89,7 +90,7 @@ export class BaseRollupHints { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromBuffer(buffer: Buffer | BufferReader): BaseRollupHints { @@ -110,7 +111,7 @@ export class BaseRollupHints { } static fromString(str: string) { - return BaseRollupHints.fromBuffer(Buffer.from(str, 'hex')); + return BaseRollupHints.fromBuffer(hexToBuffer(str)); } static empty() { diff --git a/yarn-project/circuits.js/src/structs/rollup/block_merge_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/block_merge_rollup.ts index 6732a4ffadf..e134ad16ba0 100644 --- a/yarn-project/circuits.js/src/structs/rollup/block_merge_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/block_merge_rollup.ts @@ -1,5 +1,6 @@ -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { PreviousRollupBlockData } from './previous_rollup_block_data.js'; @@ -27,7 +28,7 @@ export class BlockMergeRollupInputs { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -49,16 +50,16 @@ export class BlockMergeRollupInputs { * @returns A new BlockMergeRollupInputs instance. */ static fromString(str: string) { - return BlockMergeRollupInputs.fromBuffer(Buffer.from(str, 'hex')); + return BlockMergeRollupInputs.fromBuffer(hexToBuffer(str)); } /** Returns a hex representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(BlockMergeRollupInputs); + return bufferSchemaFor(BlockMergeRollupInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup/block_root_or_block_merge_public_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/block_root_or_block_merge_public_inputs.ts index 639f335b760..00eeb3666a7 100644 --- a/yarn-project/circuits.js/src/structs/rollup/block_root_or_block_merge_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/rollup/block_root_or_block_merge_public_inputs.ts @@ -1,7 +1,8 @@ import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, type Tuple, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { AZTEC_MAX_EPOCH_DURATION } from '../../constants.gen.js'; @@ -107,7 +108,7 @@ export class BlockRootOrBlockMergePublicInputs { * @returns - The hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -116,17 +117,17 @@ export class BlockRootOrBlockMergePublicInputs { * @returns A new BaseOrMergeRollupPublicInputs instance. */ static fromString(str: string) { - return BlockRootOrBlockMergePublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return BlockRootOrBlockMergePublicInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(BlockRootOrBlockMergePublicInputs); + return bufferSchemaFor(BlockRootOrBlockMergePublicInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup/block_root_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/block_root_rollup.ts index 3a63c40ddb3..18c1c289cb2 100644 --- a/yarn-project/circuits.js/src/structs/rollup/block_root_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/block_root_rollup.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { @@ -69,7 +70,7 @@ export class BlockRootRollupInputs { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -126,16 +127,16 @@ export class BlockRootRollupInputs { * @returns A new RootRollupInputs instance. */ static fromString(str: string) { - return BlockRootRollupInputs.fromBuffer(Buffer.from(str, 'hex')); + return BlockRootRollupInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(BlockRootRollupInputs); + return bufferSchemaFor(BlockRootRollupInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup/empty_block_root_rollup_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/empty_block_root_rollup_inputs.ts index ba42802e1ae..f4355e835a7 100644 --- a/yarn-project/circuits.js/src/structs/rollup/empty_block_root_rollup_inputs.ts +++ b/yarn-project/circuits.js/src/structs/rollup/empty_block_root_rollup_inputs.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { GlobalVariables } from '../global_variables.js'; @@ -33,7 +34,7 @@ export class EmptyBlockRootRollupInputs { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -84,16 +85,16 @@ export class EmptyBlockRootRollupInputs { * @returns A new RootRollupInputs instance. */ static fromString(str: string) { - return EmptyBlockRootRollupInputs.fromBuffer(Buffer.from(str, 'hex')); + return EmptyBlockRootRollupInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } - /** Creates an instance from a hex string. */ + /** Creates an instance from a buffer string. */ static get schema() { - return hexSchemaFor(EmptyBlockRootRollupInputs); + return bufferSchemaFor(EmptyBlockRootRollupInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts index 2950f2f1614..2b38a5f6188 100644 --- a/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts @@ -1,5 +1,6 @@ -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { PreviousRollupData } from './previous_rollup_data.js'; @@ -27,7 +28,7 @@ export class MergeRollupInputs { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -46,16 +47,16 @@ export class MergeRollupInputs { * @returns A new MergeRollupInputs instance. */ static fromString(str: string) { - return MergeRollupInputs.fromBuffer(Buffer.from(str, 'hex')); + return MergeRollupInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } - /** Creates an instance from a hex string. */ + /** Creates an instance from a string. */ static get schema() { - return hexSchemaFor(MergeRollupInputs); + return bufferSchemaFor(MergeRollupInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup/private_base_rollup_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/private_base_rollup_inputs.ts index 5cc93fdeb4e..b73f8a5620a 100644 --- a/yarn-project/circuits.js/src/structs/rollup/private_base_rollup_inputs.ts +++ b/yarn-project/circuits.js/src/structs/rollup/private_base_rollup_inputs.ts @@ -1,5 +1,6 @@ -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor, hexSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { BaseRollupHints } from './base_rollup_hints.js'; @@ -26,24 +27,24 @@ export class PrivateBaseRollupInputs { } static fromString(str: string) { - return PrivateBaseRollupInputs.fromBuffer(Buffer.from(str, 'hex')); + return PrivateBaseRollupInputs.fromBuffer(hexToBuffer(str)); } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static empty() { return new PrivateBaseRollupInputs(PrivateTubeData.empty(), BaseRollupHints.empty()); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a buffer representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(PrivateBaseRollupInputs); + return bufferSchemaFor(PrivateBaseRollupInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup/public_base_rollup_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/public_base_rollup_inputs.ts index b8ab34a167f..2768795da2b 100644 --- a/yarn-project/circuits.js/src/structs/rollup/public_base_rollup_inputs.ts +++ b/yarn-project/circuits.js/src/structs/rollup/public_base_rollup_inputs.ts @@ -1,5 +1,6 @@ -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { AvmProofData } from './avm_proof_data.js'; @@ -29,25 +30,26 @@ export class PublicBaseRollupInputs { toBuffer() { return serializeToBuffer(...PublicBaseRollupInputs.getFields(this)); } + static fromString(str: string) { - return PublicBaseRollupInputs.fromBuffer(Buffer.from(str, 'hex')); + return PublicBaseRollupInputs.fromBuffer(hexToBuffer(str)); } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static empty() { return new PublicBaseRollupInputs(PublicTubeData.empty(), AvmProofData.empty(), BaseRollupHints.empty()); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } - /** Creates an instance from a hex string. */ + /** Creates an instance from a string. */ static get schema() { - return hexSchemaFor(PublicBaseRollupInputs); + return bufferSchemaFor(PublicBaseRollupInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts index a8eb8b433e5..180bfbdcc30 100644 --- a/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, type Tuple, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { AZTEC_MAX_EPOCH_DURATION } from '../../constants.gen.js'; @@ -36,7 +37,7 @@ export class RootRollupInputs { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -76,17 +77,17 @@ export class RootRollupInputs { * @returns A new RootRollupInputs instance. */ static fromString(str: string) { - return RootRollupInputs.fromBuffer(Buffer.from(str, 'hex')); + return RootRollupInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } - /** Creates an instance from a hex string. */ + /** Creates an instance from a string. */ static get schema() { - return hexSchemaFor(RootRollupInputs); + return bufferSchemaFor(RootRollupInputs); } } @@ -163,20 +164,20 @@ export class RootRollupPublicInputs { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(str: string) { - return RootRollupPublicInputs.fromBuffer(Buffer.from(str, 'hex')); + return RootRollupPublicInputs.fromBuffer(hexToBuffer(str)); } - /** Returns a hex representation for JSON serialization. */ + /** Returns a representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } - /** Creates an instance from a hex string. */ + /** Creates an instance from a string. */ static get schema() { - return hexSchemaFor(RootRollupPublicInputs); + return bufferSchemaFor(RootRollupPublicInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup/tube_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/tube_inputs.ts index 0320d0ec228..86a58efbaf8 100644 --- a/yarn-project/circuits.js/src/structs/rollup/tube_inputs.ts +++ b/yarn-project/circuits.js/src/structs/rollup/tube_inputs.ts @@ -1,5 +1,6 @@ -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { ClientIvcProof } from '../client_ivc_proof.js'; @@ -28,7 +29,7 @@ export class TubeInputs { * @returns The instance serialized to a hex string. */ toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** @@ -50,7 +51,7 @@ export class TubeInputs { * @returns A new TubeInputs instance. */ static fromString(str: string) { - return TubeInputs.fromBuffer(Buffer.from(str, 'hex')); + return TubeInputs.fromBuffer(hexToBuffer(str)); } static empty() { @@ -59,11 +60,11 @@ export class TubeInputs { /** Returns a hex representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(TubeInputs); + return bufferSchemaFor(TubeInputs); } } diff --git a/yarn-project/circuits.js/src/structs/rollup_validation_requests.ts b/yarn-project/circuits.js/src/structs/rollup_validation_requests.ts index 4113649893d..2d2279b8c88 100644 --- a/yarn-project/circuits.js/src/structs/rollup_validation_requests.ts +++ b/yarn-project/circuits.js/src/structs/rollup_validation_requests.ts @@ -1,5 +1,6 @@ import { type Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { MaxBlockNumber } from './max_block_number.js'; @@ -23,7 +24,7 @@ export class RollupValidationRequests { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromFields(fields: Fr[] | FieldReader) { @@ -47,7 +48,7 @@ export class RollupValidationRequests { * @returns Deserialized object. */ static fromString(str: string) { - return RollupValidationRequests.fromBuffer(Buffer.from(str, 'hex')); + return RollupValidationRequests.fromBuffer(hexToBuffer(str)); } static empty() { diff --git a/yarn-project/circuits.js/src/structs/shared.ts b/yarn-project/circuits.js/src/structs/shared.ts index c8cce1576fe..ae40dd95953 100644 --- a/yarn-project/circuits.js/src/structs/shared.ts +++ b/yarn-project/circuits.js/src/structs/shared.ts @@ -43,8 +43,3 @@ export enum RollupTypes { Merge = 1, Root = 2, } - -/** - * String encoding of serialized buffer data - */ -export const STRING_ENCODING: BufferEncoding = 'hex'; diff --git a/yarn-project/circuits.js/src/structs/state_reference.ts b/yarn-project/circuits.js/src/structs/state_reference.ts index 8f0c1fd0be0..49e91ac5324 100644 --- a/yarn-project/circuits.js/src/structs/state_reference.ts +++ b/yarn-project/circuits.js/src/structs/state_reference.ts @@ -19,10 +19,6 @@ export class StateReference { public partial: PartialStateReference, ) {} - toJSON() { - return { l1ToL2MessageTree: this.l1ToL2MessageTree, partial: this.partial }; - } - static get schema() { return z .object({ diff --git a/yarn-project/circuits.js/src/structs/trees/nullifier_leaf.ts b/yarn-project/circuits.js/src/structs/trees/nullifier_leaf.ts index 8d561e1ebfb..52b8be14aec 100644 --- a/yarn-project/circuits.js/src/structs/trees/nullifier_leaf.ts +++ b/yarn-project/circuits.js/src/structs/trees/nullifier_leaf.ts @@ -38,14 +38,6 @@ export class NullifierLeafPreimage implements IndexedTreeLeafPreimage { ); } - toJSON() { - return { - nullifier: this.nullifier.toString(), - nextNullifier: this.nextNullifier.toString(), - nextIndex: '0x' + this.nextIndex.toString(16), - }; - } - getKey(): bigint { return this.nullifier.toBigInt(); } @@ -102,14 +94,6 @@ export class NullifierLeafPreimage implements IndexedTreeLeafPreimage { static clone(preimage: NullifierLeafPreimage): NullifierLeafPreimage { return new NullifierLeafPreimage(preimage.nullifier, preimage.nextNullifier, preimage.nextIndex); } - - static fromJSON(json: any): NullifierLeafPreimage { - return new NullifierLeafPreimage( - Fr.fromString(json.nullifier), - Fr.fromString(json.nextNullifier), - BigInt(json.nextIndex), - ); - } } /** diff --git a/yarn-project/circuits.js/src/structs/tx_context.ts b/yarn-project/circuits.js/src/structs/tx_context.ts index 526ff0860ef..33234b4417a 100644 --- a/yarn-project/circuits.js/src/structs/tx_context.ts +++ b/yarn-project/circuits.js/src/structs/tx_context.ts @@ -37,14 +37,6 @@ export class TxContext { .transform(TxContext.from); } - toJSON() { - return { - chainId: this.chainId, - version: this.version, - gasSettings: this.gasSettings, - }; - } - getSize() { return this.chainId.size + this.version.size + this.gasSettings.getSize(); } diff --git a/yarn-project/circuits.js/src/structs/verification_key.ts b/yarn-project/circuits.js/src/structs/verification_key.ts index 22aa2d68e04..f3fc4a27610 100644 --- a/yarn-project/circuits.js/src/structs/verification_key.ts +++ b/yarn-project/circuits.js/src/structs/verification_key.ts @@ -1,8 +1,9 @@ import { makeTuple } from '@aztec/foundation/array'; import { times } from '@aztec/foundation/collection'; import { Fq, Fr } from '@aztec/foundation/fields'; -import { hexSchemaFor } from '@aztec/foundation/schemas'; +import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS } from '../constants.gen.js'; import { CircuitType } from './shared.js'; @@ -100,11 +101,11 @@ export class VerificationKeyAsFields { static get schema() { // TODO(palla/schemas): Should we verify the hash matches the key when deserializing? - return hexSchemaFor(VerificationKeyAsFields); + return bufferSchemaFor(VerificationKeyAsFields); } toJSON() { - return '0x' + this.toBuffer().toString('hex'); + return this.toBuffer(); } /** @@ -261,7 +262,7 @@ export class VerificationKeyData { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromBuffer(buffer: Buffer | BufferReader): VerificationKeyData { @@ -273,7 +274,7 @@ export class VerificationKeyData { } static fromString(str: string): VerificationKeyData { - return VerificationKeyData.fromBuffer(Buffer.from(str, 'hex')); + return VerificationKeyData.fromBuffer(hexToBuffer(str)); } public clone() { @@ -282,11 +283,11 @@ export class VerificationKeyData { /** Returns a hex representation for JSON serialization. */ toJSON() { - return this.toString(); + return this.toBuffer(); } /** Creates an instance from a hex string. */ static get schema() { - return hexSchemaFor(VerificationKeyData); + return bufferSchemaFor(VerificationKeyData); } } diff --git a/yarn-project/circuits.js/src/structs/vk_witness_data.ts b/yarn-project/circuits.js/src/structs/vk_witness_data.ts index 723475b5fa2..2a79545973d 100644 --- a/yarn-project/circuits.js/src/structs/vk_witness_data.ts +++ b/yarn-project/circuits.js/src/structs/vk_witness_data.ts @@ -1,6 +1,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { Fr } from '@aztec/foundation/fields'; -import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { BufferReader, serializeToBuffer, type Tuple } from '@aztec/foundation/serialize'; +import { bufferToHex } from '@aztec/foundation/string'; import { VK_TREE_HEIGHT } from '../constants.gen.js'; import { type UInt32 } from './shared.js'; @@ -37,6 +38,6 @@ export class VkWitnessData { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } } diff --git a/yarn-project/circuits.js/src/types/public_keys.ts b/yarn-project/circuits.js/src/types/public_keys.ts index 321fc04c7a3..d426ab2f3b8 100644 --- a/yarn-project/circuits.js/src/types/public_keys.ts +++ b/yarn-project/circuits.js/src/types/public_keys.ts @@ -2,6 +2,7 @@ import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto'; import { Fr, Point } from '@aztec/foundation/fields'; import { schemas } from '@aztec/foundation/schemas'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { bufferToHex } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; import { z } from 'zod'; @@ -184,7 +185,7 @@ export class PublicKeys { } toString() { - return this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } static fromString(keys: string) { diff --git a/yarn-project/cli-wallet/src/cmds/cancel_tx.ts b/yarn-project/cli-wallet/src/cmds/cancel_tx.ts index c0fb4812f77..2d6ae924075 100644 --- a/yarn-project/cli-wallet/src/cmds/cancel_tx.ts +++ b/yarn-project/cli-wallet/src/cmds/cancel_tx.ts @@ -45,7 +45,7 @@ export async function cancelTx( log(` Tx fee: ${cancelReceipt.transactionFee}`); log(` Status: ${cancelReceipt.status}`); log(` Block number: ${cancelReceipt.blockNumber}`); - log(` Block hash: ${cancelReceipt.blockHash?.toString('hex')}`); + log(` Block hash: ${cancelReceipt.blockHash?.toString()}`); } catch (err: any) { log(`Could not cancel transaction\n ${err.message}`); } diff --git a/yarn-project/cli-wallet/src/cmds/send.ts b/yarn-project/cli-wallet/src/cmds/send.ts index fa6af43fa93..b87097ec125 100644 --- a/yarn-project/cli-wallet/src/cmds/send.ts +++ b/yarn-project/cli-wallet/src/cmds/send.ts @@ -42,7 +42,7 @@ export async function send( log(` Tx fee: ${receipt.transactionFee}`); log(` Status: ${receipt.status}`); log(` Block number: ${receipt.blockNumber}`); - log(` Block hash: ${receipt.blockHash?.toString('hex')}`); + log(` Block hash: ${receipt.blockHash?.toString()}`); } catch (err: any) { log(`Transaction failed\n ${err.message}`); } diff --git a/yarn-project/cli/src/utils/inspect.ts b/yarn-project/cli/src/utils/inspect.ts index 445e48c3bd1..212a5625fe2 100644 --- a/yarn-project/cli/src/utils/inspect.ts +++ b/yarn-project/cli/src/utils/inspect.ts @@ -57,7 +57,7 @@ export async function inspectTx( const artifactMap = opts?.artifactMap ?? (await getKnownArtifacts(pxe)); if (opts.includeBlockInfo) { - log(` Block: ${receipt.blockNumber} (${receipt.blockHash?.toString('hex')})`); + log(` Block: ${receipt.blockNumber} (${receipt.blockHash?.toString()})`); } if (receipt.transactionFee) { log(` Fee: ${receipt.transactionFee.toString()}`); diff --git a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts index 9007b2e0f7a..eedda40ef52 100644 --- a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts @@ -263,7 +263,7 @@ export class FullProverTest { // The simulated prover node (now shutdown) used private key index 2 const proverNodePrivateKey = getPrivateKeyFromIndex(2); - const proverNodeSenderAddress = privateKeyToAddress(new Buffer32(proverNodePrivateKey!).to0xString()); + const proverNodeSenderAddress = privateKeyToAddress(new Buffer32(proverNodePrivateKey!).toString()); this.proverAddress = EthAddress.fromString(proverNodeSenderAddress); this.logger.verbose(`Funding prover node at ${proverNodeSenderAddress}`); diff --git a/yarn-project/end-to-end/src/prover-coordination/e2e_prover_coordination.test.ts b/yarn-project/end-to-end/src/prover-coordination/e2e_prover_coordination.test.ts index e53a6327309..5f09eb625ed 100644 --- a/yarn-project/end-to-end/src/prover-coordination/e2e_prover_coordination.test.ts +++ b/yarn-project/end-to-end/src/prover-coordination/e2e_prover_coordination.test.ts @@ -111,7 +111,7 @@ describe('e2e_prover_coordination', () => { const proverKey = Buffer32.random(); proverSigner = new Secp256k1Signer(proverKey); proverWallet = createWalletClient({ - account: privateKeyToAccount(proverKey.to0xString()), + account: privateKeyToAccount(proverKey.toString()), chain: foundry, transport: http(ctx.aztecNodeConfig.l1RpcUrl), }); diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts index b58d5cc5527..78dd1c11246 100644 --- a/yarn-project/foundation/src/abi/abi.ts +++ b/yarn-project/foundation/src/abi/abi.ts @@ -230,7 +230,7 @@ export interface FunctionArtifact extends FunctionAbi { export const FunctionArtifactSchema = FunctionAbiSchema.and( z.object({ - bytecode: schemas.BufferB64, + bytecode: schemas.Buffer, verificationKey: z.string().optional(), debugSymbols: z.string(), debug: FunctionDebugMetadataSchema.optional(), diff --git a/yarn-project/foundation/src/abi/event_selector.ts b/yarn-project/foundation/src/abi/event_selector.ts index ea4d8bd234c..0203d562380 100644 --- a/yarn-project/foundation/src/abi/event_selector.ts +++ b/yarn-project/foundation/src/abi/event_selector.ts @@ -1,6 +1,7 @@ import { fromHex, toBigIntBE } from '../bigint-buffer/index.js'; import { poseidon2HashBytes, randomBytes } from '../crypto/index.js'; import { type Fr } from '../fields/fields.js'; +import { hexSchemaFor } from '../schemas/utils.js'; import { BufferReader } from '../serialize/buffer_reader.js'; import { Selector } from './selector.js'; @@ -83,9 +84,10 @@ export class EventSelector extends Selector { } toJSON() { - return { - type: 'EventSelector', - value: this.toString(), - }; + return this.toString(); + } + + static get schema() { + return hexSchemaFor(EventSelector); } } diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts index 7641234f9ab..00b75d1b500 100644 --- a/yarn-project/foundation/src/abi/function_selector.ts +++ b/yarn-project/foundation/src/abi/function_selector.ts @@ -1,6 +1,7 @@ import { fromHex, toBigIntBE } from '../bigint-buffer/index.js'; import { poseidon2HashBytes, randomBytes } from '../crypto/index.js'; import { type Fr } from '../fields/fields.js'; +import { hexSchemaFor } from '../schemas/utils.js'; import { BufferReader } from '../serialize/buffer_reader.js'; import { FieldReader } from '../serialize/field_reader.js'; import { TypeRegistry } from '../serialize/type_registry.js'; @@ -132,10 +133,11 @@ export class FunctionSelector extends Selector { } toJSON() { - return { - type: 'FunctionSelector', - value: this.toString(), - }; + return this.toString(); + } + + static get schema() { + return hexSchemaFor(FunctionSelector); } } diff --git a/yarn-project/foundation/src/abi/note_selector.ts b/yarn-project/foundation/src/abi/note_selector.ts index 392399f7ee1..70e3e8cd105 100644 --- a/yarn-project/foundation/src/abi/note_selector.ts +++ b/yarn-project/foundation/src/abi/note_selector.ts @@ -1,6 +1,7 @@ import { toBigIntBE } from '../bigint-buffer/index.js'; import { randomBytes } from '../crypto/index.js'; import { type Fr } from '../fields/fields.js'; +import { hexSchemaFor } from '../schemas/utils.js'; import { BufferReader } from '../serialize/buffer_reader.js'; import { TypeRegistry } from '../serialize/type_registry.js'; import { Selector } from './selector.js'; @@ -58,14 +59,11 @@ export class NoteSelector extends Selector { } toJSON() { - return { - type: 'NoteSelector', - value: this.toString(), - }; + return this.toString(); } - static fromJSON(json: any): NoteSelector { - return NoteSelector.fromString(json.value); + static get schema() { + return hexSchemaFor(NoteSelector); } } diff --git a/yarn-project/foundation/src/abi/selector.ts b/yarn-project/foundation/src/abi/selector.ts index e8f56e01093..9ee416654b3 100644 --- a/yarn-project/foundation/src/abi/selector.ts +++ b/yarn-project/foundation/src/abi/selector.ts @@ -2,6 +2,7 @@ import { inspect } from 'util'; import { toBufferBE } from '../bigint-buffer/index.js'; import { Fr } from '../fields/index.js'; +import { bufferToHex } from '../string/index.js'; /** A selector is the first 4 bytes of the hash of a signature. */ export abstract class Selector { @@ -36,7 +37,7 @@ export abstract class Selector { * @returns The string. */ toString(): string { - return '0x' + this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } [inspect.custom]() { diff --git a/yarn-project/foundation/src/aztec-address/index.ts b/yarn-project/foundation/src/aztec-address/index.ts index fb64a0ecd25..8188750f5f4 100644 --- a/yarn-project/foundation/src/aztec-address/index.ts +++ b/yarn-project/foundation/src/aztec-address/index.ts @@ -2,6 +2,7 @@ import { inspect } from 'util'; import { Fr, fromBuffer } from '../fields/index.js'; +import { hexSchemaFor } from '../schemas/utils.js'; import { type BufferReader, FieldReader } from '../serialize/index.js'; import { TypeRegistry } from '../serialize/type_registry.js'; import { hexToBuffer } from '../string/index.js'; @@ -102,10 +103,11 @@ export class AztecAddress { } toJSON() { - return { - type: 'AztecAddress', - value: this.toString(), - }; + return this.toString(); + } + + static get schema() { + return hexSchemaFor(AztecAddress, AztecAddress.isAddress); } } diff --git a/yarn-project/foundation/src/buffer/buffer32.ts b/yarn-project/foundation/src/buffer/buffer32.ts index 4b1c2e1c25d..799df3f27ec 100644 --- a/yarn-project/foundation/src/buffer/buffer32.ts +++ b/yarn-project/foundation/src/buffer/buffer32.ts @@ -2,6 +2,8 @@ import { randomBytes } from '@aztec/foundation/crypto'; import { type Fr } from '@aztec/foundation/fields'; import { BufferReader, deserializeBigInt, serializeBigInt } from '@aztec/foundation/serialize'; +import { bufferToHex } from '../string/index.js'; + /** * A class representing a 32 byte Buffer. */ @@ -67,17 +69,13 @@ export class Buffer32 { * @returns The hex string. */ public toString() { - return this.buffer.toString('hex'); + return bufferToHex(this.buffer); } toJSON() { return this.toString(); } - public to0xString(): `0x${string}` { - return `0x${this.buffer.toString('hex')}`; - } - /** * Convert this hash to a big int. * @returns The big int. @@ -117,18 +115,6 @@ export class Buffer32 { * @param str - The TX hash in string format. * @returns A new Buffer32 object. */ - public static fromStringUnchecked(str: string): Buffer32 { - return new Buffer32(Buffer.from(str, 'hex')); - } - - /** - * Converts a string into a Buffer32 object. - * NOTE: this method includes checks for the 0x prefix and the length of the string. - * if you dont need this checks, use fromStringUnchecked instead. - * - * @param str - The TX hash in string format. - * @returns A new Buffer32 object. - */ public static fromString(str: string): Buffer32 { if (str.startsWith('0x')) { str = str.slice(2); diff --git a/yarn-project/foundation/src/crypto/secp256k1-signer/secp256k1_signer.test.ts b/yarn-project/foundation/src/crypto/secp256k1-signer/secp256k1_signer.test.ts index 707227208f2..05c9d12fdc7 100644 --- a/yarn-project/foundation/src/crypto/secp256k1-signer/secp256k1_signer.test.ts +++ b/yarn-project/foundation/src/crypto/secp256k1-signer/secp256k1_signer.test.ts @@ -31,13 +31,13 @@ describe('Secp256k1Signer', () => { const ethHashedMessage = hashMessage({ raw: message }); const ethHashedMessageBuffer = Buffer32.fromBuffer(Buffer.from(ethHashedMessage.slice(2), 'hex')); - const viemSignature = Signature.from0xString(await viemSigner.signMessage({ message: { raw: message } })); + const viemSignature = Signature.fromString(await viemSigner.signMessage({ message: { raw: message } })); const lightSignature = lightSigner.sign(ethHashedMessageBuffer); // Check signatures match expect(viemSignature.equals(lightSignature)).toBe(true); - const viemPublicKey = await viemRecoverPublicKey({ hash: ethHashedMessage, signature: viemSignature.to0xString() }); + const viemPublicKey = await viemRecoverPublicKey({ hash: ethHashedMessage, signature: viemSignature.toString() }); const lightPublicKey = lightRecoverPublicKey(ethHashedMessageBuffer, lightSignature); // Check recovered public keys match @@ -46,7 +46,7 @@ describe('Secp256k1Signer', () => { // Get the eth address can be recovered from the message and signature const viemPublicKeyToAddress = publicKeyToAddress(viemPublicKey); const viemAddress = EthAddress.fromString( - await viemRecoverAddress({ hash: ethHashedMessage, signature: viemSignature.to0xString() }), + await viemRecoverAddress({ hash: ethHashedMessage, signature: viemSignature.toString() }), ); const lightAddress = lightRecoverAddress( Buffer32.fromBuffer(Buffer.from(ethHashedMessage.slice(2), 'hex')), diff --git a/yarn-project/foundation/src/eth-address/index.ts b/yarn-project/foundation/src/eth-address/index.ts index f30e61a0230..ed9acffbb5b 100644 --- a/yarn-project/foundation/src/eth-address/index.ts +++ b/yarn-project/foundation/src/eth-address/index.ts @@ -3,8 +3,10 @@ import { inspect } from 'util'; import { keccak256String } from '../crypto/keccak/index.js'; import { randomBytes } from '../crypto/random/index.js'; import { Fr } from '../fields/index.js'; +import { hexSchemaFor } from '../schemas/utils.js'; import { BufferReader, FieldReader } from '../serialize/index.js'; import { TypeRegistry } from '../serialize/type_registry.js'; +import { bufferToHex } from '../string/index.js'; /** * Represents an Ethereum address as a 20-byte buffer and provides various utility methods @@ -154,7 +156,7 @@ export class EthAddress { * @returns A hex-encoded string representation of the Ethereum address. */ public toString() { - return `0x${this.buffer.toString('hex')}` as `0x${string}`; + return bufferToHex(this.buffer); } [inspect.custom]() { @@ -226,19 +228,12 @@ export class EthAddress { return new EthAddress(reader.readBytes(EthAddress.SIZE_IN_BYTES)); } - /** - * Friendly representation for debugging purposes. - * @returns A hex string representing the address. - */ - toFriendlyJSON() { + toJSON() { return this.toString(); } - toJSON() { - return { - type: 'EthAddress', - value: this.toString(), - }; + static get schema() { + return hexSchemaFor(EthAddress, EthAddress.isAddress); } } diff --git a/yarn-project/foundation/src/eth-signature/eth_signature.test.ts b/yarn-project/foundation/src/eth-signature/eth_signature.test.ts index 2a2fd690184..ec76be5b6fa 100644 --- a/yarn-project/foundation/src/eth-signature/eth_signature.test.ts +++ b/yarn-project/foundation/src/eth-signature/eth_signature.test.ts @@ -25,15 +25,15 @@ describe('eth signature', () => { expect(deserialized).toEqual(serialized); }; - it('should serialize / deserialize to buffer', () => { + it('should serialize and deserialize to buffer', () => { const serialized = signature.toBuffer(); const deserialized = Signature.fromBuffer(serialized); checkEquivalence(signature, deserialized); }); - it('should serialize / deserialize real signature to hex string', () => { - const serialized = signature.to0xString(); - const deserialized = Signature.from0xString(serialized); + it('should serialize and deserialize real signature to hex string', () => { + const serialized = signature.toString(); + const deserialized = Signature.fromString(serialized); checkEquivalence(signature, deserialized); }); @@ -42,24 +42,24 @@ describe('eth signature', () => { expect(sender).toEqual(signer.address); }); - it('should serialize / deserialize to hex string with v=0', () => { + it('should serialize and deserialize to hex string with v=0', () => { const signature = new Signature(Buffer32.random(), Buffer32.random(), 0, false); - const serialized = signature.to0xString(); - const deserialized = Signature.from0xString(serialized); + const serialized = signature.toString(); + const deserialized = Signature.fromString(serialized); checkEquivalence(signature, deserialized); }); - it('should serialize / deserialize to hex string with 1-digit v', () => { + it('should serialize and deserialize to hex string with 1-digit v', () => { const signature = new Signature(Buffer32.random(), Buffer32.random(), 1, false); - const serialized = signature.to0xString(); - const deserialized = Signature.from0xString(serialized); + const serialized = signature.toString(); + const deserialized = Signature.fromString(serialized); checkEquivalence(signature, deserialized); }); - it('should serialize / deserialize to hex string with 2-digit v', () => { + it('should serialize and deserialize to hex string with 2-digit v', () => { const signature = new Signature(Buffer32.random(), Buffer32.random(), 26, false); - const serialized = signature.to0xString(); - const deserialized = Signature.from0xString(serialized); + const serialized = signature.toString(); + const deserialized = Signature.fromString(serialized); checkEquivalence(signature, deserialized); }); }); diff --git a/yarn-project/foundation/src/eth-signature/eth_signature.ts b/yarn-project/foundation/src/eth-signature/eth_signature.ts index 521cf680e9e..dec046702d0 100644 --- a/yarn-project/foundation/src/eth-signature/eth_signature.ts +++ b/yarn-project/foundation/src/eth-signature/eth_signature.ts @@ -1,6 +1,10 @@ import { Buffer32 } from '@aztec/foundation/buffer'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { z } from 'zod'; + +import { hasHexPrefix, hexToBuffer } from '../string/index.js'; + /**Viem Signature * * A version of the Signature class that uses `0x${string}` values for r and s rather than @@ -45,7 +49,7 @@ export class Signature { return new Signature(r, s, v, isEmpty); } - static isValid0xString(sig: `0x${string}`): boolean { + static isValidString(sig: `0x${string}`): boolean { return /^0x[0-9a-f]{129,}$/i.test(sig); } @@ -54,10 +58,9 @@ export class Signature { * parsing from viem, we can expect the v value to be a u8, rather than our * default serialization of u32 */ - static from0xString(sig: `0x${string}`): Signature { - const buf = Buffer.from(sig.slice(2), 'hex'); + static fromString(sig: `0x${string}`): Signature { + const buf = hexToBuffer(sig); const reader = BufferReader.asReader(buf); - const r = reader.readObject(Buffer32); const s = reader.readObject(Buffer32); const v = parseInt(sig.slice(2 + 64 * 2), 16); @@ -95,8 +98,8 @@ export class Signature { return this.size; } - to0xString(): `0x${string}` { - return `0x${this.r.toString()}${this.s.toString()}${this.v.toString(16)}`; + toString(): `0x${string}` { + return `0x${this.r.buffer.toString('hex')}${this.s.buffer.toString('hex')}${this.v.toString(16)}`; } /** @@ -104,14 +107,22 @@ export class Signature { */ toViemSignature(): ViemSignature { return { - r: this.r.to0xString(), - s: this.s.to0xString(), + r: this.r.toString(), + s: this.s.toString(), v: this.v, isEmpty: this.isEmpty, }; } toJSON() { - return this.to0xString(); + return this.toString(); + } + + static get schema() { + return z + .string() + .refine(hasHexPrefix, 'No hex prefix') + .refine(Signature.isValidString, 'Not a valid Ethereum signature') + .transform(Signature.fromString); } } diff --git a/yarn-project/foundation/src/fields/fields.ts b/yarn-project/foundation/src/fields/fields.ts index 4653d0eeee8..84b559c4f3c 100644 --- a/yarn-project/foundation/src/fields/fields.ts +++ b/yarn-project/foundation/src/fields/fields.ts @@ -4,6 +4,7 @@ import { inspect } from 'util'; import { toBigIntBE, toBufferBE } from '../bigint-buffer/index.js'; import { randomBytes } from '../crypto/random/index.js'; +import { hexSchemaFor } from '../schemas/utils.js'; import { BufferReader } from '../serialize/buffer_reader.js'; import { TypeRegistry } from '../serialize/type_registry.js'; @@ -300,12 +301,12 @@ export class Fr extends BaseField { return Fr.fromBuffer(rootBuf); } - // TODO(palla/schemas): Use toString instead of structured type toJSON() { - return { - type: 'Fr', - value: this.toString(), - }; + return this.toString(); + } + + static get schema() { + return hexSchemaFor(Fr); } } @@ -385,10 +386,11 @@ export class Fq extends BaseField { } toJSON() { - return { - type: 'Fq', - value: this.toString(), - }; + return this.toString(); + } + + static get schema() { + return hexSchemaFor(Fq); } } diff --git a/yarn-project/foundation/src/fields/point.ts b/yarn-project/foundation/src/fields/point.ts index 94b4394c2cd..f44c5df4a60 100644 --- a/yarn-project/foundation/src/fields/point.ts +++ b/yarn-project/foundation/src/fields/point.ts @@ -1,7 +1,9 @@ import { toBigIntBE } from '../bigint-buffer/index.js'; import { poseidon2Hash } from '../crypto/poseidon/index.js'; import { randomBoolean } from '../crypto/random/index.js'; +import { hexSchemaFor } from '../schemas/utils.js'; import { BufferReader, FieldReader, serializeToBuffer } from '../serialize/index.js'; +import { bufferToHex, hexToBuffer } from '../string/index.js'; import { Fr } from './fields.js'; /** @@ -34,6 +36,14 @@ export class Point { // TODO(#7386): check if on curve } + toJSON() { + return this.toString(); + } + + static get schema() { + return hexSchemaFor(Point); + } + /** * Generate a random Point instance. * @@ -84,14 +94,14 @@ export class Point { /** * Create a Point instance from a hex-encoded string. - * The input 'address' should be prefixed with '0x' or not, and have exactly 128 hex characters representing the x and y coordinates. + * The input should be prefixed with '0x' or not, and have exactly 128 hex characters representing the x and y coordinates. * Throws an error if the input length is invalid or coordinate values are out of range. * - * @param address - The hex-encoded string representing the Point coordinates. + * @param str - The hex-encoded string representing the Point coordinates. * @returns A Point instance. */ - static fromString(address: string) { - return this.fromBuffer(Buffer.from(address.replace(/^0x/i, ''), 'hex')); + static fromString(str: string) { + return this.fromBuffer(hexToBuffer(str)); } /** @@ -205,7 +215,7 @@ export class Point { * @returns A hex-encoded string representing the Point instance. */ toString() { - return '0x' + this.toBuffer().toString('hex'); + return bufferToHex(this.toBuffer()); } /** diff --git a/yarn-project/foundation/src/schemas/schemas.ts b/yarn-project/foundation/src/schemas/schemas.ts index eca83d8bcd0..45fc1af38fd 100644 --- a/yarn-project/foundation/src/schemas/schemas.ts +++ b/yarn-project/foundation/src/schemas/schemas.ts @@ -7,65 +7,45 @@ import { NoteSelector } from '../abi/note_selector.js'; import { AztecAddress } from '../aztec-address/index.js'; import { Buffer32 } from '../buffer/buffer32.js'; import { EthAddress } from '../eth-address/index.js'; -import { Signature } from '../eth-signature/eth_signature.js'; import { Fq, Fr } from '../fields/fields.js'; import { Point } from '../fields/point.js'; -import { hasHexPrefix, isHex, withoutHexPrefix } from '../string/index.js'; +import { isHex, withoutHexPrefix } from '../string/index.js'; import { type ZodFor } from './types.js'; -import { hexSchema, maybeStructuredStringSchemaFor } from './utils.js'; - -const FrSchema = maybeStructuredStringSchemaFor('Fr', Fr, isHex); -const FqSchema = maybeStructuredStringSchemaFor('Fq', Fq, isHex); +import { hexSchema } from './utils.js'; /** Validation schemas for common types. Every schema must match its toJSON. */ export const schemas = { - /** Accepts both a 0x string and a structured `{ type: EthAddress, value: '0x...' }` */ - EthAddress: maybeStructuredStringSchemaFor('EthAddress', EthAddress, EthAddress.isAddress), - - /** Accepts both a 0x string and a structured `{ type: AztecAddress, value: '0x...' }` */ - AztecAddress: maybeStructuredStringSchemaFor('AztecAddress', AztecAddress, AztecAddress.isAddress), + /** Accepts a hex string. */ + EthAddress: EthAddress.schema, - /** Accepts both a 0x string and a structured type. */ - FunctionSelector: maybeStructuredStringSchemaFor('FunctionSelector', FunctionSelector), + /** Accepts a hex string. */ + AztecAddress: AztecAddress.schema, - /** Accepts both a 0x string and a structured type. */ - NoteSelector: maybeStructuredStringSchemaFor('NoteSelector', NoteSelector), + /** Accepts a hex string. */ + FunctionSelector: FunctionSelector.schema, - /** Accepts both a 0x string and a structured type. */ - EventSelector: maybeStructuredStringSchemaFor('EventSelector', EventSelector), + /** Accepts a hex string. */ + NoteSelector: NoteSelector.schema, - /** Field element. Accepts a 0x prefixed hex string or a structured type. */ - Fr: FrSchema, + /** Accepts a hex string. */ + EventSelector: EventSelector.schema, - /** Field element. Accepts a 0x prefixed hex string or a structured type. */ - Fq: FqSchema, + /** Accepts a hex string. */ + Fr: Fr.schema, - /** Point. Serialized as 0x prefixed string or a type. */ - Point: z - .object({ - x: FrSchema, - y: FrSchema, - isInfinite: z.boolean().optional(), - }) - .or(hexSchema) - .transform(value => - typeof value === 'string' ? Point.fromString(value) : new Point(value.x, value.y, value.isInfinite ?? false), - ), + /** Accepts a hex string. */ + Fq: Fq.schema, - /** Accepts a 0x string */ - Signature: z - .string() - .refine(hasHexPrefix, 'No hex prefix') - .refine(Signature.isValid0xString, 'Not a valid Ethereum signature') - .transform(Signature.from0xString), + /** Point. Serialized as a hex string. */ + Point: Point.schema, - /** Coerces any input to bigint */ + /** Coerces any input to bigint. */ BigInt: z.union([z.bigint(), z.number(), z.string()]).pipe(z.coerce.bigint()), - /** Coerces any input to integer number */ + /** Coerces any input to integer number. */ Integer: z.union([z.bigint(), z.number(), z.string()]).pipe(z.coerce.number().int()), - /** Coerces input to UInt32 */ + /** Coerces input to UInt32. */ UInt32: z.union([z.bigint(), z.number(), z.string()]).pipe( z.coerce .number() @@ -74,11 +54,11 @@ export const schemas = { .max(2 ** 32 - 1), ), - /** Accepts a hex string as a Buffer32 type */ + /** Accepts a hex string as a Buffer32 type. */ Buffer32: z.string().refine(isHex, 'Not a valid hex string').transform(Buffer32.fromString), - /** Accepts a base64 string or a structured `{ type: 'Buffer', data: [byte, byte...] }` as a buffer */ - BufferB64: z.union([ + /** Accepts a base64 string or an object `{ type: 'Buffer', data: [byte, byte...] }` as a buffer. */ + Buffer: z.union([ z .string() .base64() @@ -86,19 +66,19 @@ export const schemas = { z .object({ type: z.literal('Buffer'), - data: z.array(z.number().int().max(255)), + data: z.array(z.number().int().min(0).max(255)), }) .transform(({ data }) => Buffer.from(data)), ]), - /** Accepts a hex string with optional 0x prefix as a buffer */ + /** Accepts a hex string as a buffer. */ BufferHex: z .string() .refine(isHex, 'Not a valid hex string') .transform(withoutHexPrefix) .transform(data => Buffer.from(data, 'hex')), - /** Hex string with an optional 0x prefix, which gets removed as part of the parsing */ + /** Hex string with an optional 0x prefix which gets removed as part of the parsing. */ HexString: hexSchema, }; diff --git a/yarn-project/foundation/src/schemas/utils.ts b/yarn-project/foundation/src/schemas/utils.ts index 412c49bc967..19aeab993f5 100644 --- a/yarn-project/foundation/src/schemas/utils.ts +++ b/yarn-project/foundation/src/schemas/utils.ts @@ -43,6 +43,8 @@ export function optional(schema: T) { return ZodNullableOptional.create(schema); } +type ToJsonIs = T extends { toJSON(): TRet } ? T : never; + /** * Creates a schema that accepts a hex string and uses it to hydrate an instance. * @param klazz - Class that implements either fromString or fromBuffer. @@ -50,28 +52,38 @@ export function optional(schema: T) { */ export function hexSchemaFor( klazz: TClass, + refinement?: (input: string) => boolean, ): ZodType< TClass extends { fromString(str: string): infer TInstance } | { fromBuffer(buf: Buffer): infer TInstance } - ? TInstance + ? ToJsonIs : never, any, string > { + const stringSchema = refinement ? z.string().refine(refinement, `Not a valid instance`) : z.string(); + const hexSchema = stringSchema.refine(isHex, 'Not a valid hex string').transform(withoutHexPrefix); return 'fromString' in klazz ? hexSchema.transform(klazz.fromString.bind(klazz)) : hexSchema.transform(str => Buffer.from(str, 'hex')).transform(klazz.fromBuffer.bind(klazz)); } -// TODO(palla/schemas): Delete this class once all serialization of the type { type: string, value: string } are removed. -export function maybeStructuredStringSchemaFor( - name: string, +/** + * Creates a schema that accepts a base64 string and uses it to hydrate an instance. + * @param klazz - Class that implements fromBuffer. + * @returns A schema for the class. + */ +export function bufferSchemaFor( klazz: TClass, - refinement?: (input: string) => boolean, -): ZodFor { - const stringSchema = refinement ? z.string().refine(refinement, `Not a valid ${name}`) : z.string(); +): ZodType< + TClass extends { fromBuffer(buf: Buffer): infer TInstance } ? ToJsonIs : never, + any, + string +> { return z - .union([stringSchema, z.object({ type: z.literal(name), value: stringSchema })]) - .transform(input => klazz.fromString(typeof input === 'string' ? input : input.value)); + .string() + .base64() + .transform(data => Buffer.from(data, 'base64')) + .transform(klazz.fromBuffer.bind(klazz)); } /** Creates a schema for a js Map type that matches the serialization used in jsonStringify. */ diff --git a/yarn-project/foundation/src/serialize/type_registry.test.ts b/yarn-project/foundation/src/serialize/type_registry.test.ts new file mode 100644 index 00000000000..b77e96a837f --- /dev/null +++ b/yarn-project/foundation/src/serialize/type_registry.test.ts @@ -0,0 +1,90 @@ +import { EventSelector } from '../abi/event_selector.js'; +import { FunctionSelector } from '../abi/function_selector.js'; +import { NoteSelector } from '../abi/note_selector.js'; +import { AztecAddress } from '../aztec-address/index.js'; +import { EthAddress } from '../eth-address/index.js'; +import { Fq, Fr } from '../fields/fields.js'; +import { resolver, reviver } from './type_registry.js'; + +describe('TypeRegistry', () => { + it('serializes registered type with type info', () => { + const data = { fr: Fr.random() }; + const json = JSON.stringify(data, resolver); + const parsed = JSON.parse(json); + expect(parsed.fr).toEqual({ type: 'Fr', value: data.fr.toString() }); + }); + + it('deserializes registered types in objects', () => { + const data = { + fr: Fr.random(), + fq: Fq.random(), + aztecAddress: AztecAddress.random(), + ethAddress: EthAddress.random(), + functionSelector: FunctionSelector.random(), + noteSelector: NoteSelector.random(), + }; + + const json = JSON.stringify(data, resolver); + const parsed = JSON.parse(json, reviver); + + expect(parsed).toEqual(data); + expect(parsed.fr).toBeInstanceOf(Fr); + expect(parsed.fq).toBeInstanceOf(Fq); + expect(parsed.aztecAddress).toBeInstanceOf(AztecAddress); + expect(parsed.ethAddress).toBeInstanceOf(EthAddress); + expect(parsed.functionSelector).toBeInstanceOf(FunctionSelector); + expect(parsed.noteSelector).toBeInstanceOf(NoteSelector); + }); + + it('deserializes registered types in arrays', () => { + const data = [ + Fr.random(), + Fq.random(), + AztecAddress.random(), + EthAddress.random(), + FunctionSelector.random(), + NoteSelector.random(), + ]; + + const json = JSON.stringify(data, resolver); + const parsed = JSON.parse(json, reviver); + + expect(parsed).toEqual(data); + expect(parsed[0]).toBeInstanceOf(Fr); + expect(parsed[1]).toBeInstanceOf(Fq); + expect(parsed[2]).toBeInstanceOf(AztecAddress); + expect(parsed[3]).toBeInstanceOf(EthAddress); + expect(parsed[4]).toBeInstanceOf(FunctionSelector); + expect(parsed[5]).toBeInstanceOf(NoteSelector); + }); + + it('ignores unregistered types', () => { + const data = { eventSelector: EventSelector.random() }; + const json = JSON.stringify(data, resolver); + const parsed = JSON.parse(json); + expect(parsed.eventSelector).toEqual(data.eventSelector.toString()); + }); + + it('handles plain objects', () => { + const data = { obj: { number: 10, string: 'string', fr: Fr.random() } }; + const json = JSON.stringify(data, resolver); + const parsed = JSON.parse(json, reviver); + expect(parsed).toEqual(data); + expect(parsed.obj.fr).toBeInstanceOf(Fr); + }); + + it('handles plain arrays', () => { + const data = [10, 'string', Fr.random()]; + const json = JSON.stringify(data, resolver); + const parsed = JSON.parse(json, reviver); + expect(parsed).toEqual(data); + expect(parsed[2]).toBeInstanceOf(Fr); + }); + + it('handles bigints', () => { + const data = { bigInt: BigInt(10) }; + const json = JSON.stringify(data, resolver); + const parsed = JSON.parse(json, reviver); + expect(parsed.bigInt).toEqual(BigInt(10)); + }); +}); diff --git a/yarn-project/foundation/src/serialize/type_registry.ts b/yarn-project/foundation/src/serialize/type_registry.ts index 85146710ed8..39a6bd00ad3 100644 --- a/yarn-project/foundation/src/serialize/type_registry.ts +++ b/yarn-project/foundation/src/serialize/type_registry.ts @@ -1,3 +1,5 @@ +import { mapValues } from '../collection/object.js'; + type Deserializable = { fromString(str: string): object }; /** @@ -23,9 +25,39 @@ export class TypeRegistry { } } +function replace(value: T) { + if ( + value && + typeof value === 'object' && + 'toString' in value && + TypeRegistry.getConstructor(value.constructor.name) + ) { + return { + type: value.constructor.name, + value: value.toString(), + }; + } + + return value; +} + // Resolver function that enables JSON serialization of BigInts. export function resolver(_: any, value: any) { - return typeof value === 'bigint' ? value.toString() + 'n' : value; + if (typeof value === 'bigint') { + return value.toString() + 'n'; + } + + if (typeof value === 'object' && value) { + if (Array.isArray(value)) { + return value.map(replace); + } else if (Buffer.isBuffer(value)) { + return { type: 'buffer', value: value.toString('hex') }; + } else { + return mapValues(value, replace); + } + } + + return value; } // Reviver function that uses TypeRegistry to instantiate objects. diff --git a/yarn-project/foundation/src/string/index.ts b/yarn-project/foundation/src/string/index.ts index 0d1fd95cb07..0c08d19f033 100644 --- a/yarn-project/foundation/src/string/index.ts +++ b/yarn-project/foundation/src/string/index.ts @@ -13,3 +13,7 @@ export function isHex(str: string): boolean { export function hexToBuffer(str: string): Buffer { return Buffer.from(withoutHexPrefix(str), 'hex'); } + +export function bufferToHex(buffer: Buffer): `0x${string}` { + return `0x${buffer.toString('hex')}`; +} diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/mocks.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/mocks.ts index 97bf92329b8..12973d954c5 100644 --- a/yarn-project/p2p/src/mem_pools/attestation_pool/mocks.ts +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/mocks.ts @@ -38,6 +38,6 @@ export const mockAttestation = async ( .toString('hex')}`; const sigString = await signer.signMessage({ message }); - const signature = Signature.from0xString(sigString); + const signature = Signature.fromString(sigString); return new BlockAttestation(payload, signature); }; diff --git a/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts b/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts index d030aa502f9..ce7e87ecc42 100644 --- a/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts +++ b/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts @@ -84,7 +84,7 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface { feeRecipient, gasFees, ); - this.log.debug(`Built global variables for block ${blockNumber}`, globalVariables.toJSON()); + this.log.debug(`Built global variables for block ${blockNumber}`, globalVariables.toFriendlyJSON()); return globalVariables; } } diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index 229ba4f7d75..07b75c4cd98 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -730,7 +730,7 @@ export class L1Publisher { const attestations = encodedData.attestations ? encodedData.attestations.map(attest => attest.toViemSignature()) : []; - const txHashes = encodedData.txHashes ? encodedData.txHashes.map(txHash => txHash.to0xString()) : []; + const txHashes = encodedData.txHashes ? encodedData.txHashes.map(txHash => txHash.toString()) : []; const args = [ `0x${encodedData.header.toString('hex')}`, `0x${encodedData.archive.toString('hex')}`, diff --git a/yarn-project/txe/src/util/encoding.ts b/yarn-project/txe/src/util/encoding.ts index 0b65122a61f..1853378af76 100644 --- a/yarn-project/txe/src/util/encoding.ts +++ b/yarn-project/txe/src/util/encoding.ts @@ -1,6 +1,7 @@ import { AztecAddress } from '@aztec/circuits.js'; import { type ContractArtifact, ContractArtifactSchema } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; +import { hexToBuffer } from '@aztec/foundation/string'; import { z } from 'zod'; @@ -23,7 +24,7 @@ export function addressFromSingle(obj: ForeignCallSingle) { } export function fromArray(obj: ForeignCallArray) { - return obj.map(str => Fr.fromBuffer(Buffer.from(str, 'hex'))); + return obj.map(str => Fr.fromBuffer(hexToBuffer(str))); } export function toSingle(obj: Fr | AztecAddress) {