From ee33c1a987aa37feb0824da22fdb77557279e5d5 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 1 Feb 2024 10:59:05 +0000 Subject: [PATCH 1/8] refactor: typing contents of MessageLoadOracleInputs --- .../src/acvm/oracle/typed_oracle.ts | 20 +++++++++++++------ .../src/client/private_execution.test.ts | 8 +------- yarn-project/acir-simulator/src/public/db.ts | 4 ++-- .../acir-simulator/src/public/index.test.ts | 9 +++++---- .../src/aztec-node/http_rpc_server.ts | 2 +- .../aztec-node/src/aztec-node/server.ts | 2 +- .../src/aztec_node/rpc/aztec_node_client.ts | 2 +- yarn-project/circuit-types/src/index.ts | 1 + .../src/interfaces/nullifier_tree.ts | 3 ++- .../src/interfaces/public_data_tree.ts | 3 ++- .../src/interfaces/state_info_provider.ts | 2 +- .../src/sibling_path}/index.ts | 0 .../src/sibling_path}/sibling-path.ts | 3 +-- .../src/interfaces/indexed_tree.ts | 2 +- .../merkle-tree/src/interfaces/merkle_tree.ts | 2 +- .../src/snapshots/append_only_snapshot.ts | 2 +- .../src/snapshots/base_full_snapshot.ts | 2 +- .../src/snapshots/snapshot_builder.ts | 2 +- .../src/sparse_tree/sparse_tree.test.ts | 2 +- .../standard_indexed_tree.ts | 2 +- .../test/standard_indexed_tree.test.ts | 2 +- .../src/test/standard_based_test_suite.ts | 2 +- .../merkle-tree/src/test/test_suite.ts | 2 +- yarn-project/merkle-tree/src/tree_base.ts | 2 +- .../pxe/src/simulator_oracle/index.ts | 16 +++++++++++---- .../src/sequencer/public_processor.test.ts | 2 +- .../src/simulator/public_executor.ts | 18 +++++++++++++---- yarn-project/types/src/index.ts | 1 - .../server_world_state_synchronizer.test.ts | 3 +-- .../world-state-db/merkle_tree_operations.ts | 3 +-- .../merkle_tree_operations_facade.ts | 3 +-- .../merkle_tree_snapshot_operations_facade.ts | 3 +-- .../src/world-state-db/merkle_trees.ts | 3 +-- 33 files changed, 75 insertions(+), 58 deletions(-) rename yarn-project/{types/src/sibling-path => circuit-types/src/sibling_path}/index.ts (100%) rename yarn-project/{types/src/sibling-path => circuit-types/src/sibling_path}/sibling-path.ts (99%) diff --git a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts index f4c58c9d33d..f0de71ac567 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts @@ -1,14 +1,22 @@ import { CompleteAddress, + L1ToL2Message, MerkleTreeId, Note, NoteStatus, NullifierMembershipWitness, PublicDataWitness, PublicKey, + SiblingPath, UnencryptedL2Log, } from '@aztec/circuit-types'; -import { GrumpkinPrivateKey, Header, PrivateCallStackItem, PublicCallRequest } from '@aztec/circuits.js'; +import { + GrumpkinPrivateKey, + Header, + L1_TO_L2_MSG_TREE_HEIGHT, + PrivateCallStackItem, + PublicCallRequest, +} from '@aztec/circuits.js'; import { FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -48,21 +56,21 @@ export interface NoteData { index?: bigint; } -export class MessageLoadOracleInputs { +export class MessageLoadOracleInputs { constructor( /** * An collapsed array of fields containing all of the l1 to l2 message components. * `l1ToL2Message.toFieldArray()` -\> [sender, chainId, recipient, version, content, secretHash, deadline, fee] */ - public message: Fr[], + public message: L1ToL2Message, /** The index of the message commitment in the merkle tree. */ public index: bigint, /** The path in the merkle tree to the message. */ - public siblingPath: Fr[], + public siblingPath: SiblingPath, ) {} toFields(): Fr[] { - return [...this.message, new Fr(this.index), ...this.siblingPath]; + return [...this.message.toFieldArray(), new Fr(this.index), ...this.siblingPath.toFieldArray()]; } } @@ -154,7 +162,7 @@ export abstract class TypedOracle { throw new Error('Not available.'); } - getL1ToL2Message(_msgKey: Fr): Promise { + getL1ToL2Message(_msgKey: Fr): Promise> { throw new Error('Not available.'); } diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index b3ace37240b..62860247a85 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -544,13 +544,7 @@ describe('Private Execution test suite', () => { const mockOracles = async () => { const tree = await insertLeaves([messageKey ?? preimage.hash()], 'l1ToL2Messages'); oracle.getL1ToL2Message.mockImplementation(async () => { - return Promise.resolve( - new MessageLoadOracleInputs( - preimage.toFieldArray(), - 0n, - (await tree.getSiblingPath(0n, false)).toFieldArray(), - ), - ); + return Promise.resolve(new MessageLoadOracleInputs(preimage, 0n, await tree.getSiblingPath(0n, false))); }); }; diff --git a/yarn-project/acir-simulator/src/public/db.ts b/yarn-project/acir-simulator/src/public/db.ts index a001a4d4ab8..26923cc366e 100644 --- a/yarn-project/acir-simulator/src/public/db.ts +++ b/yarn-project/acir-simulator/src/public/db.ts @@ -1,4 +1,4 @@ -import { EthAddress, FunctionSelector } from '@aztec/circuits.js'; +import { EthAddress, FunctionSelector, L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; @@ -74,7 +74,7 @@ export interface CommitmentsDB { * @param msgKey - The message Key. * @returns - The l1 to l2 message object */ - getL1ToL2Message(msgKey: Fr): Promise; + getL1ToL2Message(msgKey: Fr): Promise>; /** * Gets the index of a commitment in the note hash tree. diff --git a/yarn-project/acir-simulator/src/public/index.test.ts b/yarn-project/acir-simulator/src/public/index.test.ts index 4d7fdb81c92..be71abc0b4b 100644 --- a/yarn-project/acir-simulator/src/public/index.test.ts +++ b/yarn-project/acir-simulator/src/public/index.test.ts @@ -1,4 +1,4 @@ -import { L1ToL2Message } from '@aztec/circuit-types'; +import { L1ToL2Message, SiblingPath } from '@aztec/circuit-types'; import { AppendOnlyTreeSnapshot, CallContext, @@ -455,13 +455,14 @@ describe('ACIR public execution simulator', () => { publicContracts.getBytecode.mockResolvedValue(Buffer.from(mintPublicArtifact.bytecode, 'base64')); publicState.storageRead.mockResolvedValue(Fr.ZERO); - const siblingPath = Array(L1_TO_L2_MSG_TREE_HEIGHT).fill(Fr.random()); + const siblingPathFields = Array(L1_TO_L2_MSG_TREE_HEIGHT).fill(Fr.random()); + const siblingPath = new SiblingPath(L1_TO_L2_MSG_TREE_HEIGHT, siblingPathFields); let root = messageKey ?? preimage.hash(); - for (const sibling of siblingPath) { + for (const sibling of siblingPathFields) { root = Fr.fromBuffer(pedersenHash([root.toBuffer(), sibling.toBuffer()])); } commitmentsDb.getL1ToL2Message.mockImplementation(() => { - return Promise.resolve(new MessageLoadOracleInputs(preimage.toFieldArray(), 0n, siblingPath)); + return Promise.resolve(new MessageLoadOracleInputs(preimage, 0n, siblingPath)); }); return new AppendOnlyTreeSnapshot( diff --git a/yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts b/yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts index 0b4d6f7236b..fbbbed51794 100644 --- a/yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts +++ b/yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts @@ -8,6 +8,7 @@ import { L2BlockL2Logs, L2Tx, LogId, + SiblingPath, Tx, TxHash, } from '@aztec/circuit-types'; @@ -16,7 +17,6 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; import { JsonRpcServer } from '@aztec/foundation/json-rpc/server'; -import { SiblingPath } from '@aztec/types/membership'; /** * Wrap an AztecNode instance with a JSON RPC HTTP server. diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 2ccd40baa00..5f55ade4850 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -19,6 +19,7 @@ import { NullifierMembershipWitness, PublicDataWitness, SequencerConfig, + SiblingPath, Tx, TxHash, } from '@aztec/circuit-types'; @@ -46,7 +47,6 @@ import { SequencerClient, getGlobalVariableBuilder, } from '@aztec/sequencer-client'; -import { SiblingPath } from '@aztec/types/membership'; import { MerkleTrees, ServerWorldStateSynchronizer, diff --git a/yarn-project/circuit-types/src/aztec_node/rpc/aztec_node_client.ts b/yarn-project/circuit-types/src/aztec_node/rpc/aztec_node_client.ts index c78a6cdeb08..2ac789ffe38 100644 --- a/yarn-project/circuit-types/src/aztec_node/rpc/aztec_node_client.ts +++ b/yarn-project/circuit-types/src/aztec_node/rpc/aztec_node_client.ts @@ -4,7 +4,6 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; import { createJsonRpcClient, defaultFetch } from '@aztec/foundation/json-rpc/client'; -import { SiblingPath } from '@aztec/types/membership'; import { ContractData, ExtendedContractData } from '../../contract_data.js'; import { AztecNode } from '../../interfaces/index.js'; @@ -12,6 +11,7 @@ import { L1ToL2MessageAndIndex } from '../../l1_to_l2_message.js'; import { L2Block } from '../../l2_block.js'; import { L2Tx } from '../../l2_tx.js'; import { ExtendedUnencryptedL2Log, L2BlockL2Logs, LogId } from '../../logs/index.js'; +import { SiblingPath } from '../../sibling_path/index.js'; import { Tx, TxHash } from '../../tx/index.js'; /** diff --git a/yarn-project/circuit-types/src/index.ts b/yarn-project/circuit-types/src/index.ts index 85ea8cb627f..a61e91fc27d 100644 --- a/yarn-project/circuit-types/src/index.ts +++ b/yarn-project/circuit-types/src/index.ts @@ -16,6 +16,7 @@ export * from './merkle_tree_id.js'; export * from './mocks.js'; export * from './public_data_write.js'; export * from './simulation_error.js'; +export * from './sibling_path/index.js'; export * from './tx/index.js'; export * from './tx_execution_request.js'; export * from './packed_arguments.js'; diff --git a/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts b/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts index 4a06400a8c7..81b49d7dd46 100644 --- a/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts +++ b/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts @@ -1,5 +1,6 @@ import { Fr, NULLIFIER_TREE_HEIGHT, NullifierLeafPreimage } from '@aztec/circuits.js'; -import { SiblingPath } from '@aztec/types/membership'; + +import { SiblingPath } from '../sibling_path/index.js'; /** * Nullifier membership witness. diff --git a/yarn-project/circuit-types/src/interfaces/public_data_tree.ts b/yarn-project/circuit-types/src/interfaces/public_data_tree.ts index 5c5fc9c3054..5ea517fc84a 100644 --- a/yarn-project/circuit-types/src/interfaces/public_data_tree.ts +++ b/yarn-project/circuit-types/src/interfaces/public_data_tree.ts @@ -1,5 +1,6 @@ import { Fr, PUBLIC_DATA_TREE_HEIGHT, PublicDataTreeLeafPreimage } from '@aztec/circuits.js'; -import { SiblingPath } from '@aztec/types/membership'; + +import { SiblingPath } from '../sibling_path/index.js'; /** * Public data witness. diff --git a/yarn-project/circuit-types/src/interfaces/state_info_provider.ts b/yarn-project/circuit-types/src/interfaces/state_info_provider.ts index 3e7d83ece94..d653a2284c8 100644 --- a/yarn-project/circuit-types/src/interfaces/state_info_provider.ts +++ b/yarn-project/circuit-types/src/interfaces/state_info_provider.ts @@ -7,11 +7,11 @@ import { NULLIFIER_TREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, } from '@aztec/circuits.js'; -import { SiblingPath } from '@aztec/types/membership'; import { L1ToL2MessageAndIndex } from '../l1_to_l2_message.js'; import { L2Block } from '../l2_block.js'; import { MerkleTreeId } from '../merkle_tree_id.js'; +import { SiblingPath } from '../sibling_path/index.js'; import { NullifierMembershipWitness } from './nullifier_tree.js'; import { PublicDataWitness } from './public_data_tree.js'; diff --git a/yarn-project/types/src/sibling-path/index.ts b/yarn-project/circuit-types/src/sibling_path/index.ts similarity index 100% rename from yarn-project/types/src/sibling-path/index.ts rename to yarn-project/circuit-types/src/sibling_path/index.ts diff --git a/yarn-project/types/src/sibling-path/sibling-path.ts b/yarn-project/circuit-types/src/sibling_path/sibling-path.ts similarity index 99% rename from yarn-project/types/src/sibling-path/sibling-path.ts rename to yarn-project/circuit-types/src/sibling_path/sibling-path.ts index ae2db6fe133..f0a8ee22a43 100644 --- a/yarn-project/types/src/sibling-path/sibling-path.ts +++ b/yarn-project/circuit-types/src/sibling_path/sibling-path.ts @@ -6,8 +6,7 @@ import { deserializeArrayFromVector, serializeBufferArrayToVector, } from '@aztec/foundation/serialize'; - -import { Hasher } from '../interfaces/index.js'; +import { Hasher } from '@aztec/types/interfaces'; /** * Contains functionality to compute and serialize/deserialize a sibling path. diff --git a/yarn-project/merkle-tree/src/interfaces/indexed_tree.ts b/yarn-project/merkle-tree/src/interfaces/indexed_tree.ts index 651f734f09e..13c14f059dc 100644 --- a/yarn-project/merkle-tree/src/interfaces/indexed_tree.ts +++ b/yarn-project/merkle-tree/src/interfaces/indexed_tree.ts @@ -1,5 +1,5 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { IndexedTreeLeaf, IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; -import { SiblingPath } from '@aztec/types/membership'; import { AppendOnlyTree } from './append_only_tree.js'; diff --git a/yarn-project/merkle-tree/src/interfaces/merkle_tree.ts b/yarn-project/merkle-tree/src/interfaces/merkle_tree.ts index 209656f885d..752c07c3142 100644 --- a/yarn-project/merkle-tree/src/interfaces/merkle_tree.ts +++ b/yarn-project/merkle-tree/src/interfaces/merkle_tree.ts @@ -1,4 +1,4 @@ -import { SiblingPath } from '@aztec/types/membership'; +import { SiblingPath } from '@aztec/circuit-types'; /** * Defines the interface for a source of sibling paths. diff --git a/yarn-project/merkle-tree/src/snapshots/append_only_snapshot.ts b/yarn-project/merkle-tree/src/snapshots/append_only_snapshot.ts index 06d6e4b3194..3096688b806 100644 --- a/yarn-project/merkle-tree/src/snapshots/append_only_snapshot.ts +++ b/yarn-project/merkle-tree/src/snapshots/append_only_snapshot.ts @@ -1,6 +1,6 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { AztecKVStore, AztecMap } from '@aztec/kv-store'; import { Hasher } from '@aztec/types/interfaces'; -import { SiblingPath } from '@aztec/types/membership'; import { AppendOnlyTree } from '../interfaces/append_only_tree.js'; import { TreeBase } from '../tree_base.js'; diff --git a/yarn-project/merkle-tree/src/snapshots/base_full_snapshot.ts b/yarn-project/merkle-tree/src/snapshots/base_full_snapshot.ts index 5f1e250c569..01518cfd3f2 100644 --- a/yarn-project/merkle-tree/src/snapshots/base_full_snapshot.ts +++ b/yarn-project/merkle-tree/src/snapshots/base_full_snapshot.ts @@ -1,5 +1,5 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { AztecKVStore, AztecMap } from '@aztec/kv-store'; -import { SiblingPath } from '@aztec/types/membership'; import { TreeBase } from '../tree_base.js'; import { TreeSnapshot, TreeSnapshotBuilder } from './snapshot_builder.js'; diff --git a/yarn-project/merkle-tree/src/snapshots/snapshot_builder.ts b/yarn-project/merkle-tree/src/snapshots/snapshot_builder.ts index 98bbb9051d8..5feb1a2ef00 100644 --- a/yarn-project/merkle-tree/src/snapshots/snapshot_builder.ts +++ b/yarn-project/merkle-tree/src/snapshots/snapshot_builder.ts @@ -1,5 +1,5 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; -import { SiblingPath } from '@aztec/types/membership'; /** * An interface for a tree that can record snapshots of its contents. diff --git a/yarn-project/merkle-tree/src/sparse_tree/sparse_tree.test.ts b/yarn-project/merkle-tree/src/sparse_tree/sparse_tree.test.ts index 2de1db97d34..21ce5c2b767 100644 --- a/yarn-project/merkle-tree/src/sparse_tree/sparse_tree.test.ts +++ b/yarn-project/merkle-tree/src/sparse_tree/sparse_tree.test.ts @@ -1,7 +1,7 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { createDebugLogger } from '@aztec/foundation/log'; import { AztecKVStore, AztecLmdbStore } from '@aztec/kv-store'; import { Hasher } from '@aztec/types/interfaces'; -import { SiblingPath } from '@aztec/types/membership'; import { randomBytes } from 'crypto'; diff --git a/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts b/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts index 316bc2a62df..68a3f588ae2 100644 --- a/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts +++ b/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts @@ -1,10 +1,10 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { TreeInsertionStats } from '@aztec/circuit-types/stats'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { Timer } from '@aztec/foundation/timer'; import { IndexedTreeLeaf, IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; import { AztecKVStore, AztecMap } from '@aztec/kv-store'; import { Hasher } from '@aztec/types/interfaces'; -import { SiblingPath } from '@aztec/types/membership'; import { BatchInsertionResult, IndexedTree, LowLeafWitnessData, PreimageFactory } from '../interfaces/indexed_tree.js'; import { IndexedTreeSnapshotBuilder } from '../snapshots/indexed_tree_snapshot.js'; diff --git a/yarn-project/merkle-tree/src/standard_indexed_tree/test/standard_indexed_tree.test.ts b/yarn-project/merkle-tree/src/standard_indexed_tree/test/standard_indexed_tree.test.ts index 1e793daf656..6543283df8c 100644 --- a/yarn-project/merkle-tree/src/standard_indexed_tree/test/standard_indexed_tree.test.ts +++ b/yarn-project/merkle-tree/src/standard_indexed_tree/test/standard_indexed_tree.test.ts @@ -1,3 +1,4 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { Fr, NullifierLeaf, @@ -8,7 +9,6 @@ import { import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { AztecKVStore, AztecLmdbStore } from '@aztec/kv-store'; import { Hasher } from '@aztec/types/interfaces'; -import { SiblingPath } from '@aztec/types/membership'; import { INITIAL_LEAF, MerkleTree, Pedersen, loadTree, newTree } from '../../index.js'; import { treeTestSuite } from '../../test/test_suite.js'; diff --git a/yarn-project/merkle-tree/src/test/standard_based_test_suite.ts b/yarn-project/merkle-tree/src/test/standard_based_test_suite.ts index bfd95e7b349..f970a9c89aa 100644 --- a/yarn-project/merkle-tree/src/test/standard_based_test_suite.ts +++ b/yarn-project/merkle-tree/src/test/standard_based_test_suite.ts @@ -1,6 +1,6 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { AztecKVStore, AztecLmdbStore } from '@aztec/kv-store'; import { Hasher } from '@aztec/types/interfaces'; -import { SiblingPath } from '@aztec/types/membership'; import { randomBytes } from 'crypto'; diff --git a/yarn-project/merkle-tree/src/test/test_suite.ts b/yarn-project/merkle-tree/src/test/test_suite.ts index fd2d5b038fb..c7fdd51b103 100644 --- a/yarn-project/merkle-tree/src/test/test_suite.ts +++ b/yarn-project/merkle-tree/src/test/test_suite.ts @@ -1,6 +1,6 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { AztecKVStore, AztecLmdbStore } from '@aztec/kv-store'; import { Hasher } from '@aztec/types/interfaces'; -import { SiblingPath } from '@aztec/types/membership'; import { Pedersen } from '../index.js'; import { AppendOnlyTree } from '../interfaces/append_only_tree.js'; diff --git a/yarn-project/merkle-tree/src/tree_base.ts b/yarn-project/merkle-tree/src/tree_base.ts index 972cdf19cc5..21baacdc041 100644 --- a/yarn-project/merkle-tree/src/tree_base.ts +++ b/yarn-project/merkle-tree/src/tree_base.ts @@ -1,8 +1,8 @@ +import { SiblingPath } from '@aztec/circuit-types'; import { toBigIntLE, toBufferLE } from '@aztec/foundation/bigint-buffer'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { AztecKVStore, AztecMap, AztecSingleton } from '@aztec/kv-store'; import { Hasher } from '@aztec/types/interfaces'; -import { SiblingPath } from '@aztec/types/membership'; import { HasherWithStats } from './hasher_with_stats.js'; import { MerkleTree } from './interfaces/merkle_tree.js'; diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 6077752fdcb..57d53e21ad4 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -8,7 +8,15 @@ import { PublicDataWitness, StateInfoProvider, } from '@aztec/circuit-types'; -import { AztecAddress, CompleteAddress, EthAddress, Fr, FunctionSelector, Header } from '@aztec/circuits.js'; +import { + AztecAddress, + CompleteAddress, + EthAddress, + Fr, + FunctionSelector, + Header, + L1_TO_L2_MSG_TREE_HEIGHT, +} from '@aztec/circuits.js'; import { FunctionArtifactWithDebugMetadata } from '@aztec/foundation/abi'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -118,12 +126,12 @@ export class SimulatorOracle implements DBOracle { * @returns A promise that resolves to the message data, a sibling path and the * index of the message in the l1ToL2MessageTree */ - async getL1ToL2Message(msgKey: Fr): Promise { + async getL1ToL2Message(msgKey: Fr): Promise> { const messageAndIndex = await this.stateInfoProvider.getL1ToL2MessageAndIndex(msgKey); - const message = messageAndIndex.message.toFieldArray(); + const message = messageAndIndex.message; const index = messageAndIndex.index; const siblingPath = await this.stateInfoProvider.getL1ToL2MessageSiblingPath('latest', index); - return new MessageLoadOracleInputs(message, index, siblingPath.toFieldArray()); + return new MessageLoadOracleInputs(message, index, siblingPath); } /** diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts index 5bb68a03ec3..89d30f0c393 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts @@ -3,6 +3,7 @@ import { ExtendedContractData, FunctionCall, FunctionL2Logs, + SiblingPath, SimulationError, Tx, TxL2Logs, @@ -35,7 +36,6 @@ import { } from '@aztec/circuits.js/factories'; import { makeTuple } from '@aztec/foundation/array'; import { padArrayEnd, times } from '@aztec/foundation/collection'; -import { SiblingPath } from '@aztec/types/membership'; import { MerkleTreeOperations, TreeInfo } from '@aztec/world-state'; import { MockProxy, mock } from 'jest-mock-extended'; diff --git a/yarn-project/sequencer-client/src/simulator/public_executor.ts b/yarn-project/sequencer-client/src/simulator/public_executor.ts index de082839ab0..7ee16c8e0bd 100644 --- a/yarn-project/sequencer-client/src/simulator/public_executor.ts +++ b/yarn-project/sequencer-client/src/simulator/public_executor.ts @@ -1,6 +1,13 @@ import { CommitmentsDB, MessageLoadOracleInputs, PublicContractsDB, PublicStateDB } from '@aztec/acir-simulator'; import { ContractDataSource, ExtendedContractData, L1ToL2MessageSource, MerkleTreeId, Tx } from '@aztec/circuit-types'; -import { AztecAddress, EthAddress, Fr, FunctionSelector, PublicDataTreeLeafPreimage } from '@aztec/circuits.js'; +import { + AztecAddress, + EthAddress, + Fr, + FunctionSelector, + L1_TO_L2_MSG_TREE_HEIGHT, + PublicDataTreeLeafPreimage, +} from '@aztec/circuits.js'; import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/abis'; import { MerkleTreeOperations } from '@aztec/world-state'; @@ -144,13 +151,16 @@ export class WorldStatePublicDB implements PublicStateDB { export class WorldStateDB implements CommitmentsDB { constructor(private db: MerkleTreeOperations, private l1ToL2MessageSource: L1ToL2MessageSource) {} - public async getL1ToL2Message(messageKey: Fr): Promise { + public async getL1ToL2Message(messageKey: Fr): Promise> { // todo: #697 - make this one lookup. const message = await this.l1ToL2MessageSource.getConfirmedL1ToL2Message(messageKey); const index = (await this.db.findLeafIndex(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, messageKey.toBuffer()))!; - const siblingPath = await this.db.getSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, index); + const siblingPath = await this.db.getSiblingPath( + MerkleTreeId.L1_TO_L2_MESSAGE_TREE, + index, + ); - return new MessageLoadOracleInputs(message.toFieldArray(), index, siblingPath.toFieldArray()); + return new MessageLoadOracleInputs(message, index, siblingPath); } public async getCommitmentIndex(commitment: Fr): Promise { diff --git a/yarn-project/types/src/index.ts b/yarn-project/types/src/index.ts index 6815c4130c4..a3df311a469 100644 --- a/yarn-project/types/src/index.ts +++ b/yarn-project/types/src/index.ts @@ -1,2 +1 @@ export * from './interfaces/index.js'; -export * from './sibling-path/index.js'; diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts index 8c0f0e23351..684e46a84a6 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts @@ -1,10 +1,9 @@ -import { L2Block, L2BlockSource, MerkleTreeId } from '@aztec/circuit-types'; +import { L2Block, L2BlockSource, MerkleTreeId, SiblingPath } from '@aztec/circuit-types'; import { Fr } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; import { AztecKVStore, AztecLmdbStore } from '@aztec/kv-store'; import { INITIAL_LEAF, Pedersen } from '@aztec/merkle-tree'; -import { SiblingPath } from '@aztec/types/membership'; import { jest } from '@jest/globals'; import { mock } from 'jest-mock-extended'; diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts index 8a59832253a..560906b4d69 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts @@ -1,9 +1,8 @@ -import { L2Block, MerkleTreeId } from '@aztec/circuit-types'; +import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/circuit-types'; import { Header, NullifierLeafPreimage, StateReference } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; import { BatchInsertionResult } from '@aztec/merkle-tree'; -import { SiblingPath } from '@aztec/types/membership'; /** * Type alias for the nullifier tree ID. diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts index f36513f6e78..26c3cceb896 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts @@ -1,8 +1,7 @@ -import { L2Block, MerkleTreeId } from '@aztec/circuit-types'; +import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/circuit-types'; import { Header, NullifierLeafPreimage, StateReference } from '@aztec/circuits.js'; import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; import { BatchInsertionResult } from '@aztec/merkle-tree'; -import { SiblingPath } from '@aztec/types/membership'; import { MerkleTreeDb } from './merkle_tree_db.js'; import { HandleL2BlockResult, MerkleTreeOperations, TreeInfo } from './merkle_tree_operations.js'; diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_snapshot_operations_facade.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_snapshot_operations_facade.ts index 79e7a01d16f..8c645dc6ca7 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_snapshot_operations_facade.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_snapshot_operations_facade.ts @@ -1,8 +1,7 @@ -import { MerkleTreeId } from '@aztec/circuit-types'; +import { MerkleTreeId, SiblingPath } from '@aztec/circuit-types'; import { AppendOnlyTreeSnapshot, Fr, Header, PartialStateReference, StateReference } from '@aztec/circuits.js'; import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; import { BatchInsertionResult, IndexedTreeSnapshot, TreeSnapshot } from '@aztec/merkle-tree'; -import { SiblingPath } from '@aztec/types/membership'; import { MerkleTreeDb } from './merkle_tree_db.js'; import { HandleL2BlockResult, MerkleTreeOperations, TreeInfo } from './merkle_tree_operations.js'; diff --git a/yarn-project/world-state/src/world-state-db/merkle_trees.ts b/yarn-project/world-state/src/world-state-db/merkle_trees.ts index 3a55636c273..102946f05b2 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_trees.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_trees.ts @@ -1,4 +1,4 @@ -import { L2Block, MerkleTreeId } from '@aztec/circuit-types'; +import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/circuit-types'; import { ARCHIVE_HEIGHT, AppendOnlyTreeSnapshot, @@ -37,7 +37,6 @@ import { newTree, } from '@aztec/merkle-tree'; import { Hasher } from '@aztec/types/interfaces'; -import { SiblingPath } from '@aztec/types/membership'; import { INITIAL_NULLIFIER_TREE_SIZE, INITIAL_PUBLIC_DATA_TREE_SIZE, MerkleTreeDb } from './merkle_tree_db.js'; import { HandleL2BlockResult, IndexedTreeId, MerkleTreeOperations, TreeInfo } from './merkle_tree_operations.js'; From 1300439281ef912764ff30ac8b4b116581e8cee4 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 1 Feb 2024 11:53:55 +0000 Subject: [PATCH 2/8] test fix --- yarn-project/acir-simulator/src/public/index.test.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/yarn-project/acir-simulator/src/public/index.test.ts b/yarn-project/acir-simulator/src/public/index.test.ts index be71abc0b4b..e96cd2ecaa9 100644 --- a/yarn-project/acir-simulator/src/public/index.test.ts +++ b/yarn-project/acir-simulator/src/public/index.test.ts @@ -455,11 +455,14 @@ describe('ACIR public execution simulator', () => { publicContracts.getBytecode.mockResolvedValue(Buffer.from(mintPublicArtifact.bytecode, 'base64')); publicState.storageRead.mockResolvedValue(Fr.ZERO); - const siblingPathFields = Array(L1_TO_L2_MSG_TREE_HEIGHT).fill(Fr.random()); - const siblingPath = new SiblingPath(L1_TO_L2_MSG_TREE_HEIGHT, siblingPathFields); + const siblingPathBuffers = Array(L1_TO_L2_MSG_TREE_HEIGHT) + .fill(Fr.random()) + .map(f => f.toBuffer()); + const siblingPath = new SiblingPath(L1_TO_L2_MSG_TREE_HEIGHT, siblingPathBuffers); + let root = messageKey ?? preimage.hash(); - for (const sibling of siblingPathFields) { - root = Fr.fromBuffer(pedersenHash([root.toBuffer(), sibling.toBuffer()])); + for (const sibling of siblingPathBuffers) { + root = Fr.fromBuffer(pedersenHash([root.toBuffer(), sibling])); } commitmentsDb.getL1ToL2Message.mockImplementation(() => { return Promise.resolve(new MessageLoadOracleInputs(preimage, 0n, siblingPath)); From e30fbc5afa1a4b89c9fb1de08af535c6fa419da8 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 1 Feb 2024 13:14:12 +0000 Subject: [PATCH 3/8] stale comment --- yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts index f0de71ac567..e19424a24ca 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts @@ -58,10 +58,7 @@ export interface NoteData { export class MessageLoadOracleInputs { constructor( - /** - * An collapsed array of fields containing all of the l1 to l2 message components. - * `l1ToL2Message.toFieldArray()` -\> [sender, chainId, recipient, version, content, secretHash, deadline, fee] - */ + /** The message. */ public message: L1ToL2Message, /** The index of the message commitment in the merkle tree. */ public index: bigint, From dd67ce5242b1e6147fd84591ce534e64a9f9e1fb Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 1 Feb 2024 13:04:27 +0000 Subject: [PATCH 4/8] refactor: PublicCircuitPublicInputs cleanup --- .../src/structs/contract_storage_read.test.ts | 21 +++ .../src/structs/contract_storage_read.ts | 77 ++++++++++ .../contract_storage_update_request.test.ts | 21 +++ .../contract_storage_update_request.ts | 83 +++++++++++ yarn-project/circuits.js/src/structs/index.ts | 2 + .../structs/public_circuit_public_inputs.ts | 131 +----------------- 6 files changed, 206 insertions(+), 129 deletions(-) create mode 100644 yarn-project/circuits.js/src/structs/contract_storage_read.test.ts create mode 100644 yarn-project/circuits.js/src/structs/contract_storage_read.ts create mode 100644 yarn-project/circuits.js/src/structs/contract_storage_update_request.test.ts create mode 100644 yarn-project/circuits.js/src/structs/contract_storage_update_request.ts diff --git a/yarn-project/circuits.js/src/structs/contract_storage_read.test.ts b/yarn-project/circuits.js/src/structs/contract_storage_read.test.ts new file mode 100644 index 00000000000..51264c92afd --- /dev/null +++ b/yarn-project/circuits.js/src/structs/contract_storage_read.test.ts @@ -0,0 +1,21 @@ +import { makeContractStorageRead } from '../tests/factories.js'; +import { ContractStorageRead } from './contract_storage_read.js'; + +describe('ContractStorageRead', () => { + it('serializes to buffer and deserializes it back', () => { + const randomInt = Math.floor(Math.random() * 1000); + const expected = makeContractStorageRead(randomInt); + const buffer = expected.toBuffer(); + const res = ContractStorageRead.fromBuffer(buffer); + expect(res).toEqual(expected); + }); + + it('serializes to field array and deserializes it back', () => { + const randomInt = Math.floor(Math.random() * 1000); + const expected = makeContractStorageRead(randomInt); + + const fieldArray = expected.toFields(); + const res = ContractStorageRead.fromFields(fieldArray); + expect(res).toEqual(expected); + }); +}); diff --git a/yarn-project/circuits.js/src/structs/contract_storage_read.ts b/yarn-project/circuits.js/src/structs/contract_storage_read.ts new file mode 100644 index 00000000000..907470b132d --- /dev/null +++ b/yarn-project/circuits.js/src/structs/contract_storage_read.ts @@ -0,0 +1,77 @@ +import { Fr } from '@aztec/foundation/fields'; +import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; + +/** + * Contract storage read operation on a specific contract. + * + * Note: Similar to `PublicDataRead` but it's from the POV of contract storage so we are not working with public data + * tree leaf index but storage slot index. + */ +export class ContractStorageRead { + constructor( + /** + * Storage slot we are reading from. + */ + public readonly storageSlot: Fr, + /** + * Value read from the storage slot. + */ + public readonly currentValue: Fr, + /** + * Optional side effect counter tracking position of this event in tx execution. + * Note: Not serialized + */ + public readonly sideEffectCounter?: number, + ) {} + + static from(args: { + /** + * Storage slot we are reading from. + */ + storageSlot: Fr; + /** + * Value read from the storage slot. + */ + currentValue: Fr; + /** + * Optional side effect counter tracking position of this event in tx execution. + */ + sideEffectCounter?: number; + }) { + return new ContractStorageRead(args.storageSlot, args.currentValue, args.sideEffectCounter); + } + + toBuffer() { + return serializeToBuffer(this.storageSlot, this.currentValue); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new ContractStorageRead(Fr.fromBuffer(reader), Fr.fromBuffer(reader)); + } + + static empty() { + return new ContractStorageRead(Fr.ZERO, Fr.ZERO); + } + + isEmpty() { + return this.storageSlot.isZero() && this.currentValue.isZero(); + } + + toFriendlyJSON() { + return `Slot=${this.storageSlot.toFriendlyJSON()}: ${this.currentValue.toFriendlyJSON()}`; + } + + toFields(): Fr[] { + return [this.storageSlot, this.currentValue]; + } + + static fromFields(fields: Fr[] | FieldReader): ContractStorageRead { + const reader = FieldReader.asReader(fields); + + const storageSlot = reader.readField(); + const currentValue = reader.readField(); + + return new ContractStorageRead(storageSlot, currentValue); + } +} diff --git a/yarn-project/circuits.js/src/structs/contract_storage_update_request.test.ts b/yarn-project/circuits.js/src/structs/contract_storage_update_request.test.ts new file mode 100644 index 00000000000..e38a0b031aa --- /dev/null +++ b/yarn-project/circuits.js/src/structs/contract_storage_update_request.test.ts @@ -0,0 +1,21 @@ +import { makeContractStorageUpdateRequest } from '../tests/factories.js'; +import { ContractStorageUpdateRequest } from './contract_storage_update_request.js'; + +describe('ContractStorageUpdateRequest', () => { + it('serializes to buffer and deserializes it back', () => { + const randomInt = Math.floor(Math.random() * 1000); + const expected = makeContractStorageUpdateRequest(randomInt); + const buffer = expected.toBuffer(); + const res = ContractStorageUpdateRequest.fromBuffer(buffer); + expect(res).toEqual(expected); + }); + + it('serializes to field array and deserializes it back', () => { + const randomInt = Math.floor(Math.random() * 1000); + const expected = makeContractStorageUpdateRequest(randomInt); + + const fieldArray = expected.toFields(); + const res = ContractStorageUpdateRequest.fromFields(fieldArray); + expect(res).toEqual(expected); + }); +}); diff --git a/yarn-project/circuits.js/src/structs/contract_storage_update_request.ts b/yarn-project/circuits.js/src/structs/contract_storage_update_request.ts new file mode 100644 index 00000000000..351ea091825 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/contract_storage_update_request.ts @@ -0,0 +1,83 @@ +import { Fr } from '@aztec/foundation/fields'; +import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { FieldsOf } from '@aztec/foundation/types'; + +/** + * Contract storage update request for a slot on a specific contract. + * + * Note: Similar to `PublicDataUpdateRequest` but it's from the POV of contract storage so we are not working with + * public data tree leaf index but storage slot index. + */ +export class ContractStorageUpdateRequest { + constructor( + /** + * Storage slot we are updating. + */ + public readonly storageSlot: Fr, + /** + * Old value of the storage slot. + */ + public readonly oldValue: Fr, + /** + * New value of the storage slot. + */ + public readonly newValue: Fr, + /** + * Optional side effect counter tracking position of this event in tx execution. + */ + public readonly sideEffectCounter?: number, + ) {} + + toBuffer() { + return serializeToBuffer(this.storageSlot, this.oldValue, this.newValue); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new ContractStorageUpdateRequest(Fr.fromBuffer(reader), Fr.fromBuffer(reader), Fr.fromBuffer(reader)); + } + + /** + * Create PublicCallRequest from a fields dictionary. + * @param fields - The dictionary. + * @returns A PublicCallRequest object. + */ + static from(fields: FieldsOf): ContractStorageUpdateRequest { + return new ContractStorageUpdateRequest(...ContractStorageUpdateRequest.getFields(fields)); + } + + /** + * Serialize into a field array. Low-level utility. + * @param fields - Object with fields. + * @returns The array. + */ + static getFields(fields: FieldsOf) { + return [fields.storageSlot, fields.oldValue, fields.newValue, fields.sideEffectCounter] as const; + } + + static empty() { + return new ContractStorageUpdateRequest(Fr.ZERO, Fr.ZERO, Fr.ZERO); + } + + isEmpty() { + return this.storageSlot.isZero() && this.oldValue.isZero() && this.newValue.isZero(); + } + + toFriendlyJSON() { + return `Slot=${this.storageSlot.toFriendlyJSON()}: ${this.oldValue.toFriendlyJSON()} => ${this.newValue.toFriendlyJSON()}`; + } + + toFields(): Fr[] { + return [this.storageSlot, this.oldValue, this.newValue]; + } + + static fromFields(fields: Fr[] | FieldReader): ContractStorageUpdateRequest { + const reader = FieldReader.asReader(fields); + + const storageSlot = reader.readField(); + const oldValue = reader.readField(); + const newValue = reader.readField(); + + return new ContractStorageUpdateRequest(storageSlot, oldValue, newValue); + } +} diff --git a/yarn-project/circuits.js/src/structs/index.ts b/yarn-project/circuits.js/src/structs/index.ts index 2218c043152..cb06d1b1412 100644 --- a/yarn-project/circuits.js/src/structs/index.ts +++ b/yarn-project/circuits.js/src/structs/index.ts @@ -5,6 +5,8 @@ export * from './call_request.js'; export * from './call_stack_item.js'; export * from './complete_address.js'; export * from './contract_deployment_data.js'; +export * from './contract_storage_read.js'; +export * from './contract_storage_update_request.js'; export * from './function_data.js'; export * from './function_leaf_preimage.js'; export * from './global_variables.js'; diff --git a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts index 572e76e273b..a1e1abad29e 100644 --- a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts @@ -2,7 +2,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { isArrayEmpty } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/fields'; -import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { FieldsOf } from '@aztec/foundation/types'; import { @@ -15,134 +15,7 @@ import { RETURN_VALUES_LENGTH, } from '../constants.gen.js'; import { CallContext } from './call_context.js'; -import { Header, SideEffect, SideEffectLinkedToNoteHash } from './index.js'; - -/** - * Contract storage read operation on a specific contract. - * - * Note: Similar to `PublicDataRead` but it's from the POV of contract storage so we are not working with public data - * tree leaf index but storage slot index. - */ -export class ContractStorageRead { - constructor( - /** - * Storage slot we are reading from. - */ - public readonly storageSlot: Fr, - /** - * Value read from the storage slot. - */ - public readonly currentValue: Fr, - /** - * Optional side effect counter tracking position of this event in tx execution. - */ - public readonly sideEffectCounter?: number, - ) {} - - static from(args: { - /** - * Storage slot we are reading from. - */ - storageSlot: Fr; - /** - * Value read from the storage slot. - */ - currentValue: Fr; - /** - * Optional side effect counter tracking position of this event in tx execution. - */ - sideEffectCounter?: number; - }) { - return new ContractStorageRead(args.storageSlot, args.currentValue, args.sideEffectCounter); - } - - toBuffer() { - return serializeToBuffer(this.storageSlot, this.currentValue); - } - - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new ContractStorageRead(Fr.fromBuffer(reader), Fr.fromBuffer(reader)); - } - - static empty() { - return new ContractStorageRead(Fr.ZERO, Fr.ZERO); - } - - isEmpty() { - return this.storageSlot.isZero() && this.currentValue.isZero(); - } - - toFriendlyJSON() { - return `Slot=${this.storageSlot.toFriendlyJSON()}: ${this.currentValue.toFriendlyJSON()}`; - } -} - -/** - * Contract storage update request for a slot on a specific contract. - * - * Note: Similar to `PublicDataUpdateRequest` but it's from the POV of contract storage so we are not working with - * public data tree leaf index but storage slot index. - */ -export class ContractStorageUpdateRequest { - constructor( - /** - * Storage slot we are updating. - */ - public readonly storageSlot: Fr, - /** - * Old value of the storage slot. - */ - public readonly oldValue: Fr, - /** - * New value of the storage slot. - */ - public readonly newValue: Fr, - /** - * Optional side effect counter tracking position of this event in tx execution. - */ - public readonly sideEffectCounter?: number, - ) {} - - toBuffer() { - return serializeToBuffer(this.storageSlot, this.oldValue, this.newValue); - } - - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new ContractStorageUpdateRequest(Fr.fromBuffer(reader), Fr.fromBuffer(reader), Fr.fromBuffer(reader)); - } - - /** - * Create PublicCallRequest from a fields dictionary. - * @param fields - The dictionary. - * @returns A PublicCallRequest object. - */ - static from(fields: FieldsOf): ContractStorageUpdateRequest { - return new ContractStorageUpdateRequest(...ContractStorageUpdateRequest.getFields(fields)); - } - - /** - * Serialize into a field array. Low-level utility. - * @param fields - Object with fields. - * @returns The array. - */ - static getFields(fields: FieldsOf) { - return [fields.storageSlot, fields.oldValue, fields.newValue, fields.sideEffectCounter] as const; - } - - static empty() { - return new ContractStorageUpdateRequest(Fr.ZERO, Fr.ZERO, Fr.ZERO); - } - - isEmpty() { - return this.storageSlot.isZero() && this.oldValue.isZero() && this.newValue.isZero(); - } - - toFriendlyJSON() { - return `Slot=${this.storageSlot.toFriendlyJSON()}: ${this.oldValue.toFriendlyJSON()} => ${this.newValue.toFriendlyJSON()}`; - } -} +import { ContractStorageRead, ContractStorageUpdateRequest, Header, SideEffect, SideEffectLinkedToNoteHash } from './index.js'; /** * Public inputs to a public circuit. From 7e8d3f188ba12153005314d1cc38a4cd7bd53c26 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 1 Feb 2024 13:33:17 +0000 Subject: [PATCH 5/8] cleanup of extractPublicCircuitPublicInputs --- .../acir-simulator/src/acvm/deserialize.ts | 61 +------------------ .../public_circuit_public_inputs.test.ts | 10 +++ .../structs/public_circuit_public_inputs.ts | 52 +++++++++++++++- 3 files changed, 62 insertions(+), 61 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/deserialize.ts b/yarn-project/acir-simulator/src/acvm/deserialize.ts index 1c4aa93ec26..82ae5b1fce0 100644 --- a/yarn-project/acir-simulator/src/acvm/deserialize.ts +++ b/yarn-project/acir-simulator/src/acvm/deserialize.ts @@ -1,8 +1,6 @@ import { CallContext, ContractDeploymentData, - ContractStorageRead, - ContractStorageUpdateRequest, HEADER_LENGTH, Header, MAX_NEW_COMMITMENTS_PER_CALL, @@ -11,8 +9,6 @@ import { MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, - MAX_PUBLIC_DATA_READS_PER_CALL, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_READ_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256, NullifierKeyValidationRequest, @@ -22,10 +18,9 @@ import { SideEffect, SideEffectLinkedToNoteHash, } from '@aztec/circuits.js'; -import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr, Point } from '@aztec/foundation/fields'; -import { FieldReader, Tuple } from '@aztec/foundation/serialize'; +import { FieldReader } from '@aztec/foundation/serialize'; import { getReturnWitness } from '@noir-lang/acvm_js'; @@ -145,57 +140,5 @@ export function extractPrivateCircuitPublicInputs( */ export function extractPublicCircuitPublicInputs(partialWitness: ACVMWitness, acir: Buffer): PublicCircuitPublicInputs { const witnessReader = createPublicInputsReader(partialWitness, acir); - - const callContext = witnessReader.readObject(CallContext); - - const argsHash = witnessReader.readField(); - const returnValues = witnessReader.readFieldArray(RETURN_VALUES_LENGTH); - - const contractStorageUpdateRequests = new Array(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL).fill( - ContractStorageUpdateRequest.empty(), - ); - for (let i = 0; i < MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL; i++) { - const request = new ContractStorageUpdateRequest( - witnessReader.readField(), - witnessReader.readField(), - witnessReader.readField(), - ); - contractStorageUpdateRequests[i] = request; - } - const contractStorageReads = new Array(MAX_PUBLIC_DATA_READS_PER_CALL).fill(ContractStorageRead.empty()); - for (let i = 0; i < MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL; i++) { - const request = new ContractStorageRead(witnessReader.readField(), witnessReader.readField()); - contractStorageReads[i] = request; - } - - const publicCallStack = witnessReader.readFieldArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL); - const newCommitments = witnessReader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect); - const newNullifiers = witnessReader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash); - const newL2ToL1Msgs = witnessReader.readFieldArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL); - - const unencryptedLogsHash = witnessReader.readFieldArray(NUM_FIELDS_PER_SHA256); - const unencryptedLogPreimagesLength = witnessReader.readField(); - - const header = Header.fromFields(witnessReader.readFieldArray(HEADER_LENGTH)); - - const proverAddress = AztecAddress.fromField(witnessReader.readField()); - - return new PublicCircuitPublicInputs( - callContext, - argsHash, - returnValues, - contractStorageUpdateRequests as Tuple< - ContractStorageUpdateRequest, - typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL - >, - contractStorageReads as Tuple, - publicCallStack, - newCommitments, - newNullifiers, - newL2ToL1Msgs, - unencryptedLogsHash, - unencryptedLogPreimagesLength, - header, - proverAddress, - ); + return PublicCircuitPublicInputs.fromFields(witnessReader); } diff --git a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.test.ts b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.test.ts index 531a766e2fe..7fb1145ea63 100644 --- a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.test.ts +++ b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.test.ts @@ -1,6 +1,16 @@ +import { makePublicCircuitPublicInputs } from '../tests/factories.js'; import { PublicCircuitPublicInputs } from './public_circuit_public_inputs.js'; describe('PublicCircuitPublicInputs', () => { + it('serializes to field array and deserializes it back', () => { + const randomInt = Math.floor(Math.random() * 1000); + const expected = makePublicCircuitPublicInputs(randomInt, undefined); + + const fieldArray = expected.toFields(); + const res = PublicCircuitPublicInputs.fromFields(fieldArray); + expect(res).toEqual(expected); + }); + it(`initializes an empty PrivateCircuitPublicInputs`, () => { const target = PublicCircuitPublicInputs.empty(); expect(target.isEmpty()).toBe(true); diff --git a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts index a1e1abad29e..d0d7961f538 100644 --- a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts @@ -2,7 +2,7 @@ import { makeTuple } from '@aztec/foundation/array'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { isArrayEmpty } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/fields'; -import { Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { FieldReader, Tuple, serializeToBuffer, serializeToFieldArray } from '@aztec/foundation/serialize'; import { FieldsOf } from '@aztec/foundation/types'; import { @@ -12,10 +12,17 @@ import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, + NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH, } from '../constants.gen.js'; import { CallContext } from './call_context.js'; -import { ContractStorageRead, ContractStorageUpdateRequest, Header, SideEffect, SideEffectLinkedToNoteHash } from './index.js'; +import { + ContractStorageRead, + ContractStorageUpdateRequest, + Header, + SideEffect, + SideEffectLinkedToNoteHash, +} from './index.js'; /** * Public inputs to a public circuit. @@ -164,4 +171,45 @@ export class PublicCircuitPublicInputs { toBuffer(): Buffer { return serializeToBuffer(...PublicCircuitPublicInputs.getFields(this)); } + + toFields(): Fr[] { + return serializeToFieldArray(...PublicCircuitPublicInputs.getFields(this)); + } + + static fromFields(fields: Fr[] | FieldReader): PublicCircuitPublicInputs { + const reader = FieldReader.asReader(fields); + + const callContext = CallContext.fromFields(reader); + const argsHash = reader.readField(); + const returnValues = reader.readFieldArray(RETURN_VALUES_LENGTH); + const contractStorageUpdateRequests = reader.readArray( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, + ContractStorageUpdateRequest, + ); + const contractStorageReads = reader.readArray(MAX_PUBLIC_DATA_READS_PER_CALL, ContractStorageRead); + const publicCallStackHashes = reader.readFieldArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL); + const newCommitments = reader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect); + const newNullifiers = reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash); + const newL2ToL1Msgs = reader.readFieldArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL); + const unencryptedLogsHash = reader.readFieldArray(NUM_FIELDS_PER_SHA256); + const unencryptedLogPreimagesLength = reader.readField(); + const historicalHeader = Header.fromFields(reader); + const proverAddress = AztecAddress.fromFields(reader); + + return new PublicCircuitPublicInputs( + callContext, + argsHash, + returnValues, + contractStorageUpdateRequests, + contractStorageReads, + publicCallStackHashes, + newCommitments, + newNullifiers, + newL2ToL1Msgs, + unencryptedLogsHash, + unencryptedLogPreimagesLength, + historicalHeader, + proverAddress, + ); + } } From 1fba60884bcb15f0137a7229a924f7e5e06fe8a1 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 1 Feb 2024 13:36:31 +0000 Subject: [PATCH 6/8] cleanup of extractPrivateCircuitPublicInputs --- .../acir-simulator/src/acvm/deserialize.ts | 80 +------------------ 1 file changed, 3 insertions(+), 77 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/deserialize.ts b/yarn-project/acir-simulator/src/acvm/deserialize.ts index 82ae5b1fce0..8b901ed0fbc 100644 --- a/yarn-project/acir-simulator/src/acvm/deserialize.ts +++ b/yarn-project/acir-simulator/src/acvm/deserialize.ts @@ -1,25 +1,5 @@ -import { - CallContext, - ContractDeploymentData, - HEADER_LENGTH, - Header, - MAX_NEW_COMMITMENTS_PER_CALL, - MAX_NEW_L2_TO_L1_MSGS_PER_CALL, - MAX_NEW_NULLIFIERS_PER_CALL, - MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, - MAX_READ_REQUESTS_PER_CALL, - NUM_FIELDS_PER_SHA256, - NullifierKeyValidationRequest, - PrivateCircuitPublicInputs, - PublicCircuitPublicInputs, - RETURN_VALUES_LENGTH, - SideEffect, - SideEffectLinkedToNoteHash, -} from '@aztec/circuits.js'; -import { EthAddress } from '@aztec/foundation/eth-address'; -import { Fr, Point } from '@aztec/foundation/fields'; +import { PrivateCircuitPublicInputs, PublicCircuitPublicInputs } from '@aztec/circuits.js'; +import { Fr } from '@aztec/foundation/fields'; import { FieldReader } from '@aztec/foundation/serialize'; import { getReturnWitness } from '@noir-lang/acvm_js'; @@ -75,61 +55,7 @@ export function extractPrivateCircuitPublicInputs( acir: Buffer, ): PrivateCircuitPublicInputs { const witnessReader = createPublicInputsReader(partialWitness, acir); - - const callContext = witnessReader.readObject(CallContext); - const argsHash = witnessReader.readField(); - const returnValues = witnessReader.readFieldArray(RETURN_VALUES_LENGTH); - const readRequests = witnessReader.readArray(MAX_READ_REQUESTS_PER_CALL, SideEffect); - const nullifierKeyValidationRequests = witnessReader.readArray( - MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, - NullifierKeyValidationRequest, - ); - const newCommitments = witnessReader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect); - const newNullifiers = witnessReader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash); - const privateCallStack = witnessReader.readFieldArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL); - const publicCallStack = witnessReader.readFieldArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL); - const newL2ToL1Msgs = witnessReader.readFieldArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL); - const endSideEffectCounter = witnessReader.readField(); - - const encryptedLogsHash = witnessReader.readFieldArray(NUM_FIELDS_PER_SHA256); - const unencryptedLogsHash = witnessReader.readFieldArray(NUM_FIELDS_PER_SHA256); - const encryptedLogPreimagesLength = witnessReader.readField(); - const unencryptedLogPreimagesLength = witnessReader.readField(); - - const header = Header.fromFields(witnessReader.readFieldArray(HEADER_LENGTH)); - - const contractDeploymentData = new ContractDeploymentData( - new Point(witnessReader.readField(), witnessReader.readField()), - witnessReader.readField(), - witnessReader.readField(), - witnessReader.readField(), - EthAddress.fromField(witnessReader.readField()), - ); - - const chainId = witnessReader.readField(); - const version = witnessReader.readField(); - - return new PrivateCircuitPublicInputs( - callContext, - argsHash, - returnValues, - readRequests, - nullifierKeyValidationRequests, - newCommitments, - newNullifiers, - privateCallStack, - publicCallStack, - newL2ToL1Msgs, - endSideEffectCounter, - encryptedLogsHash, - unencryptedLogsHash, - encryptedLogPreimagesLength, - unencryptedLogPreimagesLength, - header, - contractDeploymentData, - chainId, - version, - ); + return PrivateCircuitPublicInputs.fromFields(witnessReader); } /** From d14c88f3e70fcfbc234b9f9f9c4da43b86db387b Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 1 Feb 2024 14:37:02 +0000 Subject: [PATCH 7/8] nuking extractPublicCircuitPublicInputs and extractPrivateCircuitPublicInputs --- .../acir-simulator/src/acvm/deserialize.ts | 35 ------------------- .../src/client/private_execution.ts | 7 ++-- .../acir-simulator/src/public/executor.ts | 7 ++-- 3 files changed, 8 insertions(+), 41 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/deserialize.ts b/yarn-project/acir-simulator/src/acvm/deserialize.ts index 8b901ed0fbc..44bbd85d6a6 100644 --- a/yarn-project/acir-simulator/src/acvm/deserialize.ts +++ b/yarn-project/acir-simulator/src/acvm/deserialize.ts @@ -1,6 +1,4 @@ -import { PrivateCircuitPublicInputs, PublicCircuitPublicInputs } from '@aztec/circuits.js'; import { Fr } from '@aztec/foundation/fields'; -import { FieldReader } from '@aztec/foundation/serialize'; import { getReturnWitness } from '@noir-lang/acvm_js'; @@ -35,36 +33,3 @@ export function extractReturnWitness(acir: Buffer, partialWitness: ACVMWitness): const sortedKeys = [...returnWitness.keys()].sort((a, b) => a - b); return sortedKeys.map(key => returnWitness.get(key)!).map(fromACVMField); } - -/** - * Create a reader for the public inputs of the ACVM generated partial witness. - */ -function createPublicInputsReader(witness: ACVMWitness, acir: Buffer) { - const fields = extractReturnWitness(acir, witness); - return new FieldReader(fields); -} - -/** - * Extracts the public inputs from the ACVM generated partial witness. - * @param partialWitness - The partial witness. - * @param acir - The ACIR bytecode. - * @returns The public inputs. - */ -export function extractPrivateCircuitPublicInputs( - partialWitness: ACVMWitness, - acir: Buffer, -): PrivateCircuitPublicInputs { - const witnessReader = createPublicInputsReader(partialWitness, acir); - return PrivateCircuitPublicInputs.fromFields(witnessReader); -} - -/** - * Extracts the public circuit public inputs from the ACVM generated partial witness. - * @param partialWitness - The partial witness. - * @param acir - The ACIR bytecode. - * @returns The public inputs. - */ -export function extractPublicCircuitPublicInputs(partialWitness: ACVMWitness, acir: Buffer): PublicCircuitPublicInputs { - const witnessReader = createPublicInputsReader(partialWitness, acir); - return PublicCircuitPublicInputs.fromFields(witnessReader); -} diff --git a/yarn-project/acir-simulator/src/client/private_execution.ts b/yarn-project/acir-simulator/src/client/private_execution.ts index c16fcd83b34..f02ca372be9 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.ts @@ -1,11 +1,11 @@ -import { FunctionData, PrivateCallStackItem } from '@aztec/circuits.js'; +import { FunctionData, PrivateCallStackItem, PrivateCircuitPublicInputs } from '@aztec/circuits.js'; import { FunctionArtifactWithDebugMetadata, decodeReturnValues } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { to2Fields } from '@aztec/foundation/serialize'; -import { extractPrivateCircuitPublicInputs } from '../acvm/deserialize.js'; +import { extractReturnWitness } from '../acvm/deserialize.js'; import { Oracle, acvm, extractCallStack } from '../acvm/index.js'; import { ExecutionError } from '../common/errors.js'; import { ClientExecutionContext } from './client_execution_context.js'; @@ -42,7 +42,8 @@ export async function executePrivateFunction( }, ); - const publicInputs = extractPrivateCircuitPublicInputs(partialWitness, acir); + const returnWitness = extractReturnWitness(acir, partialWitness); + const publicInputs = PrivateCircuitPublicInputs.fromFields(returnWitness); const encryptedLogs = context.getEncryptedLogs(); const unencryptedLogs = context.getUnencryptedLogs(); diff --git a/yarn-project/acir-simulator/src/public/executor.ts b/yarn-project/acir-simulator/src/public/executor.ts index 67af8c89a57..e5d3b935403 100644 --- a/yarn-project/acir-simulator/src/public/executor.ts +++ b/yarn-project/acir-simulator/src/public/executor.ts @@ -1,7 +1,7 @@ -import { GlobalVariables, Header } from '@aztec/circuits.js'; +import { GlobalVariables, Header, PublicCircuitPublicInputs } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; -import { Oracle, acvm, extractCallStack, extractPublicCircuitPublicInputs } from '../acvm/index.js'; +import { Oracle, acvm, extractCallStack, extractReturnWitness } from '../acvm/index.js'; import { ExecutionError, createSimulationError } from '../common/errors.js'; import { SideEffectCounter } from '../common/index.js'; import { PackedArgsCache } from '../common/packed_args_cache.js'; @@ -39,12 +39,13 @@ export async function executePublicFunction( }, ); + const returnWitness = extractReturnWitness(acir, partialWitness); const { returnValues, newL2ToL1Msgs, newCommitments: newCommitmentsPadded, newNullifiers: newNullifiersPadded, - } = extractPublicCircuitPublicInputs(partialWitness, acir); + } = PublicCircuitPublicInputs.fromFields(returnWitness); const newL2ToL1Messages = newL2ToL1Msgs.filter(v => !v.isZero()); const newCommitments = newCommitmentsPadded.filter(v => !v.isEmpty()); From bb571a221ac240679d4aa6d9cfef9b7fe07bcbc5 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 1 Feb 2024 14:41:40 +0000 Subject: [PATCH 8/8] comment --- yarn-project/acir-simulator/src/acvm/deserialize.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn-project/acir-simulator/src/acvm/deserialize.ts b/yarn-project/acir-simulator/src/acvm/deserialize.ts index 44bbd85d6a6..57a9e437fc5 100644 --- a/yarn-project/acir-simulator/src/acvm/deserialize.ts +++ b/yarn-project/acir-simulator/src/acvm/deserialize.ts @@ -17,6 +17,7 @@ export function fromACVMField(field: ACVMField): Fr { * Converts a field to a number. * @param fr - The field to convert. * @returns The number. + * TODO(#4102): Nuke this once block number is big int. */ export function frToNumber(fr: Fr): number { return Number(fr.value);