diff --git a/yarn-project/archiver/src/archiver/archiver.test.ts b/yarn-project/archiver/src/archiver/archiver.test.ts index 48471c74aa3c..3a4e4428a4c1 100644 --- a/yarn-project/archiver/src/archiver/archiver.test.ts +++ b/yarn-project/archiver/src/archiver/archiver.test.ts @@ -1,4 +1,4 @@ -import { Body, L2Block, L2BlockL2Logs, LogType } from '@aztec/circuit-types'; +import { Body, EncryptedL2BlockL2Logs, L2Block, LogType, UnencryptedL2BlockL2Logs } from '@aztec/circuit-types'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; import { sleep } from '@aztec/foundation/sleep'; @@ -102,7 +102,7 @@ describe('Archiver', () => { for (const [index, x] of blockNumbers.entries()) { const expectedTotalNumEncryptedLogs = 4 * x * (x * 2); - const totalNumEncryptedLogs = L2BlockL2Logs.unrollLogs([encryptedLogs[index]]).length; + const totalNumEncryptedLogs = EncryptedL2BlockL2Logs.unrollLogs([encryptedLogs[index]]).length; expect(totalNumEncryptedLogs).toEqual(expectedTotalNumEncryptedLogs); } @@ -111,7 +111,7 @@ describe('Archiver', () => { blockNumbers.forEach((x, index) => { const expectedTotalNumUnencryptedLogs = 4 * (x + 1) * (x * 3); - const totalNumUnencryptedLogs = L2BlockL2Logs.unrollLogs([unencryptedLogs[index]]).length; + const totalNumUnencryptedLogs = UnencryptedL2BlockL2Logs.unrollLogs([unencryptedLogs[index]]).length; expect(totalNumUnencryptedLogs).toEqual(expectedTotalNumUnencryptedLogs); }); diff --git a/yarn-project/archiver/src/archiver/archiver.ts b/yarn-project/archiver/src/archiver/archiver.ts index ebf8df6d1780..e7228ff5bf42 100644 --- a/yarn-project/archiver/src/archiver/archiver.ts +++ b/yarn-project/archiver/src/archiver/archiver.ts @@ -1,4 +1,5 @@ import { + FromLogType, GetUnencryptedLogsResponse, L1ToL2MessageSource, L2Block, @@ -276,8 +277,7 @@ export class Archiver implements ArchiveSource { retrievedBlocks.retrievedData.map(async block => { const blockLogs = block.body.txEffects .flatMap(txEffect => (txEffect ? [txEffect.unencryptedLogs] : [])) - .flatMap(txLog => txLog.unrollLogs()) - .map(log => UnencryptedL2Log.fromBuffer(log)); + .flatMap(txLog => txLog.unrollLogs()); await this.storeRegisteredContractClasses(blockLogs, block.number); await this.storeDeployedContractInstances(blockLogs, block.number); await this.storeBroadcastedIndividualFunctions(blockLogs, block.number); @@ -437,7 +437,11 @@ export class Archiver implements ArchiveSource { * @param logType - Specifies whether to return encrypted or unencrypted logs. * @returns The requested logs. */ - public getLogs(from: number, limit: number, logType: LogType): Promise { + public getLogs( + from: number, + limit: number, + logType: TLogType, + ): Promise>[]> { return this.store.getLogs(from, limit, logType); } diff --git a/yarn-project/archiver/src/archiver/archiver_store.ts b/yarn-project/archiver/src/archiver/archiver_store.ts index 6072172b5e47..ad6a792c75f5 100644 --- a/yarn-project/archiver/src/archiver/archiver_store.ts +++ b/yarn-project/archiver/src/archiver/archiver_store.ts @@ -1,5 +1,7 @@ import { Body, + EncryptedL2BlockL2Logs, + FromLogType, GetUnencryptedLogsResponse, InboxLeaf, L2Block, @@ -9,6 +11,7 @@ import { TxEffect, TxHash, TxReceipt, + UnencryptedL2BlockL2Logs, } from '@aztec/circuit-types'; import { Fr } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; @@ -88,8 +91,8 @@ export interface ArchiverDataStore { * @returns True if the operation is successful. */ addLogs( - encryptedLogs: L2BlockL2Logs | undefined, - unencryptedLogs: L2BlockL2Logs | undefined, + encryptedLogs: EncryptedL2BlockL2Logs | undefined, + unencryptedLogs: UnencryptedL2BlockL2Logs | undefined, blockNumber: number, ): Promise; @@ -122,7 +125,11 @@ export interface ArchiverDataStore { * @param logType - Specifies whether to return encrypted or unencrypted logs. * @returns The requested logs. */ - getLogs(from: number, limit: number, logType: LogType): Promise; + getLogs( + from: number, + limit: number, + logType: TLogType, + ): Promise>[]>; /** * Gets unencrypted logs based on the provided filter. diff --git a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts index 056e783f2bb3..1117ee277b54 100644 --- a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts +++ b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts @@ -1,4 +1,4 @@ -import { InboxLeaf, L2Block, L2BlockContext, LogId, LogType, TxHash, UnencryptedL2Log } from '@aztec/circuit-types'; +import { InboxLeaf, L2Block, L2BlockContext, LogId, LogType, TxHash } from '@aztec/circuit-types'; import '@aztec/circuit-types/jest'; import { AztecAddress, Fr, INITIAL_L2_BLOCK_NUM, L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/circuits.js'; import { @@ -367,11 +367,10 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch const targetTxIndex = randomInt(txsPerBlock); const targetFunctionLogIndex = randomInt(numPublicFunctionCalls); const targetLogIndex = randomInt(numUnencryptedLogs); - const targetContractAddress = UnencryptedL2Log.fromBuffer( + const targetContractAddress = blocks.retrievedData[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[ targetFunctionLogIndex - ].logs[targetLogIndex], - ).contractAddress; + ].logs[targetLogIndex].contractAddress; const response = await store.getUnencryptedLogs({ contractAddress: targetContractAddress }); @@ -388,11 +387,10 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch const targetTxIndex = randomInt(txsPerBlock); const targetFunctionLogIndex = randomInt(numPublicFunctionCalls); const targetLogIndex = randomInt(numUnencryptedLogs); - const targetSelector = UnencryptedL2Log.fromBuffer( + const targetSelector = blocks.retrievedData[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[ targetFunctionLogIndex - ].logs[targetLogIndex], - ).selector; + ].logs[targetLogIndex].selector; const response = await store.getUnencryptedLogs({ selector: targetSelector }); diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts index b084d3940dbd..ab8c12d795d7 100644 --- a/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts +++ b/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts @@ -1,5 +1,7 @@ import { Body, + EncryptedL2BlockL2Logs, + FromLogType, GetUnencryptedLogsResponse, InboxLeaf, L2Block, @@ -9,6 +11,7 @@ import { TxEffect, TxHash, TxReceipt, + UnencryptedL2BlockL2Logs, } from '@aztec/circuit-types'; import { Fr } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; @@ -150,8 +153,8 @@ export class KVArchiverDataStore implements ArchiverDataStore { * @returns True if the operation is successful. */ addLogs( - encryptedLogs: L2BlockL2Logs | undefined, - unencryptedLogs: L2BlockL2Logs | undefined, + encryptedLogs: EncryptedL2BlockL2Logs | undefined, + unencryptedLogs: UnencryptedL2BlockL2Logs | undefined, blockNumber: number, ): Promise { return this.#logStore.addLogs(encryptedLogs, unencryptedLogs, blockNumber); @@ -196,7 +199,11 @@ export class KVArchiverDataStore implements ArchiverDataStore { * @param logType - Specifies whether to return encrypted or unencrypted logs. * @returns The requested logs. */ - getLogs(start: number, limit: number, logType: LogType): Promise { + getLogs( + start: number, + limit: number, + logType: TLogType, + ): Promise>[]> { try { return Promise.resolve(Array.from(this.#logStore.getLogs(start, limit, logType))); } catch (err) { diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/log_store.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/log_store.ts index 6c30395d7129..cada02c9979a 100644 --- a/yarn-project/archiver/src/archiver/kv_archiver_store/log_store.ts +++ b/yarn-project/archiver/src/archiver/kv_archiver_store/log_store.ts @@ -1,10 +1,13 @@ import { + EncryptedL2BlockL2Logs, ExtendedUnencryptedL2Log, + FromLogType, GetUnencryptedLogsResponse, L2BlockL2Logs, LogFilter, LogId, LogType, + UnencryptedL2BlockL2Logs, UnencryptedL2Log, } from '@aztec/circuit-types'; import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants'; @@ -37,8 +40,8 @@ export class LogStore { * @returns True if the operation is successful. */ addLogs( - encryptedLogs: L2BlockL2Logs | undefined, - unencryptedLogs: L2BlockL2Logs | undefined, + encryptedLogs: EncryptedL2BlockL2Logs | undefined, + unencryptedLogs: UnencryptedL2BlockL2Logs | undefined, blockNumber: number, ): Promise { return this.db.transaction(() => { @@ -61,10 +64,15 @@ export class LogStore { * @param logType - Specifies whether to return encrypted or unencrypted logs. * @returns The requested logs. */ - *getLogs(start: number, limit: number, logType: LogType): IterableIterator { + *getLogs( + start: number, + limit: number, + logType: TLogType, + ): IterableIterator>> { const logMap = logType === LogType.ENCRYPTED ? this.#encryptedLogs : this.#unencryptedLogs; + const L2BlockL2Logs = logType === LogType.ENCRYPTED ? EncryptedL2BlockL2Logs : UnencryptedL2BlockL2Logs; for (const buffer of logMap.values({ start, limit })) { - yield L2BlockL2Logs.fromBuffer(buffer); + yield L2BlockL2Logs.fromBuffer(buffer) as L2BlockL2Logs>; } } @@ -94,7 +102,7 @@ export class LogStore { } const unencryptedLogsInBlock = this.#getBlockLogs(blockNumber, LogType.UNENCRYPTED); - const txLogs = unencryptedLogsInBlock.txLogs[txIndex].unrollLogs().map(log => UnencryptedL2Log.fromBuffer(log)); + const txLogs = unencryptedLogsInBlock.txLogs[txIndex].unrollLogs(); const logs: ExtendedUnencryptedL2Log[] = []; const maxLogsHit = this.#accumulateLogs(logs, blockNumber, txIndex, txLogs, filter); @@ -118,9 +126,9 @@ export class LogStore { let maxLogsHit = false; loopOverBlocks: for (const [blockNumber, logBuffer] of this.#unencryptedLogs.entries({ start, end })) { - const unencryptedLogsInBlock = L2BlockL2Logs.fromBuffer(logBuffer); + const unencryptedLogsInBlock = UnencryptedL2BlockL2Logs.fromBuffer(logBuffer); for (let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < unencryptedLogsInBlock.txLogs.length; txIndex++) { - const txLogs = unencryptedLogsInBlock.txLogs[txIndex].unrollLogs().map(log => UnencryptedL2Log.fromBuffer(log)); + const txLogs = unencryptedLogsInBlock.txLogs[txIndex].unrollLogs(); maxLogsHit = this.#accumulateLogs(logs, blockNumber, txIndex, txLogs, filter); if (maxLogsHit) { this.#log(`Max logs hit at block ${blockNumber}`); @@ -161,14 +169,19 @@ export class LogStore { return maxLogsHit; } - #getBlockLogs(blockNumber: number, logType: LogType): L2BlockL2Logs { + #getBlockLogs( + blockNumber: number, + logType: TLogType, + ): L2BlockL2Logs> { const logMap = logType === LogType.ENCRYPTED ? this.#encryptedLogs : this.#unencryptedLogs; + const L2BlockL2Logs: typeof EncryptedL2BlockL2Logs | typeof UnencryptedL2BlockL2Logs = + logType === LogType.ENCRYPTED ? EncryptedL2BlockL2Logs : UnencryptedL2BlockL2Logs; const buffer = logMap.get(blockNumber); if (!buffer) { - return new L2BlockL2Logs([]); + return new L2BlockL2Logs([]) as L2BlockL2Logs>; } - return L2BlockL2Logs.fromBuffer(buffer); + return L2BlockL2Logs.fromBuffer(buffer) as L2BlockL2Logs>; } } 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 0efc82081c48..43d197cc576c 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 @@ -1,6 +1,8 @@ import { Body, + EncryptedL2BlockL2Logs, ExtendedUnencryptedL2Log, + FromLogType, GetUnencryptedLogsResponse, InboxLeaf, L2Block, @@ -13,7 +15,7 @@ import { TxHash, TxReceipt, TxStatus, - UnencryptedL2Log, + UnencryptedL2BlockL2Logs, } from '@aztec/circuit-types'; import { Fr, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; @@ -51,13 +53,13 @@ export class MemoryArchiverStore implements ArchiverDataStore { * An array containing all the encrypted logs that have been fetched so far. * Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM). */ - private encryptedLogsPerBlock: L2BlockL2Logs[] = []; + private encryptedLogsPerBlock: EncryptedL2BlockL2Logs[] = []; /** * An array containing all the unencrypted logs that have been fetched so far. * Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM). */ - private unencryptedLogsPerBlock: L2BlockL2Logs[] = []; + private unencryptedLogsPerBlock: UnencryptedL2BlockL2Logs[] = []; /** * Contains all L1 to L2 messages. @@ -183,7 +185,11 @@ export class MemoryArchiverStore implements ArchiverDataStore { * @param blockNumber - The block for which to add the logs. * @returns True if the operation is successful. */ - addLogs(encryptedLogs: L2BlockL2Logs, unencryptedLogs: L2BlockL2Logs, blockNumber: number): Promise { + addLogs( + encryptedLogs: EncryptedL2BlockL2Logs, + unencryptedLogs: UnencryptedL2BlockL2Logs, + blockNumber: number, + ): Promise { if (encryptedLogs) { this.encryptedLogsPerBlock[blockNumber - INITIAL_L2_BLOCK_NUM] = encryptedLogs; } @@ -288,11 +294,17 @@ export class MemoryArchiverStore implements ArchiverDataStore { * @param logType - Specifies whether to return encrypted or unencrypted logs. * @returns The requested logs. */ - getLogs(from: number, limit: number, logType: LogType): Promise { + getLogs( + from: number, + limit: number, + logType: TLogType, + ): Promise>[]> { if (from < INITIAL_L2_BLOCK_NUM || limit < 1) { throw new Error(`Invalid limit: ${limit}`); } - const logs = logType === LogType.ENCRYPTED ? this.encryptedLogsPerBlock : this.unencryptedLogsPerBlock; + const logs = ( + logType === LogType.ENCRYPTED ? this.encryptedLogsPerBlock : this.unencryptedLogsPerBlock + ) as L2BlockL2Logs>[]; if (from > logs.length) { return Promise.resolve([]); } @@ -355,7 +367,7 @@ export class MemoryArchiverStore implements ArchiverDataStore { const blockContext = this.l2BlockContexts[fromBlockIndex]; const blockLogs = this.unencryptedLogsPerBlock[fromBlockIndex]; for (; txIndexInBlock < blockLogs.txLogs.length; txIndexInBlock++) { - const txLogs = blockLogs.txLogs[txIndexInBlock].unrollLogs().map(log => UnencryptedL2Log.fromBuffer(log)); + const txLogs = blockLogs.txLogs[txIndexInBlock].unrollLogs(); for (; logIndexInTx < txLogs.length; logIndexInTx++) { const log = txLogs[logIndexInTx]; if ( diff --git a/yarn-project/archiver/src/rpc/archiver_client.ts b/yarn-project/archiver/src/rpc/archiver_client.ts index a77b7df3d6e2..2e456cc6218b 100644 --- a/yarn-project/archiver/src/rpc/archiver_client.ts +++ b/yarn-project/archiver/src/rpc/archiver_client.ts @@ -1,9 +1,10 @@ import { + EncryptedL2BlockL2Logs, ExtendedUnencryptedL2Log, L2Block, - L2BlockL2Logs, NullifierMembershipWitness, TxReceipt, + UnencryptedL2BlockL2Logs, } from '@aztec/circuit-types'; import { EthAddress, Fr } from '@aztec/circuits.js'; import { createJsonRpcClient, makeFetch } from '@aztec/foundation/json-rpc/client'; @@ -18,10 +19,11 @@ export const createArchiverClient = (url: string, fetch = makeFetch([1, 2, 3], t ExtendedUnencryptedL2Log, Fr, L2Block, - L2BlockL2Logs, + EncryptedL2BlockL2Logs, + UnencryptedL2BlockL2Logs, }, { TxReceipt, NullifierMembershipWitness }, false, 'archiver', fetch, - ); + ) as ArchiveSource; diff --git a/yarn-project/archiver/src/rpc/archiver_server.ts b/yarn-project/archiver/src/rpc/archiver_server.ts index 6a9efa8d1fea..8e96db9bcbb6 100644 --- a/yarn-project/archiver/src/rpc/archiver_server.ts +++ b/yarn-project/archiver/src/rpc/archiver_server.ts @@ -1,10 +1,11 @@ import { + EncryptedL2BlockL2Logs, ExtendedUnencryptedL2Log, L2Block, - L2BlockL2Logs, NullifierMembershipWitness, TxEffect, TxReceipt, + UnencryptedL2BlockL2Logs, } from '@aztec/circuit-types'; import { EthAddress, Fr } from '@aztec/circuits.js'; import { JsonRpcServer } from '@aztec/foundation/json-rpc/server'; @@ -24,7 +25,8 @@ export function createArchiverRpcServer(archiverService: Archiver): JsonRpcServe ExtendedUnencryptedL2Log, Fr, L2Block, - L2BlockL2Logs, + EncryptedL2BlockL2Logs, + UnencryptedL2BlockL2Logs, TxEffect, }, { TxReceipt, NullifierMembershipWitness }, 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 24cea8129552..7158662dfc5d 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 @@ -1,8 +1,8 @@ import { AztecNode, + EncryptedL2BlockL2Logs, ExtendedUnencryptedL2Log, L2Block, - L2BlockL2Logs, LogId, NullifierMembershipWitness, SiblingPath, @@ -10,6 +10,7 @@ import { TxEffect, TxHash, TxReceipt, + UnencryptedL2BlockL2Logs, } from '@aztec/circuit-types'; import { FunctionSelector, Header } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; @@ -38,7 +39,7 @@ export function createAztecNodeRpcServer(node: AztecNode) { TxHash, SiblingPath, }, - { Tx, TxReceipt, L2BlockL2Logs, NullifierMembershipWitness }, + { Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness }, // disable methods not part of the AztecNode interface ['start', 'stop'], ); diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 21e1d4ab3f17..f905fbe31869 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -1,6 +1,7 @@ import { ArchiveSource, Archiver, KVArchiverDataStore, createArchiverClient } from '@aztec/archiver'; import { AztecNode, + FromLogType, GetUnencryptedLogsResponse, L1ToL2MessageSource, L2Block, @@ -265,9 +266,13 @@ export class AztecNodeService implements AztecNode { * @param logType - Specifies whether to return encrypted or unencrypted logs. * @returns The requested logs. */ - public getLogs(from: number, limit: number, logType: LogType): Promise { + public getLogs( + from: number, + limit: number, + logType: LogType, + ): Promise>[]> { const logSource = logType === LogType.ENCRYPTED ? this.encryptedLogsSource : this.unencryptedLogsSource; - return logSource.getLogs(from, limit, logType); + return logSource.getLogs(from, limit, logType) as Promise>[]>; } /** diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index 8b7785c05848..646c5488bf9b 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -90,6 +90,8 @@ export { L2Actor, L2Block, L2BlockL2Logs, + EncryptedL2BlockL2Logs, + UnencryptedL2BlockL2Logs, LogFilter, LogId, LogType, diff --git a/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts b/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts index c0e740d4d1eb..59ced8b1cc44 100644 --- a/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts +++ b/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts @@ -1,9 +1,9 @@ import { AuthWitness, + EncryptedL2BlockL2Logs, ExtendedNote, ExtendedUnencryptedL2Log, L2Block, - L2BlockL2Logs, LogId, Note, NullifierMembershipWitness, @@ -13,6 +13,7 @@ import { TxExecutionRequest, TxHash, TxReceipt, + UnencryptedL2BlockL2Logs, } from '@aztec/circuit-types'; import { AztecAddress, @@ -52,7 +53,7 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], false) TxExecutionRequest, TxHash, }, - { Tx, TxReceipt, L2BlockL2Logs, NullifierMembershipWitness }, + { Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness }, false, 'pxe', fetch, 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 30a70f88fa85..2e093883d1e8 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 @@ -8,7 +8,7 @@ import { createJsonRpcClient, defaultFetch } from '@aztec/foundation/json-rpc/cl import { AztecNode } from '../../interfaces/aztec-node.js'; import { NullifierMembershipWitness } from '../../interfaces/nullifier_tree.js'; import { L2Block } from '../../l2_block.js'; -import { ExtendedUnencryptedL2Log, L2BlockL2Logs, LogId } from '../../logs/index.js'; +import { EncryptedL2BlockL2Logs, ExtendedUnencryptedL2Log, LogId, UnencryptedL2BlockL2Logs } from '../../logs/index.js'; import { SiblingPath } from '../../sibling_path/index.js'; import { Tx, TxHash, TxReceipt } from '../../tx/index.js'; import { TxEffect } from '../../tx_effect.js'; @@ -36,9 +36,9 @@ export function createAztecNodeClient(url: string, fetch = defaultFetch): AztecN TxHash, SiblingPath, }, - { Tx, TxReceipt, L2BlockL2Logs, NullifierMembershipWitness }, + { Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness }, false, 'node', fetch, - ); + ) as AztecNode; } diff --git a/yarn-project/circuit-types/src/body.ts b/yarn-project/circuit-types/src/body.ts index 79b794a9697b..3c9e0a87761a 100644 --- a/yarn-project/circuit-types/src/body.ts +++ b/yarn-project/circuit-types/src/body.ts @@ -1,4 +1,4 @@ -import { L2BlockL2Logs, TxEffect } from '@aztec/circuit-types'; +import { EncryptedL2BlockL2Logs, TxEffect, UnencryptedL2BlockL2Logs } from '@aztec/circuit-types'; import { sha256 } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, serializeToBuffer, truncateAndPad } from '@aztec/foundation/serialize'; @@ -65,16 +65,16 @@ export class Body { return computeRoot(leafs); } - get encryptedLogs(): L2BlockL2Logs { + get encryptedLogs(): EncryptedL2BlockL2Logs { const logs = this.txEffects.map(txEffect => txEffect.encryptedLogs); - return new L2BlockL2Logs(logs); + return new EncryptedL2BlockL2Logs(logs); } - get unencryptedLogs(): L2BlockL2Logs { + get unencryptedLogs(): UnencryptedL2BlockL2Logs { const logs = this.txEffects.map(txEffect => txEffect.unencryptedLogs); - return new L2BlockL2Logs(logs); + return new UnencryptedL2BlockL2Logs(logs); } get numberOfTxs() { diff --git a/yarn-project/circuit-types/src/interfaces/aztec-node.ts b/yarn-project/circuit-types/src/interfaces/aztec-node.ts index 291968417615..5c03eddccbc6 100644 --- a/yarn-project/circuit-types/src/interfaces/aztec-node.ts +++ b/yarn-project/circuit-types/src/interfaces/aztec-node.ts @@ -12,7 +12,7 @@ import { Fr } from '@aztec/foundation/fields'; import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/contracts'; import { L2Block } from '../l2_block.js'; -import { GetUnencryptedLogsResponse, L2BlockL2Logs, LogFilter, LogType } from '../logs/index.js'; +import { FromLogType, GetUnencryptedLogsResponse, L2BlockL2Logs, LogFilter, LogType } from '../logs/index.js'; import { MerkleTreeId } from '../merkle_tree_id.js'; import { SiblingPath } from '../sibling_path/index.js'; import { Tx, TxHash, TxReceipt } from '../tx/index.js'; @@ -203,7 +203,11 @@ export interface AztecNode { * @param logType - Specifies whether to return encrypted or unencrypted logs. * @returns The requested logs. */ - getLogs(from: number, limit: number, logType: LogType): Promise; + getLogs( + from: number, + limit: number, + logType: TLogType, + ): Promise>[]>; /** * Gets unencrypted logs based on the provided filter. diff --git a/yarn-project/circuit-types/src/l2_block.test.ts b/yarn-project/circuit-types/src/l2_block.test.ts index 1642e644c77f..42283c1fe854 100644 --- a/yarn-project/circuit-types/src/l2_block.test.ts +++ b/yarn-project/circuit-types/src/l2_block.test.ts @@ -1,5 +1,5 @@ import { L2Block } from './l2_block.js'; -import { TxL2Logs } from './logs/index.js'; +import { EncryptedTxL2Logs } from './logs/index.js'; describe('L2Block', () => { it('can serialize an L2 block with logs to a buffer and back', () => { @@ -15,7 +15,7 @@ describe('L2Block', () => { it('correctly computes kernel logs hash when there are no logs', () => { // The following 2 values are copied from `testComputeKernelLogsIterationWithoutLogs` in `Decoder.t.sol` const encodedLogs = Buffer.from('0000000400000000', 'hex'); - const logs = TxL2Logs.fromBuffer(encodedLogs, true); + const logs = EncryptedTxL2Logs.fromBuffer(encodedLogs, true); const referenceLogsHash = Buffer.from('006003947a07e21c81ce2062539d6d6864fe999b58b03fc46f6c190d9eac9b39', 'hex'); const logsHash = logs.hash(); @@ -26,7 +26,7 @@ describe('L2Block', () => { it('correctly computes kernel logs hash when are logs from 1 iteration', () => { // The following 2 values are copied from `testComputeKernelLogs1Iteration` in `Decoder.t.sol` const encodedLogs = Buffer.from('0000000c000000080000000493e78a70', 'hex'); - const logs = TxL2Logs.fromBuffer(encodedLogs, true); + const logs = EncryptedTxL2Logs.fromBuffer(encodedLogs, true); const referenceLogsHash = Buffer.from('00f458589e520e9e9bdaf746a7d226c39124e4a438f21fd41e6117a90f25f9a6', 'hex'); const logsHash = logs.hash(); @@ -40,7 +40,7 @@ describe('L2Block', () => { '00000024000000080000000493e78a70000000140000001006a86173c86c6d3f108eefc36e7fb014', 'hex', ); - const logs = TxL2Logs.fromBuffer(encodedLogs, true); + const logs = EncryptedTxL2Logs.fromBuffer(encodedLogs, true); const referenceLogsHash = Buffer.from('0084c3495a8cc56372f8f1d1efc0512920dae0f134d679cf26a12aff1509de14', 'hex'); const logsHash = logs.hash(); @@ -54,7 +54,7 @@ describe('L2Block', () => { '00000028000000080000000493e78a7000000000000000140000001006a86173c86c6d3f108eefc36e7fb014', 'hex', ); - const logs = TxL2Logs.fromBuffer(encodedLogs, true); + const logs = EncryptedTxL2Logs.fromBuffer(encodedLogs, true); const referenceLogsHash = Buffer.from('00fb7a99b84aad205b5a8368c12a5a6b2dc19e5d623a601717b337cdadb56aa4', 'hex'); const logsHash = logs.hash(); diff --git a/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts b/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts new file mode 100644 index 000000000000..4e11c696d2f3 --- /dev/null +++ b/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts @@ -0,0 +1,60 @@ +import { Fr, Point } from '@aztec/circuits.js'; +import { randomBytes } from '@aztec/foundation/crypto'; + +/** + * Represents an individual encrypted log entry. + */ +export class EncryptedL2Log { + constructor( + /** The encrypted data contents of the log. */ + public readonly data: Buffer, + ) {} + + get length(): number { + return this.data.length; + } + + /** + * Serializes log to a buffer. + * @returns A buffer containing the serialized log. + */ + public toBuffer(): Buffer { + return this.data; + } + + /** Returns a JSON-friendly representation of the log. */ + public toJSON(): object { + return { + data: this.data.toString('hex'), + }; + } + + /** Converts a plain JSON object into an instance. */ + public static fromJSON(obj: any) { + return new EncryptedL2Log(Buffer.from(obj.data, 'hex')); + } + + /** + * Deserializes log from a buffer. + * @param buffer - The buffer containing the log. + * @returns Deserialized instance of `Log`. + */ + public static fromBuffer(data: Buffer): EncryptedL2Log { + return new EncryptedL2Log(data); + } + + /** + * Crates a random log. + * @returns A random log. + */ + public static random(): EncryptedL2Log { + const randomEphPubKey = Point.random(); + const randomLogContent = randomBytes(144 - Point.SIZE_IN_BYTES); + const data = Buffer.concat([Fr.random().toBuffer(), randomLogContent, randomEphPubKey.toBuffer()]); + return new EncryptedL2Log(data); + } + + public static empty() { + return new EncryptedL2Log(Buffer.alloc(0)); + } +} 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 4c47ec6519ee..ae10dc63ed58 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 @@ -1,21 +1,37 @@ -import { FunctionL2Logs } from './function_l2_logs.js'; +import { EncryptedFunctionL2Logs, UnencryptedFunctionL2Logs } from './function_l2_logs.js'; -describe('FunctionL2Logs', () => { - it('can encode L2Logs to buffer and back', () => { - const l2Logs = FunctionL2Logs.random(42); +function shouldBehaveLikeFunctionL2Logs( + FunctionL2Logs: typeof UnencryptedFunctionL2Logs | typeof EncryptedFunctionL2Logs, +) { + describe(FunctionL2Logs.name, () => { + it('can encode L2Logs to buffer and back', () => { + const l2Logs = FunctionL2Logs.random(42); - const buffer = l2Logs.toBuffer(); - const recovered = FunctionL2Logs.fromBuffer(buffer); + const buffer = l2Logs.toBuffer(); + const recovered = FunctionL2Logs.fromBuffer(buffer); - expect(recovered).toEqual(l2Logs); - }); + expect(recovered).toEqual(l2Logs); + }); + + it('can encode L2Logs to JSON and back', () => { + const l2Logs = FunctionL2Logs.random(42); + + const buffer = l2Logs.toJSON(); + const recovered = FunctionL2Logs.fromJSON(buffer); - it('getSerializedLength returns the correct length', () => { - const l2Logs = FunctionL2Logs.random(42); + expect(recovered).toEqual(l2Logs); + }); - const buffer = l2Logs.toBuffer(); - const recovered = FunctionL2Logs.fromBuffer(buffer); + it('getSerializedLength returns the correct length', () => { + const l2Logs = FunctionL2Logs.random(42); - expect(recovered.getSerializedLength()).toEqual(buffer.length); + const buffer = l2Logs.toBuffer(); + const recovered = FunctionL2Logs.fromBuffer(buffer); + + expect(recovered.getSerializedLength()).toEqual(buffer.length); + }); }); -}); +} + +shouldBehaveLikeFunctionL2Logs(EncryptedFunctionL2Logs); +shouldBehaveLikeFunctionL2Logs(UnencryptedFunctionL2Logs); 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 5d544d299f00..12c44942915f 100644 --- a/yarn-project/circuit-types/src/logs/function_l2_logs.ts +++ b/yarn-project/circuit-types/src/logs/function_l2_logs.ts @@ -1,19 +1,18 @@ -import { randomBytes, sha256 } from '@aztec/foundation/crypto'; -import { Fr, Point } from '@aztec/foundation/fields'; +import { sha256 } from '@aztec/foundation/crypto'; import { BufferReader, prefixBufferWithLength, truncateAndPad } from '@aztec/foundation/serialize'; -import { LogType } from './log_type.js'; +import { EncryptedL2Log } from './encrypted_l2_log.js'; import { UnencryptedL2Log } from './unencrypted_l2_log.js'; /** * Data container of logs emitted in 1 function invocation (corresponds to 1 kernel iteration). */ -export class FunctionL2Logs { +export abstract class FunctionL2Logs { constructor( /** * An array of logs. */ - public readonly logs: Buffer[], + public readonly logs: TLog[], ) {} /** @@ -23,7 +22,7 @@ export class FunctionL2Logs { * the resulting buffer is prefixed with 4 bytes for its total length. */ public toBuffer(): Buffer { - const serializedLogs = this.logs.map(buffer => prefixBufferWithLength(buffer)); + const serializedLogs = this.logs.map(log => prefixBufferWithLength(log.toBuffer())); return prefixBufferWithLength(Buffer.concat(serializedLogs)); } @@ -47,58 +46,104 @@ export class FunctionL2Logs { return truncateAndPad(sha256(preimage)); } + /** + * Convert a FunctionL2Logs class object to a plain JSON object. + * @returns A plain object with FunctionL2Logs properties. + */ + public toJSON() { + return { + logs: this.logs.map(log => log.toJSON()), + }; + } +} + +export class EncryptedFunctionL2Logs extends FunctionL2Logs { + /** + * Creates an empty L2Logs object with no logs. + * @returns A new FunctionL2Logs object with no logs. + */ + public static empty(): EncryptedFunctionL2Logs { + return new EncryptedFunctionL2Logs([]); + } + /** * Deserializes logs from a buffer. * @param buf - The buffer containing the serialized logs. * @param isLengthPrefixed - Whether the buffer is prefixed with 4 bytes for its total length. * @returns Deserialized instance of `FunctionL2Logs`. */ - public static fromBuffer(buf: Buffer, isLengthPrefixed = true): FunctionL2Logs { + public static fromBuffer(buf: Buffer, isLengthPrefixed = true): EncryptedFunctionL2Logs { const reader = new BufferReader(buf, 0); // If the buffer is length prefixed use the length to read the array. Otherwise, the entire buffer is consumed. const logsBufLength = isLengthPrefixed ? reader.readNumber() : -1; const logs = reader.readBufferArray(logsBufLength); - return new FunctionL2Logs(logs); + return new EncryptedFunctionL2Logs(logs.map(EncryptedL2Log.fromBuffer)); } /** * Creates a new L2Logs object with `numLogs` logs. * @param numLogs - The number of logs to create. * @param logType - The type of logs to generate. - * @returns A new FunctionL2Logs object. + * @returns A new EncryptedFunctionL2Logs object. */ - public static random(numLogs: number, logType = LogType.ENCRYPTED): FunctionL2Logs { - const logs: Buffer[] = []; + public static random(numLogs: number): EncryptedFunctionL2Logs { + const logs: EncryptedL2Log[] = []; for (let i = 0; i < numLogs; i++) { - if (logType === LogType.ENCRYPTED) { - const randomEphPubKey = Point.random(); - const randomLogContent = randomBytes(144 - Point.SIZE_IN_BYTES); - logs.push(Buffer.concat([Fr.random().toBuffer(), randomLogContent, randomEphPubKey.toBuffer()])); - } else { - logs.push(UnencryptedL2Log.random().toBuffer()); - } + logs.push(EncryptedL2Log.random()); } - return new FunctionL2Logs(logs); + 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 { /** * Creates an empty L2Logs object with no logs. * @returns A new FunctionL2Logs object with no logs. */ - public static empty(): FunctionL2Logs { - return new FunctionL2Logs([]); + public static empty(): UnencryptedFunctionL2Logs { + return new UnencryptedFunctionL2Logs([]); } /** - * Convert a FunctionL2Logs class object to a plain JSON object. - * @returns A plain object with FunctionL2Logs properties. + * Deserializes logs from a buffer. + * @param buf - The buffer containing the serialized logs. + * @param isLengthPrefixed - Whether the buffer is prefixed with 4 bytes for its total length. + * @returns Deserialized instance of `FunctionL2Logs`. */ - public toJSON() { - return { - logs: this.logs.map(log => log.toString('hex')), - }; + public static fromBuffer(buf: Buffer, isLengthPrefixed = true): UnencryptedFunctionL2Logs { + const reader = new BufferReader(buf, 0); + + // If the buffer is length prefixed use the length to read the array. Otherwise, the entire buffer is consumed. + const logsBufLength = isLengthPrefixed ? reader.readNumber() : -1; + const logs = reader.readBufferArray(logsBufLength); + + return new UnencryptedFunctionL2Logs(logs.map(UnencryptedL2Log.fromBuffer)); + } + + /** + * Creates a new L2Logs object with `numLogs` logs. + * @param numLogs - The number of logs to create. + * @param logType - The type of logs to generate. + * @returns A new UnencryptedFunctionL2Logs object. + */ + public static random(numLogs: number): UnencryptedFunctionL2Logs { + const logs: UnencryptedL2Log[] = []; + for (let i = 0; i < numLogs; i++) { + logs.push(UnencryptedL2Log.random()); + } + return new UnencryptedFunctionL2Logs(logs); } /** @@ -107,7 +152,7 @@ export class FunctionL2Logs { * @returns A FunctionL2Logs class object. */ public static fromJSON(obj: any) { - const logs = obj.logs.map((log: string) => Buffer.from(log, 'hex')); - return new FunctionL2Logs(logs); + const logs = obj.logs.map(UnencryptedL2Log.fromJSON); + return new UnencryptedFunctionL2Logs(logs); } } diff --git a/yarn-project/circuit-types/src/logs/index.ts b/yarn-project/circuit-types/src/logs/index.ts index 98a84492c189..c333eb9fdae9 100644 --- a/yarn-project/circuit-types/src/logs/index.ts +++ b/yarn-project/circuit-types/src/logs/index.ts @@ -1,3 +1,4 @@ +export * from './encrypted_l2_log.js'; export * from './get_unencrypted_logs_response.js'; export * from './function_l2_logs.js'; export * from './l2_block_l2_logs.js'; 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 d3a231c347f1..843de7951968 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 @@ -1,28 +1,33 @@ -import { L2BlockL2Logs } from './l2_block_l2_logs.js'; +import { EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs } from './l2_block_l2_logs.js'; -describe('L2BlockL2Logs', () => { - it('can encode L2Logs to buffer and back', () => { - const l2Logs = L2BlockL2Logs.random(3, 6, 2); +function shouldBehaveLikeL2BlockL2Logs(L2BlockL2Logs: typeof EncryptedL2BlockL2Logs | typeof UnencryptedL2BlockL2Logs) { + describe(L2BlockL2Logs.name, () => { + it('can encode L2Logs to buffer and back', () => { + const l2Logs = L2BlockL2Logs.random(3, 6, 2); - const buffer = l2Logs.toBuffer(); - const recovered = L2BlockL2Logs.fromBuffer(buffer); + const buffer = l2Logs.toBuffer(); + const recovered = L2BlockL2Logs.fromBuffer(buffer); - expect(recovered).toEqual(l2Logs); - }); + expect(recovered).toEqual(l2Logs); + }); - it('getSerializedLength returns the correct length', () => { - const l2Logs = L2BlockL2Logs.random(3, 6, 2); + it('getSerializedLength returns the correct length', () => { + const l2Logs = L2BlockL2Logs.random(3, 6, 2); - const buffer = l2Logs.toBuffer(); - const recovered = L2BlockL2Logs.fromBuffer(buffer); + const buffer = l2Logs.toBuffer(); + const recovered = L2BlockL2Logs.fromBuffer(buffer); - expect(recovered.getSerializedLength()).toEqual(buffer.length); - }); + expect(recovered.getSerializedLength()).toEqual(buffer.length); + }); - it('serializes to and from JSON', () => { - const l2Logs = L2BlockL2Logs.random(3, 6, 2); - const json = l2Logs.toJSON(); - const recovered = L2BlockL2Logs.fromJSON(json); - expect(recovered).toEqual(l2Logs); + it('serializes to and from JSON', () => { + const l2Logs = L2BlockL2Logs.random(3, 6, 2); + const json = l2Logs.toJSON(); + const recovered = L2BlockL2Logs.fromJSON(json); + expect(recovered).toEqual(l2Logs); + }); }); -}); +} + +shouldBehaveLikeL2BlockL2Logs(EncryptedL2BlockL2Logs); +shouldBehaveLikeL2BlockL2Logs(UnencryptedL2BlockL2Logs); 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 7a1580b92116..9aa780fda8b7 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 @@ -2,18 +2,19 @@ import { BufferReader, prefixBufferWithLength } from '@aztec/foundation/serializ import isEqual from 'lodash.isequal'; -import { LogType } from './log_type.js'; -import { TxL2Logs } from './tx_l2_logs.js'; +import { EncryptedL2Log } from './encrypted_l2_log.js'; +import { EncryptedTxL2Logs, TxL2Logs, UnencryptedTxL2Logs } from './tx_l2_logs.js'; +import { UnencryptedL2Log } from './unencrypted_l2_log.js'; /** * Data container of logs emitted in all txs in a given L2 block. */ -export class L2BlockL2Logs { +export abstract class L2BlockL2Logs { constructor( /** * An array containing logs emitted in individual function invocations in this tx. */ - public readonly txLogs: TxL2Logs[], + public readonly txLogs: TxL2Logs[], ) {} /** @@ -41,27 +42,69 @@ export class L2BlockL2Logs { return this.txLogs.reduce((acc, logs) => acc + logs.getTotalLogCount(), 0); } + /** + * Seralizes logs into a string. + * @returns A string representation of the serialized logs. + */ + public toString(): string { + return this.toBuffer().toString('hex'); + } + + /** + * Convert a L2BlockL2Logs class object to a plain JSON object. + * @returns A plain object with L2BlockL2Logs properties. + */ + public toJSON() { + return { + txLogs: this.txLogs.map(log => log.toJSON()), + }; + } + + /** + * Checks if two L2BlockL2Logs objects are equal. + * @param other - Another L2BlockL2Logs object to compare with. + * @returns True if the two objects are equal, false otherwise. + */ + public equals(other: L2BlockL2Logs): boolean { + return isEqual(this, other); + } + + /** + * Returns the total number of log entries across an array of L2BlockL2Logs. + * @param l2BlockL2logs - L2BlockL2Logs to sum over. + * @returns Total sum of log entries. + */ + public static getTotalLogCount( + l2BlockL2logs: L2BlockL2Logs[], + ): number { + return l2BlockL2logs.reduce((sum, log) => sum + log.getTotalLogCount(), 0); + } +} + +export class EncryptedL2BlockL2Logs extends L2BlockL2Logs { + /** + * 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. * @returns A new `L2BlockL2Logs` object. */ - public static fromBuffer(buffer: Buffer | BufferReader): L2BlockL2Logs { + public static fromBuffer(buffer: Buffer | BufferReader): EncryptedL2BlockL2Logs { const reader = BufferReader.asReader(buffer); const logsBufLength = reader.readNumber(); const serializedTxLogs = reader.readBufferArray(logsBufLength); - const txLogs = serializedTxLogs.map(logs => TxL2Logs.fromBuffer(logs, false)); - return new L2BlockL2Logs(txLogs); - } - - /** - * Seralizes logs into a string. - * @returns A string representation of the serialized logs. - */ - public toString(): string { - return this.toBuffer().toString('hex'); + const txLogs = serializedTxLogs.map(logs => EncryptedTxL2Logs.fromBuffer(logs, false)); + return new EncryptedL2BlockL2Logs(txLogs); } /** @@ -69,9 +112,9 @@ export class L2BlockL2Logs { * @param data - The string containing the serialized logs. * @returns A new `L2BlockL2Logs` object. */ - public static fromString(data: string): L2BlockL2Logs { + public static fromString(data: string): EncryptedL2BlockL2Logs { const buffer = Buffer.from(data, 'hex'); - return L2BlockL2Logs.fromBuffer(buffer); + return EncryptedL2BlockL2Logs.fromBuffer(buffer); } /** @@ -83,17 +126,12 @@ export class L2BlockL2Logs { * @param logType - The type of logs to generate. * @returns A new `L2BlockL2Logs` object. */ - public static random( - numTxs: number, - numCalls: number, - numLogsPerCall: number, - logType = LogType.ENCRYPTED, - ): L2BlockL2Logs { - const txLogs: TxL2Logs[] = []; + public static random(numTxs: number, numCalls: number, numLogsPerCall: number): EncryptedL2BlockL2Logs { + const txLogs: EncryptedTxL2Logs[] = []; for (let i = 0; i < numTxs; i++) { - txLogs.push(TxL2Logs.random(numCalls, numLogsPerCall, logType)); + txLogs.push(EncryptedTxL2Logs.random(numCalls, numLogsPerCall)); } - return new L2BlockL2Logs(txLogs); + return new EncryptedL2BlockL2Logs(txLogs); } /** @@ -101,8 +139,8 @@ export class L2BlockL2Logs { * @param blockLogs - Input logs from a set of blocks. * @returns Unrolled logs. */ - public static unrollLogs(blockLogs: (L2BlockL2Logs | undefined)[]): Buffer[] { - const logs: Buffer[] = []; + public static unrollLogs(blockLogs: (EncryptedL2BlockL2Logs | undefined)[]): EncryptedL2Log[] { + const logs: EncryptedL2Log[] = []; for (const blockLog of blockLogs) { if (blockLog) { for (const txLog of blockLog.txLogs) { @@ -112,42 +150,75 @@ export class L2BlockL2Logs { } return logs; } +} +export class UnencryptedL2BlockL2Logs extends L2BlockL2Logs { /** - * Convert a L2BlockL2Logs class object to a plain JSON object. - * @returns A plain object with L2BlockL2Logs properties. + * Convert a plain JSON object to a L2BlockL2Logs class object. + * @param obj - A plain L2BlockL2Logs JSON object. + * @returns A L2BlockL2Logs class object. */ - public toJSON() { - return { - txLogs: this.txLogs.map(log => log.toJSON()), - }; + public static fromJSON(obj: any) { + const txLogs = obj.txLogs.map((log: any) => UnencryptedTxL2Logs.fromJSON(log)); + return new UnencryptedL2BlockL2Logs(txLogs); } /** - * Checks if two L2BlockL2Logs objects are equal. - * @param other - Another L2BlockL2Logs object to compare with. - * @returns True if the two objects are equal, false otherwise. + * Deserializes logs from a buffer. + * @param buffer - The buffer containing the serialized logs. + * @returns A new `L2BlockL2Logs` object. */ - public equals(other: L2BlockL2Logs): boolean { - return isEqual(this, other); + public static fromBuffer(buffer: Buffer | BufferReader): UnencryptedL2BlockL2Logs { + const reader = BufferReader.asReader(buffer); + + const logsBufLength = reader.readNumber(); + const serializedTxLogs = reader.readBufferArray(logsBufLength); + + const txLogs = serializedTxLogs.map(logs => UnencryptedTxL2Logs.fromBuffer(logs, false)); + return new UnencryptedL2BlockL2Logs(txLogs); } /** - * Convert a plain JSON object to a L2BlockL2Logs class object. - * @param obj - A plain L2BlockL2Logs JSON object. - * @returns A L2BlockL2Logs class object. + * Deserializes logs from a string. + * @param data - The string containing the serialized logs. + * @returns A new `L2BlockL2Logs` object. */ - public static fromJSON(obj: any) { - const txLogs = obj.txLogs.map((log: any) => TxL2Logs.fromJSON(log)); - return new L2BlockL2Logs(txLogs); + public static fromString(data: string): UnencryptedL2BlockL2Logs { + const buffer = Buffer.from(data, 'hex'); + return UnencryptedL2BlockL2Logs.fromBuffer(buffer); } /** - * Returns the total number of log entries across an array of L2BlockL2Logs. - * @param l2BlockL2logs - L2BlockL2Logs to sum over. - * @returns Total sum of log entries. + * Creates a new `L2BlockL2Logs` object with `numCalls` function logs and `numLogsPerCall` logs in each function + * call. + * @param numTxs - The number of txs in the block. + * @param numCalls - The number of function calls in the tx. + * @param numLogsPerCall - The number of logs emitted in each function call. + * @param logType - The type of logs to generate. + * @returns A new `L2BlockL2Logs` object. */ - public static getTotalLogCount(l2BlockL2logs: L2BlockL2Logs[]): number { - return l2BlockL2logs.reduce((sum, log) => sum + log.getTotalLogCount(), 0); + public static random(numTxs: number, numCalls: number, numLogsPerCall: number): UnencryptedL2BlockL2Logs { + const txLogs: UnencryptedTxL2Logs[] = []; + for (let i = 0; i < numTxs; i++) { + txLogs.push(UnencryptedTxL2Logs.random(numCalls, numLogsPerCall)); + } + return new UnencryptedL2BlockL2Logs(txLogs); + } + + /** + * Unrolls logs from a set of blocks. + * @param blockLogs - Input logs from a set of blocks. + * @returns Unrolled logs. + */ + public static unrollLogs(blockLogs: (UnencryptedL2BlockL2Logs | undefined)[]): UnencryptedL2Log[] { + const logs: UnencryptedL2Log[] = []; + for (const blockLog of blockLogs) { + if (blockLog) { + for (const txLog of blockLog.txLogs) { + logs.push(...txLog.unrollLogs()); + } + } + } + return logs; } } diff --git a/yarn-project/circuit-types/src/logs/l2_logs_source.ts b/yarn-project/circuit-types/src/logs/l2_logs_source.ts index a3566a803fcc..d6d9ac4d1d96 100644 --- a/yarn-project/circuit-types/src/logs/l2_logs_source.ts +++ b/yarn-project/circuit-types/src/logs/l2_logs_source.ts @@ -1,7 +1,7 @@ import { GetUnencryptedLogsResponse } from './get_unencrypted_logs_response.js'; import { L2BlockL2Logs } from './l2_block_l2_logs.js'; import { LogFilter } from './log_filter.js'; -import { LogType } from './log_type.js'; +import { FromLogType, LogType } from './log_type.js'; /** * Interface of classes allowing for the retrieval of logs. @@ -14,7 +14,11 @@ export interface L2LogsSource { * @param logType - Specifies whether to return encrypted or unencrypted logs. * @returns The requested logs. */ - getLogs(from: number, limit: number, logType: LogType): Promise; + getLogs( + from: number, + limit: number, + logType: TLogType, + ): Promise>[]>; /** * Gets unencrypted logs based on the provided filter. diff --git a/yarn-project/circuit-types/src/logs/log_type.ts b/yarn-project/circuit-types/src/logs/log_type.ts index 7216f3e05e2c..00d2a49240c8 100644 --- a/yarn-project/circuit-types/src/logs/log_type.ts +++ b/yarn-project/circuit-types/src/logs/log_type.ts @@ -1,3 +1,6 @@ +import { EncryptedL2Log } from './encrypted_l2_log.js'; +import { UnencryptedL2Log } from './unencrypted_l2_log.js'; + /** * Defines possible log types. */ @@ -5,3 +8,7 @@ export enum LogType { ENCRYPTED, UNENCRYPTED, } + +export type FromLogType = TLogType extends LogType.ENCRYPTED + ? EncryptedL2Log + : UnencryptedL2Log; 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 2bc20cf3dcbf..6f706a4c72bc 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 @@ -1,21 +1,35 @@ -import { TxL2Logs } from './tx_l2_logs.js'; +import { EncryptedTxL2Logs, UnencryptedTxL2Logs } from './tx_l2_logs.js'; -describe('TxL2Logs', () => { - it('can encode L2Logs to buffer and back', () => { - const l2Logs = TxL2Logs.random(6, 2); +function shouldBehaveLikeTxL2Logs(TxL2Logs: typeof EncryptedTxL2Logs | typeof UnencryptedTxL2Logs) { + describe(TxL2Logs.name, () => { + it('can encode TxL2Logs to buffer and back', () => { + const l2Logs = TxL2Logs.random(6, 2); - const buffer = l2Logs.toBuffer(); - const recovered = TxL2Logs.fromBuffer(buffer); + const buffer = l2Logs.toBuffer(); + const recovered = TxL2Logs.fromBuffer(buffer); - expect(recovered).toEqual(l2Logs); - }); + expect(recovered).toEqual(l2Logs); + }); + + it('can encode TxL2Logs to JSON and back', () => { + const l2Logs = TxL2Logs.random(6, 2); + + const buffer = l2Logs.toJSON(); + const recovered = TxL2Logs.fromJSON(buffer); - it('getSerializedLength returns the correct length', () => { - const l2Logs = TxL2Logs.random(6, 2); + expect(recovered).toEqual(l2Logs); + }); - const buffer = l2Logs.toBuffer(); - const recovered = TxL2Logs.fromBuffer(buffer); + it('getSerializedLength returns the correct length', () => { + const l2Logs = TxL2Logs.random(6, 2); - expect(recovered.getSerializedLength()).toEqual(buffer.length); + const buffer = l2Logs.toBuffer(); + const recovered = TxL2Logs.fromBuffer(buffer); + + expect(recovered.getSerializedLength()).toEqual(buffer.length); + }); }); -}); +} + +shouldBehaveLikeTxL2Logs(EncryptedTxL2Logs); +shouldBehaveLikeTxL2Logs(UnencryptedTxL2Logs); 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 09fa81dc2afb..774e479cf651 100644 --- a/yarn-project/circuit-types/src/logs/tx_l2_logs.ts +++ b/yarn-project/circuit-types/src/logs/tx_l2_logs.ts @@ -3,18 +3,17 @@ import { BufferReader, prefixBufferWithLength, truncateAndPad } from '@aztec/fou import isEqual from 'lodash.isequal'; -import { FunctionL2Logs } from './function_l2_logs.js'; -import { LogType } from './log_type.js'; +import { EncryptedL2Log } from './encrypted_l2_log.js'; +import { EncryptedFunctionL2Logs, FunctionL2Logs, UnencryptedFunctionL2Logs } from './function_l2_logs.js'; +import { UnencryptedL2Log } from './unencrypted_l2_log.js'; /** * Data container of logs emitted in 1 tx. */ -export class TxL2Logs { +export abstract class TxL2Logs { constructor( - /** - * An array containing logs emitted in individual function invocations in this tx. - */ - public readonly functionLogs: FunctionL2Logs[], + /** * An array containing logs emitted in individual function invocations in this tx. */ + public readonly functionLogs: FunctionL2Logs[], ) {} /** @@ -45,42 +44,10 @@ export class TxL2Logs { * @param functionLogs - The function logs to add * @remarks Used by sequencer to append unencrypted logs emitted in public function calls. */ - public addFunctionLogs(functionLogs: FunctionL2Logs[]) { + public addFunctionLogs(functionLogs: FunctionL2Logs[]) { this.functionLogs.push(...functionLogs); } - /** - * Deserializes logs from a buffer. - * @param buf - The buffer containing the serialized logs. - * @param isLengthPrefixed - Whether the buffer is prefixed with 4 bytes for its total length. - * @returns A new L2Logs object. - */ - public static fromBuffer(buf: Buffer | BufferReader, isLengthPrefixed = true): TxL2Logs { - const reader = BufferReader.asReader(buf); - - // If the buffer is length prefixed use the length to read the array. Otherwise, the entire buffer is consumed. - const logsBufLength = isLengthPrefixed ? reader.readNumber() : -1; - const serializedFunctionLogs = reader.readBufferArray(logsBufLength); - - const functionLogs = serializedFunctionLogs.map(logs => FunctionL2Logs.fromBuffer(logs, false)); - return new TxL2Logs(functionLogs); - } - - /** - * Creates a new `TxL2Logs` object with `numCalls` function logs and `numLogsPerCall` logs in each invocation. - * @param numCalls - The number of function calls in the tx. - * @param numLogsPerCall - The number of logs emitted in each function call. - * @param logType - The type of logs to generate. - * @returns A new `TxL2Logs` object. - */ - public static random(numCalls: number, numLogsPerCall: number, logType = LogType.ENCRYPTED): TxL2Logs { - const functionLogs: FunctionL2Logs[] = []; - for (let i = 0; i < numCalls; i++) { - functionLogs.push(FunctionL2Logs.random(numLogsPerCall, logType)); - } - return new TxL2Logs(functionLogs); - } - /** * Convert a TxL2Logs class object to a plain JSON object. * @returns A plain object with TxL2Logs properties. @@ -95,26 +62,16 @@ export class TxL2Logs { * Unrolls logs from this tx. * @returns Unrolled logs. */ - public unrollLogs(): Buffer[] { + public unrollLogs(): TLog[] { return this.functionLogs.flatMap(functionLog => functionLog.logs); } - /** - * 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) => FunctionL2Logs.fromJSON(log)); - return new TxL2Logs(functionLogs); - } - /** * Checks if two TxL2Logs objects are equal. * @param other - Another TxL2Logs object to compare with. * @returns True if the two objects are equal, false otherwise. */ - public equals(other: TxL2Logs): boolean { + public equals(other: TxL2Logs): boolean { return isEqual(this, other); } @@ -139,9 +96,102 @@ export class TxL2Logs { return kernelPublicInputsLogsHash; } +} +export class UnencryptedTxL2Logs extends TxL2Logs { /** Creates an empty instance. */ public static empty() { - return new TxL2Logs([]); + return new UnencryptedTxL2Logs([]); + } + + /** + * Deserializes logs from a buffer. + * @param buf - The buffer containing the serialized logs. + * @param isLengthPrefixed - Whether the buffer is prefixed with 4 bytes for its total length. + * @returns A new L2Logs object. + */ + public static fromBuffer(buf: Buffer | BufferReader, isLengthPrefixed = true): UnencryptedTxL2Logs { + const reader = BufferReader.asReader(buf); + + // If the buffer is length prefixed use the length to read the array. Otherwise, the entire buffer is consumed. + const logsBufLength = isLengthPrefixed ? reader.readNumber() : -1; + const serializedFunctionLogs = reader.readBufferArray(logsBufLength); + + const functionLogs = serializedFunctionLogs.map(logs => UnencryptedFunctionL2Logs.fromBuffer(logs, false)); + return new UnencryptedTxL2Logs(functionLogs); + } + + /** + * Creates a new `TxL2Logs` object with `numCalls` function logs and `numLogsPerCall` logs in each invocation. + * @param numCalls - The number of function calls in the tx. + * @param numLogsPerCall - The number of logs emitted in each function call. + * @param logType - The type of logs to generate. + * @returns A new `TxL2Logs` object. + */ + public static random(numCalls: number, numLogsPerCall: number): UnencryptedTxL2Logs { + const functionLogs: UnencryptedFunctionL2Logs[] = []; + for (let i = 0; i < numCalls; i++) { + functionLogs.push(UnencryptedFunctionL2Logs.random(numLogsPerCall)); + } + 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); + } +} + +export class EncryptedTxL2Logs extends TxL2Logs { + /** Creates an empty instance. */ + public static empty() { + return new EncryptedTxL2Logs([]); + } + + /** + * Deserializes logs from a buffer. + * @param buf - The buffer containing the serialized logs. + * @param isLengthPrefixed - Whether the buffer is prefixed with 4 bytes for its total length. + * @returns A new L2Logs object. + */ + public static fromBuffer(buf: Buffer | BufferReader, isLengthPrefixed = true): EncryptedTxL2Logs { + const reader = BufferReader.asReader(buf); + + // If the buffer is length prefixed use the length to read the array. Otherwise, the entire buffer is consumed. + const logsBufLength = isLengthPrefixed ? reader.readNumber() : -1; + const serializedFunctionLogs = reader.readBufferArray(logsBufLength); + + const functionLogs = serializedFunctionLogs.map(logs => EncryptedFunctionL2Logs.fromBuffer(logs, false)); + return new EncryptedTxL2Logs(functionLogs); + } + + /** + * Creates a new `TxL2Logs` object with `numCalls` function logs and `numLogsPerCall` logs in each invocation. + * @param numCalls - The number of function calls in the tx. + * @param numLogsPerCall - The number of logs emitted in each function call. + * @param logType - The type of logs to generate. + * @returns A new `TxL2Logs` object. + */ + public static random(numCalls: number, numLogsPerCall: number): EncryptedTxL2Logs { + const functionLogs: EncryptedFunctionL2Logs[] = []; + for (let i = 0; i < numCalls; i++) { + functionLogs.push(EncryptedFunctionL2Logs.random(numLogsPerCall)); + } + 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); } } 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 d63553a60c80..a8bc9ee0fecc 100644 --- a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts +++ b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts @@ -24,7 +24,7 @@ export class UnencryptedL2Log { ) {} get length(): number { - return EventSelector.SIZE + this.data.length; + return EventSelector.SIZE + this.data.length + AztecAddress.SIZE_IN_BYTES + 4; } /** @@ -51,6 +51,24 @@ export class UnencryptedL2Log { return `UnencryptedL2Log(contractAddress: ${this.contractAddress.toString()}, selector: ${this.selector.toString()}, data: ${payload})`; } + /** Returns a JSON-friendly representation of the log. */ + public toJSON(): object { + return { + contractAddress: this.contractAddress.toString(), + selector: this.selector.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), + EventSelector.fromString(obj.selector), + 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/mocks.ts b/yarn-project/circuit-types/src/mocks.ts index 30ad57764ac9..18700c91c163 100644 --- a/yarn-project/circuit-types/src/mocks.ts +++ b/yarn-project/circuit-types/src/mocks.ts @@ -15,7 +15,8 @@ import { Fr } from '@aztec/foundation/fields'; import { Tuple } from '@aztec/foundation/serialize'; import { ContractInstanceWithAddress, SerializableContractInstance } from '@aztec/types/contracts'; -import { FunctionL2Logs, Note, TxL2Logs } from './logs/index.js'; +import { EncryptedL2Log } from './logs/encrypted_l2_log.js'; +import { EncryptedFunctionL2Logs, EncryptedTxL2Logs, Note, UnencryptedTxL2Logs } from './logs/index.js'; import { makePrivateKernelTailCircuitPublicInputs, makePublicCallRequest } from './mocks_to_purge.js'; import { ExtendedNote } from './notes/index.js'; import { Tx, TxHash } from './tx/index.js'; @@ -23,9 +24,9 @@ import { Tx, TxHash } from './tx/index.js'; /** * Testing utility to create empty logs composed from a single empty log. */ -export function makeEmptyLogs(): TxL2Logs { - const functionLogs = [new FunctionL2Logs([Buffer.alloc(0)])]; - return new TxL2Logs(functionLogs); +export function makeEmptyLogs(): EncryptedTxL2Logs { + const functionLogs = [new EncryptedFunctionL2Logs([EncryptedL2Log.empty()])]; + return new EncryptedTxL2Logs(functionLogs); } export const randomTxHash = (): TxHash => new TxHash(randomBytes(32)); @@ -34,8 +35,8 @@ export const mockTx = (seed = 1, logs = true) => { const tx = new Tx( makePrivateKernelTailCircuitPublicInputs(seed), new Proof(Buffer.alloc(0)), - logs ? TxL2Logs.random(8, 3) : TxL2Logs.empty(), // 8 priv function invocations creating 3 encrypted logs each - logs ? TxL2Logs.random(11, 2) : TxL2Logs.empty(), // 8 priv + 3 pub function invocations creating 2 unencrypted logs each + logs ? EncryptedTxL2Logs.random(8, 3) : EncryptedTxL2Logs.empty(), // 8 priv function invocations creating 3 encrypted logs each + logs ? UnencryptedTxL2Logs.random(11, 2) : UnencryptedTxL2Logs.empty(), // 8 priv + 3 pub function invocations creating 2 unencrypted logs each times(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, makePublicCallRequest), ); diff --git a/yarn-project/circuit-types/src/tx/processed_tx.ts b/yarn-project/circuit-types/src/tx/processed_tx.ts index 9e321fb0cee6..410052f705a1 100644 --- a/yarn-project/circuit-types/src/tx/processed_tx.ts +++ b/yarn-project/circuit-types/src/tx/processed_tx.ts @@ -1,4 +1,12 @@ -import { PublicDataWrite, SimulationError, Tx, TxEffect, TxHash, TxL2Logs } from '@aztec/circuit-types'; +import { + EncryptedTxL2Logs, + PublicDataWrite, + SimulationError, + Tx, + TxEffect, + TxHash, + UnencryptedTxL2Logs, +} from '@aztec/circuit-types'; import { Fr, Header, @@ -143,8 +151,8 @@ export function makeProcessedTx( hash: tx.getTxHash(), data: publicKernelPublicInput, proof: previousProof, - encryptedLogs: revertReason ? new TxL2Logs([]) : tx.encryptedLogs, - unencryptedLogs: revertReason ? new TxL2Logs([]) : tx.unencryptedLogs, + encryptedLogs: revertReason ? EncryptedTxL2Logs.empty() : tx.encryptedLogs, + unencryptedLogs: revertReason ? UnencryptedTxL2Logs.empty() : tx.unencryptedLogs, isEmpty: false, revertReason, }; @@ -164,8 +172,8 @@ export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr): const hash = new TxHash(Fr.ZERO.toBuffer()); return { hash, - encryptedLogs: new TxL2Logs([]), - unencryptedLogs: new TxL2Logs([]), + encryptedLogs: EncryptedTxL2Logs.empty(), + unencryptedLogs: UnencryptedTxL2Logs.empty(), data: emptyKernelOutput, proof: emptyProof, isEmpty: true, @@ -186,13 +194,13 @@ export function toTxEffect(tx: ProcessedTx): TxEffect { PublicDataWrite, typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX >, - tx.encryptedLogs || new TxL2Logs([]), - tx.unencryptedLogs || new TxL2Logs([]), + tx.encryptedLogs || EncryptedTxL2Logs.empty(), + tx.unencryptedLogs || UnencryptedTxL2Logs.empty(), ); } function validateProcessedTxLogs(tx: ProcessedTx): void { - const unencryptedLogs = tx.unencryptedLogs || new TxL2Logs([]); + const unencryptedLogs = tx.unencryptedLogs || UnencryptedTxL2Logs.empty(); const kernelUnencryptedLogsHash = tx.data.combinedData.unencryptedLogsHash; const referenceHash = Fr.fromBuffer(unencryptedLogs.hash()); if (!referenceHash.equals(kernelUnencryptedLogsHash)) { diff --git a/yarn-project/circuit-types/src/tx/tx.ts b/yarn-project/circuit-types/src/tx/tx.ts index 4c9497fcd892..4ce149a3720d 100644 --- a/yarn-project/circuit-types/src/tx/tx.ts +++ b/yarn-project/circuit-types/src/tx/tx.ts @@ -9,10 +9,9 @@ import { import { arrayNonEmptyLength } from '@aztec/foundation/collection'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { UnencryptedL2Log } from '../index.js'; import { GetUnencryptedLogsResponse } from '../logs/get_unencrypted_logs_response.js'; import { L2LogsSource } from '../logs/l2_logs_source.js'; -import { TxL2Logs } from '../logs/tx_l2_logs.js'; +import { EncryptedTxL2Logs, UnencryptedTxL2Logs } from '../logs/tx_l2_logs.js'; import { TxStats } from '../stats/stats.js'; import { TxHash } from './tx_hash.js'; @@ -32,11 +31,11 @@ export class Tx { /** * Encrypted logs generated by the tx. */ - public readonly encryptedLogs: TxL2Logs, + public readonly encryptedLogs: EncryptedTxL2Logs, /** * Unencrypted logs generated by the tx. */ - public readonly unencryptedLogs: TxL2Logs, + public readonly unencryptedLogs: UnencryptedTxL2Logs, /** * Enqueued public functions from the private circuit to be run by the sequencer. * Preimages of the public call stack entries from the private kernel circuit output. @@ -73,8 +72,8 @@ export class Tx { return new Tx( reader.readObject(PrivateKernelTailCircuitPublicInputs), reader.readObject(Proof), - reader.readObject(TxL2Logs), - reader.readObject(TxL2Logs), + reader.readObject(EncryptedTxL2Logs), + reader.readObject(UnencryptedTxL2Logs), reader.readArray(reader.readNumber(), PublicCallRequest), ); } @@ -124,8 +123,8 @@ export class Tx { */ public static fromJSON(obj: any) { const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(Buffer.from(obj.data, 'hex')); - const encryptedLogs = TxL2Logs.fromBuffer(Buffer.from(obj.encryptedLogs, 'hex')); - const unencryptedLogs = TxL2Logs.fromBuffer(Buffer.from(obj.unencryptedLogs, 'hex')); + const encryptedLogs = EncryptedTxL2Logs.fromBuffer(Buffer.from(obj.encryptedLogs, 'hex')); + const unencryptedLogs = UnencryptedTxL2Logs.fromBuffer(Buffer.from(obj.unencryptedLogs, 'hex')); const proof = Buffer.from(obj.proof, 'hex'); const enqueuedPublicFunctions = obj.enqueuedPublicFunctions ? obj.enqueuedPublicFunctions.map((x: string) => PublicCallRequest.fromBuffer(Buffer.from(x, 'hex'))) @@ -179,7 +178,6 @@ export class Tx { : 'none', classRegisteredCount: this.unencryptedLogs .unrollLogs() - .map(log => UnencryptedL2Log.fromBuffer(log)) .filter(log => ContractClassRegisteredEvent.isContractClassRegisteredEvent(log.data)).length, }; } @@ -210,8 +208,8 @@ export class Tx { static clone(tx: Tx): Tx { const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(tx.data.toBuffer()); const proof = Proof.fromBuffer(tx.proof.toBuffer()); - const encryptedLogs = TxL2Logs.fromBuffer(tx.encryptedLogs.toBuffer()); - const unencryptedLogs = TxL2Logs.fromBuffer(tx.unencryptedLogs.toBuffer()); + const encryptedLogs = EncryptedTxL2Logs.fromBuffer(tx.encryptedLogs.toBuffer()); + const unencryptedLogs = UnencryptedTxL2Logs.fromBuffer(tx.unencryptedLogs.toBuffer()); const enqueuedPublicFunctions = tx.enqueuedPublicFunctionCalls.map(x => { return PublicCallRequest.fromBuffer(x.toBuffer()); }); diff --git a/yarn-project/circuit-types/src/tx_effect.ts b/yarn-project/circuit-types/src/tx_effect.ts index c80d0cee28d4..5814843f147c 100644 --- a/yarn-project/circuit-types/src/tx_effect.ts +++ b/yarn-project/circuit-types/src/tx_effect.ts @@ -1,4 +1,4 @@ -import { LogType, PublicDataWrite, TxHash, TxL2Logs } from '@aztec/circuit-types'; +import { EncryptedTxL2Logs, PublicDataWrite, TxHash, UnencryptedTxL2Logs } from '@aztec/circuit-types'; import { Fr, MAX_NEW_L2_TO_L1_MSGS_PER_TX, @@ -45,8 +45,8 @@ export class TxEffect { /** * The logs of the txEffect */ - public encryptedLogs: TxL2Logs, - public unencryptedLogs: TxL2Logs, + public encryptedLogs: EncryptedTxL2Logs, + public unencryptedLogs: UnencryptedTxL2Logs, ) {} toBuffer(): Buffer { @@ -86,8 +86,8 @@ export class TxEffect { padArrayEnd(nonZeroNullifiers, Fr.ZERO, MAX_NEW_NULLIFIERS_PER_TX), padArrayEnd(nonZeroL2ToL1Msgs, Fr.ZERO, MAX_NEW_L2_TO_L1_MSGS_PER_TX), padArrayEnd(nonZeroPublicDataWrites, PublicDataWrite.empty(), MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX), - TxL2Logs.fromBuffer(reader), - TxL2Logs.fromBuffer(reader), + EncryptedTxL2Logs.fromBuffer(reader), + UnencryptedTxL2Logs.fromBuffer(reader), ); } @@ -137,8 +137,8 @@ export class TxEffect { makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.random), makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.random), makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite.random), - TxL2Logs.random(numPrivateCallsPerTx, numEncryptedLogsPerCall, LogType.ENCRYPTED), - TxL2Logs.random(numPublicCallsPerTx, numUnencryptedLogsPerCall, LogType.UNENCRYPTED), + EncryptedTxL2Logs.random(numPrivateCallsPerTx, numEncryptedLogsPerCall), + UnencryptedTxL2Logs.random(numPublicCallsPerTx, numUnencryptedLogsPerCall), ); } @@ -149,8 +149,8 @@ export class TxEffect { makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.zero), makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite.empty), - TxL2Logs.empty(), - TxL2Logs.empty(), + EncryptedTxL2Logs.empty(), + UnencryptedTxL2Logs.empty(), ); } diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 9aaddc20197a..463ddbe28d5f 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -11,9 +11,9 @@ import { ContractMethod, DebugLogger, DeployL1Contracts, + EncryptedL2BlockL2Logs, EthCheatCodes, L1ContractArtifactsForDeployment, - L2BlockL2Logs, LogType, PXE, SentTx, @@ -471,7 +471,7 @@ export const expectsNumOfEncryptedLogsInTheLastBlockToBe = async ( } const l2BlockNum = await aztecNode.getBlockNumber(); const encryptedLogs = await aztecNode.getLogs(l2BlockNum, 1, LogType.ENCRYPTED); - const unrolledLogs = L2BlockL2Logs.unrollLogs(encryptedLogs); + const unrolledLogs = EncryptedL2BlockL2Logs.unrollLogs(encryptedLogs); expect(unrolledLogs.length).toBe(numEncryptedLogs); }; diff --git a/yarn-project/p2p/src/service/tx_messages.ts b/yarn-project/p2p/src/service/tx_messages.ts index 5858f6e36788..744d8f7e02d7 100644 --- a/yarn-project/p2p/src/service/tx_messages.ts +++ b/yarn-project/p2p/src/service/tx_messages.ts @@ -1,4 +1,4 @@ -import { Tx, TxHash, TxL2Logs } from '@aztec/circuit-types'; +import { EncryptedTxL2Logs, Tx, TxHash, UnencryptedTxL2Logs } from '@aztec/circuit-types'; import { PrivateKernelTailCircuitPublicInputs, Proof, PublicCallRequest } from '@aztec/circuits.js'; import { numToUInt32BE } from '@aztec/foundation/serialize'; @@ -188,13 +188,13 @@ export function fromTxMessage(buffer: Buffer): Tx { const publicInputs = toObject(buffer.subarray(4), PrivateKernelTailCircuitPublicInputs); const proof = toObject(publicInputs.remainingData, Proof); - const encryptedLogs = toObject(proof.remainingData, TxL2Logs); + const encryptedLogs = toObject(proof.remainingData, EncryptedTxL2Logs); if (!encryptedLogs.obj) { - encryptedLogs.obj = new TxL2Logs([]); + encryptedLogs.obj = new EncryptedTxL2Logs([]); } - const unencryptedLogs = toObject(encryptedLogs.remainingData, TxL2Logs); + const unencryptedLogs = toObject(encryptedLogs.remainingData, UnencryptedTxL2Logs); if (!unencryptedLogs.obj) { - unencryptedLogs.obj = new TxL2Logs([]); + unencryptedLogs.obj = new UnencryptedTxL2Logs([]); } const publicCalls = toObjectArray(unencryptedLogs.remainingData, PublicCallRequest); diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index 5a8f599c0bf7..27ca152a1812 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -1,4 +1,4 @@ -import { FunctionL2Logs, Note } from '@aztec/circuit-types'; +import { EncryptedFunctionL2Logs, Note, UnencryptedFunctionL2Logs } from '@aztec/circuit-types'; import { FunctionData, FunctionSelector, @@ -76,8 +76,8 @@ describe('Kernel Prover', () => { acir: Buffer.alloc(0), partialWitness: new Map(), enqueuedPublicFunctionCalls: [], - encryptedLogs: new FunctionL2Logs([]), - unencryptedLogs: new FunctionL2Logs([]), + encryptedLogs: EncryptedFunctionL2Logs.empty(), + unencryptedLogs: UnencryptedFunctionL2Logs.empty(), }; }; diff --git a/yarn-project/pxe/src/note_processor/note_processor.test.ts b/yarn-project/pxe/src/note_processor/note_processor.test.ts index ed30e119880f..3f026ce3a9d0 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -1,14 +1,15 @@ import { AztecNode, - FunctionL2Logs, + EncryptedFunctionL2Logs, + EncryptedL2BlockL2Logs, + EncryptedL2Log, + EncryptedTxL2Logs, KeyPair, KeyStore, L1NotePayload, L2Block, L2BlockContext, - L2BlockL2Logs, TaggedNote, - TxL2Logs, } from '@aztec/circuit-types'; import { Fr, INITIAL_L2_BLOCK_NUM, MAX_NEW_NOTE_HASHES_PER_TX } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; @@ -47,7 +48,7 @@ describe('Note Processor', () => { const createEncryptedLogsAndOwnedL1NotePayloads = (ownedData: number[][], ownedNotes: TaggedNote[]) => { const newNotes: TaggedNote[] = []; const ownedL1NotePayloads: L1NotePayload[] = []; - const txLogs: TxL2Logs[] = []; + const txLogs: EncryptedTxL2Logs[] = []; let usedOwnedNote = 0; for (let i = 0; i < TXS_PER_BLOCK; ++i) { const ownedDataIndices = ownedData[i] || []; @@ -55,7 +56,7 @@ describe('Note Processor', () => { throw new Error(`Data index should be less than ${MAX_NEW_NOTE_HASHES_PER_TX}.`); } - const logs: FunctionL2Logs[] = []; + const logs: EncryptedFunctionL2Logs[] = []; for (let noteIndex = 0; noteIndex < MAX_NEW_NOTE_HASHES_PER_TX; ++noteIndex) { const isOwner = ownedDataIndices.includes(noteIndex); const publicKey = isOwner ? owner.getPublicKey() : Point.random(); @@ -68,12 +69,12 @@ describe('Note Processor', () => { // const encryptedNote = const log = note.toEncryptedBuffer(publicKey, grumpkin); // 1 tx containing 1 function invocation containing 1 log - logs.push(new FunctionL2Logs([log])); + logs.push(new EncryptedFunctionL2Logs([new EncryptedL2Log(log)])); } - txLogs.push(new TxL2Logs(logs)); + txLogs.push(new EncryptedTxL2Logs(logs)); } - const encryptedLogs = new L2BlockL2Logs(txLogs); + const encryptedLogs = new EncryptedL2BlockL2Logs(txLogs); return { newNotes, ownedL1NotePayloads, encryptedLogs }; }; @@ -88,7 +89,7 @@ describe('Note Processor', () => { } const blockContexts: L2BlockContext[] = []; - const encryptedLogsArr: L2BlockL2Logs[] = []; + const encryptedLogsArr: EncryptedL2BlockL2Logs[] = []; const ownedL1NotePayloads: L1NotePayload[] = []; const numberOfBlocks = prependedBlocks + appendedBlocks + 1; for (let i = 0; i < numberOfBlocks; ++i) { diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 82a02a36151b..7edfe6e5b09c 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -1,4 +1,11 @@ -import { AztecNode, KeyStore, L1NotePayload, L2BlockContext, L2BlockL2Logs, TaggedNote } from '@aztec/circuit-types'; +import { + AztecNode, + EncryptedL2BlockL2Logs, + KeyStore, + L1NotePayload, + L2BlockContext, + TaggedNote, +} from '@aztec/circuit-types'; import { NoteProcessorStats } from '@aztec/circuit-types/stats'; import { INITIAL_L2_BLOCK_NUM, MAX_NEW_NOTE_HASHES_PER_TX, PublicKey } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; @@ -84,7 +91,10 @@ export class NoteProcessor { * @param encryptedL2BlockLogs - An array of encrypted logs associated with the L2 block contexts. * @returns A promise that resolves once the processing is completed. */ - public async process(l2BlockContexts: L2BlockContext[], encryptedL2BlockLogs: L2BlockL2Logs[]): Promise { + public async process( + l2BlockContexts: L2BlockContext[], + encryptedL2BlockLogs: EncryptedL2BlockL2Logs[], + ): Promise { if (l2BlockContexts.length !== encryptedL2BlockLogs.length) { throw new Error( `Number of blocks and EncryptedLogs is not equal. Received ${l2BlockContexts.length} blocks, ${encryptedL2BlockLogs.length} encrypted logs.`, @@ -125,7 +135,7 @@ export class NoteProcessor { for (const functionLogs of txFunctionLogs) { for (const log of functionLogs.logs) { this.stats.seen++; - const taggedNote = TaggedNote.fromEncryptedBuffer(log, privateKey, curve); + const taggedNote = TaggedNote.fromEncryptedBuffer(log.data, privateKey, curve); if (taggedNote?.notePayload) { const { notePayload: payload } = taggedNote; // We have successfully decrypted the data. diff --git a/yarn-project/pxe/src/pxe_http/pxe_http_server.ts b/yarn-project/pxe/src/pxe_http/pxe_http_server.ts index 7fe3bb8a591d..ef91f7836be8 100644 --- a/yarn-project/pxe/src/pxe_http/pxe_http_server.ts +++ b/yarn-project/pxe/src/pxe_http/pxe_http_server.ts @@ -1,10 +1,10 @@ import { AuthWitness, CompleteAddress, + EncryptedL2BlockL2Logs, ExtendedNote, ExtendedUnencryptedL2Log, L2Block, - L2BlockL2Logs, LogId, Note, NullifierMembershipWitness, @@ -14,6 +14,7 @@ import { TxExecutionRequest, TxHash, TxReceipt, + UnencryptedL2BlockL2Logs, } from '@aztec/circuit-types'; import { FunctionSelector } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; @@ -48,7 +49,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer { TxEffect, LogId, }, - { Tx, TxReceipt, L2BlockL2Logs, NullifierMembershipWitness }, + { Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness }, ['start', 'stop'], ); } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index de2c170513a3..21e03cccf7d8 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -1,6 +1,7 @@ import { AuthWitness, AztecNode, + EncryptedTxL2Logs, ExtendedNote, FunctionCall, GetUnencryptedLogsResponse, @@ -15,8 +16,8 @@ import { TxEffect, TxExecutionRequest, TxHash, - TxL2Logs, TxReceipt, + UnencryptedTxL2Logs, isNoirCallStackUnresolved, } from '@aztec/circuit-types'; import { TxPXEProcessingStats } from '@aztec/circuit-types/stats'; @@ -621,8 +622,8 @@ export class PXEService implements PXE { `Needs setup: ${publicInputs.needsSetup}, needs app logic: ${publicInputs.needsAppLogic}, needs teardown: ${publicInputs.needsTeardown}`, ); - const encryptedLogs = new TxL2Logs(collectEncryptedLogs(executionResult)); - const unencryptedLogs = new TxL2Logs(collectUnencryptedLogs(executionResult)); + const encryptedLogs = new EncryptedTxL2Logs(collectEncryptedLogs(executionResult)); + const unencryptedLogs = new UnencryptedTxL2Logs(collectUnencryptedLogs(executionResult)); const enqueuedPublicFunctions = collectEnqueuedPublicFunctionCalls(executionResult); // HACK(#1639): Manually patches the ordering of the public call stack diff --git a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts index 5376ae460c25..6508ec266184 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -1,4 +1,4 @@ -import { FunctionL2Logs, MerkleTreeId, SimulationError, Tx } from '@aztec/circuit-types'; +import { MerkleTreeId, SimulationError, Tx, UnencryptedFunctionL2Logs } from '@aztec/circuit-types'; import { AztecAddress, CallRequest, @@ -180,7 +180,7 @@ export abstract class AbstractPhaseManager { tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs, previousPublicKernelProof: Proof, - ): Promise<[PublicKernelCircuitPublicInputs, Proof, FunctionL2Logs[], SimulationError | undefined]> { + ): Promise<[PublicKernelCircuitPublicInputs, Proof, UnencryptedFunctionL2Logs[], SimulationError | undefined]> { let kernelOutput = previousPublicKernelOutput; let kernelProof = previousPublicKernelProof; @@ -190,7 +190,7 @@ export abstract class AbstractPhaseManager { return [kernelOutput, kernelProof, [], undefined]; } - const newUnencryptedFunctionLogs: FunctionL2Logs[] = []; + const newUnencryptedFunctionLogs: UnencryptedFunctionL2Logs[] = []; // TODO(#1684): Should multiple separately enqueued public calls be treated as // separate public callstacks to be proven by separate public kernel sequences 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 38be5b440ca4..7044472cb53b 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts @@ -1,12 +1,13 @@ import { + EncryptedTxL2Logs, FunctionCall, - FunctionL2Logs, ProcessedTx, PublicDataWrite, SiblingPath, SimulationError, Tx, - TxL2Logs, + UnencryptedFunctionL2Logs, + UnencryptedTxL2Logs, mockTx, toTxEffect, } from '@aztec/circuit-types'; @@ -206,7 +207,13 @@ describe('public_processor', () => { ); kernelOutput.end.unencryptedLogsHash = Fr.ZERO; - const tx = new Tx(kernelOutput, proof, TxL2Logs.empty(), TxL2Logs.empty(), publicCallRequests); + const tx = new Tx( + kernelOutput, + proof, + EncryptedTxL2Logs.empty(), + UnencryptedTxL2Logs.empty(), + publicCallRequests, + ); tx.data.needsSetup = false; tx.data.needsTeardown = false; @@ -252,7 +259,7 @@ describe('public_processor', () => { kernelOutput.needsSetup = false; kernelOutput.needsTeardown = false; - const tx = new Tx(kernelOutput, proof, TxL2Logs.empty(), TxL2Logs.empty(), [callRequest]); + const tx = new Tx(kernelOutput, proof, EncryptedTxL2Logs.empty(), UnencryptedTxL2Logs.empty(), [callRequest]); const publicExecutionResult = PublicExecutionResultBuilder.fromPublicCallRequest({ request: callRequest, @@ -302,8 +309,8 @@ describe('public_processor', () => { const tx = new Tx( kernelOutput, proof, - TxL2Logs.empty(), - TxL2Logs.empty(), + EncryptedTxL2Logs.empty(), + UnencryptedTxL2Logs.empty(), // reverse because `enqueuedPublicFunctions` expects the last element to be the front of the queue callRequests.slice().reverse(), ); @@ -418,8 +425,8 @@ describe('public_processor', () => { const tx = new Tx( kernelOutput, proof, - TxL2Logs.empty(), - TxL2Logs.empty(), + EncryptedTxL2Logs.empty(), + UnencryptedTxL2Logs.empty(), // reverse because `enqueuedPublicFunctions` expects the last element to be the front of the queue callRequests.slice().reverse(), ); @@ -522,8 +529,8 @@ describe('public_processor', () => { const tx = new Tx( kernelOutput, proof, - TxL2Logs.empty(), - TxL2Logs.empty(), + EncryptedTxL2Logs.empty(), + UnencryptedTxL2Logs.empty(), // reverse because `enqueuedPublicFunctions` expects the last element to be the front of the queue callRequests.slice().reverse(), ); @@ -625,8 +632,8 @@ describe('public_processor', () => { const tx = new Tx( kernelOutput, proof, - TxL2Logs.empty(), - TxL2Logs.empty(), + EncryptedTxL2Logs.empty(), + UnencryptedTxL2Logs.empty(), // reverse because `enqueuedPublicFunctions` expects the last element to be the front of the queue callRequests.slice().reverse(), ); @@ -812,7 +819,7 @@ class PublicExecutionResultBuilder { newNullifiers: [], newL2ToL1Messages: [], contractStorageReads: [], - unencryptedLogs: new FunctionL2Logs([]), + unencryptedLogs: UnencryptedFunctionL2Logs.empty(), startSideEffectCounter: Fr.ZERO, endSideEffectCounter: Fr.ZERO, reverted: this._reverted, diff --git a/yarn-project/sequencer-client/src/simulator/public_executor.ts b/yarn-project/sequencer-client/src/simulator/public_executor.ts index f6a42947704c..6ff7728fb1d8 100644 --- a/yarn-project/sequencer-client/src/simulator/public_executor.ts +++ b/yarn-project/sequencer-client/src/simulator/public_executor.ts @@ -1,4 +1,4 @@ -import { MerkleTreeId, NullifierMembershipWitness, Tx, UnencryptedL2Log } from '@aztec/circuit-types'; +import { MerkleTreeId, NullifierMembershipWitness, Tx } from '@aztec/circuit-types'; import { AztecAddress, ContractClassRegisteredEvent, @@ -36,7 +36,7 @@ export class ContractsDataSourcePublicDB implements PublicContractsDB { */ public addNewContracts(tx: Tx): Promise { // Extract contract class and instance data from logs and add to cache for this block - const logs = tx.unencryptedLogs.unrollLogs().map(UnencryptedL2Log.fromBuffer); + const logs = tx.unencryptedLogs.unrollLogs(); ContractClassRegisteredEvent.fromLogs(logs, getCanonicalClassRegistererAddress()).forEach(e => { this.log(`Adding class ${e.contractClassId.toString()} to public execution contract cache`); this.classCache.set(e.contractClassId.toString(), e.toContractClassPublic()); @@ -59,7 +59,7 @@ export class ContractsDataSourcePublicDB implements PublicContractsDB { // TODO(@spalladino): Can this inadvertently delete a valid contract added by another tx? // Let's say we have two txs adding the same contract on the same block. If the 2nd one reverts, // wouldn't that accidentally remove the contract added on the first one? - const logs = tx.unencryptedLogs.unrollLogs().map(UnencryptedL2Log.fromBuffer); + const logs = tx.unencryptedLogs.unrollLogs(); ContractClassRegisteredEvent.fromLogs(logs, getCanonicalClassRegistererAddress()).forEach(e => this.classCache.delete(e.contractClassId.toString()), ); diff --git a/yarn-project/simulator/src/avm/temporary_executor_migration.ts b/yarn-project/simulator/src/avm/temporary_executor_migration.ts index 6591fe216535..4c2e0bb203d2 100644 --- a/yarn-project/simulator/src/avm/temporary_executor_migration.ts +++ b/yarn-project/simulator/src/avm/temporary_executor_migration.ts @@ -1,5 +1,5 @@ // All code in this file needs to die once the public executor is phased out. -import { FunctionL2Logs } from '@aztec/circuit-types'; +import { UnencryptedFunctionL2Logs } from '@aztec/circuit-types'; import { ContractStorageRead, ContractStorageUpdateRequest, @@ -96,7 +96,7 @@ export function temporaryConvertAvmResults( const nullifierReadRequests: ReadRequest[] = []; const nullifierNonExistentReadRequests: ReadRequest[] = []; const newNullifiers: SideEffectLinkedToNoteHash[] = []; - const unencryptedLogs = FunctionL2Logs.empty(); + const unencryptedLogs = UnencryptedFunctionL2Logs.empty(); const newL2ToL1Messages = newWorldState.newL1Messages.map(() => L2ToL1Message.empty()); // TODO keep track of side effect counters const startSideEffectCounter = Fr.ZERO; diff --git a/yarn-project/simulator/src/client/client_execution_context.ts b/yarn-project/simulator/src/client/client_execution_context.ts index 2c1b9571a877..8586f777ae13 100644 --- a/yarn-project/simulator/src/client/client_execution_context.ts +++ b/yarn-project/simulator/src/client/client_execution_context.ts @@ -1,11 +1,13 @@ import { AuthWitness, AztecNode, - FunctionL2Logs, + EncryptedFunctionL2Logs, + EncryptedL2Log, L1NotePayload, Note, NoteStatus, TaggedNote, + UnencryptedFunctionL2Logs, UnencryptedL2Log, } from '@aztec/circuit-types'; import { @@ -56,7 +58,7 @@ export class ClientExecutionContext extends ViewDataOracle { * They should act as references for the read requests output by an app circuit via public inputs. */ private gotNotes: Map = new Map(); - private encryptedLogs: Buffer[] = []; + private encryptedLogs: EncryptedL2Log[] = []; private unencryptedLogs: UnencryptedL2Log[] = []; private nestedExecutions: ExecutionResult[] = []; private enqueuedPublicFunctionCalls: PublicCallRequest[] = []; @@ -144,14 +146,14 @@ export class ClientExecutionContext extends ViewDataOracle { * Return the encrypted logs emitted during this execution. */ public getEncryptedLogs() { - return new FunctionL2Logs(this.encryptedLogs); + return new EncryptedFunctionL2Logs(this.encryptedLogs); } /** * Return the encrypted logs emitted during this execution. */ public getUnencryptedLogs() { - return new FunctionL2Logs(this.unencryptedLogs.map(log => log.toBuffer())); + return new UnencryptedFunctionL2Logs(this.unencryptedLogs); } /** @@ -304,7 +306,7 @@ export class ClientExecutionContext extends ViewDataOracle { const l1NotePayload = new L1NotePayload(note, contractAddress, storageSlot, noteTypeId); const taggedNote = new TaggedNote(l1NotePayload); const encryptedNote = taggedNote.toEncryptedBuffer(publicKey, this.curve); - this.encryptedLogs.push(encryptedNote); + this.encryptedLogs.push(new EncryptedL2Log(encryptedNote)); } /** diff --git a/yarn-project/simulator/src/client/execution_result.test.ts b/yarn-project/simulator/src/client/execution_result.test.ts index b2e626ab3824..f09c5bf07443 100644 --- a/yarn-project/simulator/src/client/execution_result.test.ts +++ b/yarn-project/simulator/src/client/execution_result.test.ts @@ -1,5 +1,11 @@ -import { FunctionL2Logs } from '@aztec/circuit-types'; -import { PrivateCallStackItem } from '@aztec/circuits.js'; +import { + EncryptedFunctionL2Logs, + EncryptedL2Log, + UnencryptedFunctionL2Logs, + UnencryptedL2Log, +} from '@aztec/circuit-types'; +import { AztecAddress, PrivateCallStackItem } from '@aztec/circuits.js'; +import { EventSelector } from '@aztec/foundation/abi'; import { ExecutionResult, collectEncryptedLogs, collectUnencryptedLogs } from './execution_result.js'; @@ -14,18 +20,22 @@ function emptyExecutionResult(): ExecutionResult { returnValues: [], nestedExecutions: [], enqueuedPublicFunctionCalls: [], - encryptedLogs: FunctionL2Logs.empty(), - unencryptedLogs: FunctionL2Logs.empty(), + encryptedLogs: EncryptedFunctionL2Logs.empty(), + unencryptedLogs: UnencryptedFunctionL2Logs.empty(), }; } describe('Execution Result test suite - collect encrypted logs', () => { - function emptyExecutionResultWithEncryptedLogs(encryptedLogs = FunctionL2Logs.empty()): ExecutionResult { + function emptyExecutionResultWithEncryptedLogs(encryptedLogs = EncryptedFunctionL2Logs.empty()): ExecutionResult { const executionResult = emptyExecutionResult(); executionResult.encryptedLogs = encryptedLogs; return executionResult; } + function makeEncryptedFunctionLogs(contents: string[]) { + return new EncryptedFunctionL2Logs(contents.map(s => new EncryptedL2Log(Buffer.from(s)))); + } + it('collect encrypted logs with nested fn calls', () => { /* Create the following executionResult object: @@ -38,14 +48,14 @@ describe('Execution Result test suite - collect encrypted logs', () => { Circuits and ACVM process in a DFS + stack like format: [fnA, fnE, fnG, fnF, fnC, fnD, fnB] */ const executionResult: ExecutionResult = emptyExecutionResultWithEncryptedLogs( - new FunctionL2Logs([Buffer.from('Log 1')]), + makeEncryptedFunctionLogs(['Log 1']), ); - const fnB = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 2')])); - const fnC = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 3')])); - const fnD = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 4')])); - const fnE = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 5')])); - const fnF = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 6')])); - const fnG = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 7')])); + const fnB = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 2'])); + const fnC = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 3'])); + const fnD = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 4'])); + const fnE = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 5'])); + const fnF = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 6'])); + const fnG = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 7'])); fnE.nestedExecutions.push(fnF, fnG); @@ -55,13 +65,13 @@ describe('Execution Result test suite - collect encrypted logs', () => { const encryptedLogs = collectEncryptedLogs(executionResult); expect(encryptedLogs).toEqual([ - new FunctionL2Logs([Buffer.from('Log 1')]), - new FunctionL2Logs([Buffer.from('Log 5')]), - new FunctionL2Logs([Buffer.from('Log 7')]), - new FunctionL2Logs([Buffer.from('Log 6')]), - new FunctionL2Logs([Buffer.from('Log 3')]), - new FunctionL2Logs([Buffer.from('Log 4')]), - new FunctionL2Logs([Buffer.from('Log 2')]), + makeEncryptedFunctionLogs(['Log 1']), + makeEncryptedFunctionLogs(['Log 5']), + makeEncryptedFunctionLogs(['Log 7']), + makeEncryptedFunctionLogs(['Log 6']), + makeEncryptedFunctionLogs(['Log 3']), + makeEncryptedFunctionLogs(['Log 4']), + makeEncryptedFunctionLogs(['Log 2']), ]); }); @@ -74,19 +84,19 @@ describe('Execution Result test suite - collect encrypted logs', () => { Circuits and ACVM process in a DFS + stack like format: [fnA, fnC, fnD, fnB] */ const executionResult: ExecutionResult = emptyExecutionResultWithEncryptedLogs( - new FunctionL2Logs([Buffer.from('Log 1'), Buffer.from('Log 2')]), + makeEncryptedFunctionLogs(['Log 1', 'Log 2']), ); - const fnB = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 3'), Buffer.from('Log 4')])); - const fnC = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 5')])); - const fnD = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 6')])); + const fnB = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 3', 'Log 4'])); + const fnC = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 5'])); + const fnD = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 6'])); fnC.nestedExecutions.push(fnD); executionResult.nestedExecutions.push(fnB, fnC); const encryptedLogs = collectEncryptedLogs(executionResult); expect(encryptedLogs).toEqual([ - new FunctionL2Logs([Buffer.from('Log 1'), Buffer.from('Log 2')]), - new FunctionL2Logs([Buffer.from('Log 5')]), - new FunctionL2Logs([Buffer.from('Log 6')]), - new FunctionL2Logs([Buffer.from('Log 3'), Buffer.from('Log 4')]), + makeEncryptedFunctionLogs(['Log 1', 'Log 2']), + makeEncryptedFunctionLogs(['Log 5']), + makeEncryptedFunctionLogs(['Log 6']), + makeEncryptedFunctionLogs(['Log 3', 'Log 4']), ]); }); @@ -98,15 +108,15 @@ describe('Execution Result test suite - collect encrypted logs', () => { Circuits and ACVM process in a DFS + stack like format: [fnA, fnB, fnC] */ const executionResult: ExecutionResult = emptyExecutionResult(); - const fnB = emptyExecutionResultWithEncryptedLogs(new FunctionL2Logs([Buffer.from('Log 1')])); + const fnB = emptyExecutionResultWithEncryptedLogs(makeEncryptedFunctionLogs(['Log 1'])); const fnC = emptyExecutionResult(); fnB.nestedExecutions.push(fnC); executionResult.nestedExecutions.push(fnB); const encryptedLogs = collectEncryptedLogs(executionResult); expect(encryptedLogs).toEqual([ - FunctionL2Logs.empty(), - new FunctionL2Logs([Buffer.from('Log 1')]), - FunctionL2Logs.empty(), + EncryptedFunctionL2Logs.empty(), + makeEncryptedFunctionLogs(['Log 1']), + EncryptedFunctionL2Logs.empty(), ]); }); @@ -131,11 +141,11 @@ describe('Execution Result test suite - collect encrypted logs', () => { const encryptedLogs = collectEncryptedLogs(executionResult); expect(encryptedLogs).toEqual([ - FunctionL2Logs.empty(), - FunctionL2Logs.empty(), - FunctionL2Logs.empty(), - FunctionL2Logs.empty(), - FunctionL2Logs.empty(), + EncryptedFunctionL2Logs.empty(), + EncryptedFunctionL2Logs.empty(), + EncryptedFunctionL2Logs.empty(), + EncryptedFunctionL2Logs.empty(), + EncryptedFunctionL2Logs.empty(), ]); }); }); @@ -143,17 +153,25 @@ describe('Execution Result test suite - collect encrypted logs', () => { describe('collect unencrypted logs', () => { // collection of unencrypted logs work similar to encrypted logs, so lets write other kinds of test cases: - function emptyExecutionResultWithUnencryptedLogs(unencryptedLogs = FunctionL2Logs.empty()): ExecutionResult { + function emptyExecutionResultWithUnencryptedLogs( + unencryptedLogs = UnencryptedFunctionL2Logs.empty(), + ): ExecutionResult { const executionResult = emptyExecutionResult(); executionResult.unencryptedLogs = unencryptedLogs; return executionResult; } + function makeUnencryptedFunctionLogs(contents: string[]) { + return new UnencryptedFunctionL2Logs( + contents.map(s => new UnencryptedL2Log(AztecAddress.ZERO, EventSelector.empty(), Buffer.from(s))), + ); + } + it('collect unencrypted logs even when no logs and no recursion', () => { // fnA() const executionResult: ExecutionResult = emptyExecutionResult(); const unencryptedLogs = collectUnencryptedLogs(executionResult); - expect(unencryptedLogs).toEqual([FunctionL2Logs.empty()]); + expect(unencryptedLogs).toEqual([UnencryptedFunctionL2Logs.empty()]); }); it('collect unencrypted logs with no logs in some nested calls', () => { @@ -165,17 +183,15 @@ describe('collect unencrypted logs', () => { */ const executionResult: ExecutionResult = emptyExecutionResult(); const fnB = emptyExecutionResult(); - const fnC = emptyExecutionResultWithUnencryptedLogs( - new FunctionL2Logs([Buffer.from('Log 1'), Buffer.from('Log 2'), Buffer.from('Log 3')]), - ); + const fnC = emptyExecutionResultWithUnencryptedLogs(makeUnencryptedFunctionLogs(['Log 1', 'Log 2', 'Log 3'])); executionResult.nestedExecutions.push(fnB, fnC); const unencryptedLogs = collectUnencryptedLogs(executionResult); expect(unencryptedLogs).toEqual([ - FunctionL2Logs.empty(), - new FunctionL2Logs([Buffer.from('Log 1'), Buffer.from('Log 2'), Buffer.from('Log 3')]), - FunctionL2Logs.empty(), + UnencryptedFunctionL2Logs.empty(), + makeUnencryptedFunctionLogs(['Log 1', 'Log 2', 'Log 3']), + UnencryptedFunctionL2Logs.empty(), ]); }); @@ -190,20 +206,16 @@ describe('collect unencrypted logs', () => { */ const executionResult: ExecutionResult = emptyExecutionResult(); const fnB = emptyExecutionResult(); - const fnC = emptyExecutionResultWithUnencryptedLogs( - new FunctionL2Logs([Buffer.from('Log 1'), Buffer.from('Log 2'), Buffer.from('Log 3')]), - ); - const fnD = emptyExecutionResultWithUnencryptedLogs( - new FunctionL2Logs([Buffer.from('Log 4'), Buffer.from('Log 5'), Buffer.from('Log 6')]), - ); + const fnC = emptyExecutionResultWithUnencryptedLogs(makeUnencryptedFunctionLogs(['Log 1', 'Log 2', 'Log 3'])); + const fnD = emptyExecutionResultWithUnencryptedLogs(makeUnencryptedFunctionLogs(['Log 4', 'Log 5', 'Log 6'])); fnB.nestedExecutions.push(fnC, fnD); executionResult.nestedExecutions.push(fnB); const unencryptedLogs = collectUnencryptedLogs(executionResult); expect(unencryptedLogs).toEqual([ - FunctionL2Logs.empty(), - FunctionL2Logs.empty(), - new FunctionL2Logs([Buffer.from('Log 4'), Buffer.from('Log 5'), Buffer.from('Log 6')]), - new FunctionL2Logs([Buffer.from('Log 1'), Buffer.from('Log 2'), Buffer.from('Log 3')]), + UnencryptedFunctionL2Logs.empty(), + UnencryptedFunctionL2Logs.empty(), + makeUnencryptedFunctionLogs(['Log 4', 'Log 5', 'Log 6']), + makeUnencryptedFunctionLogs(['Log 1', 'Log 2', 'Log 3']), ]); }); }); diff --git a/yarn-project/simulator/src/client/execution_result.ts b/yarn-project/simulator/src/client/execution_result.ts index 355f4d8abbe8..4fccc6e8e015 100644 --- a/yarn-project/simulator/src/client/execution_result.ts +++ b/yarn-project/simulator/src/client/execution_result.ts @@ -1,4 +1,4 @@ -import { FunctionL2Logs, Note } from '@aztec/circuit-types'; +import { EncryptedFunctionL2Logs, Note, UnencryptedFunctionL2Logs } from '@aztec/circuit-types'; import { NoteHashReadRequestMembershipWitness, PrivateCallStackItem, PublicCallRequest } from '@aztec/circuits.js'; import { DecodedReturn } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; @@ -46,12 +46,12 @@ export interface ExecutionResult { * Encrypted logs emitted during execution of this function call. * Note: These are preimages to `encryptedLogsHash`. */ - encryptedLogs: FunctionL2Logs; + encryptedLogs: EncryptedFunctionL2Logs; /** * Unencrypted logs emitted during execution of this function call. * Note: These are preimages to `unencryptedLogsHash`. */ - unencryptedLogs: FunctionL2Logs; + unencryptedLogs: UnencryptedFunctionL2Logs; } /** @@ -59,7 +59,7 @@ export interface ExecutionResult { * @param execResult - The topmost execution result. * @returns All encrypted logs. */ -export function collectEncryptedLogs(execResult: ExecutionResult): FunctionL2Logs[] { +export function collectEncryptedLogs(execResult: ExecutionResult): EncryptedFunctionL2Logs[] { // without the .reverse(), the logs will be in a queue like fashion which is wrong as the kernel processes it like a stack. return [execResult.encryptedLogs, ...[...execResult.nestedExecutions].reverse().flatMap(collectEncryptedLogs)]; } @@ -69,7 +69,7 @@ export function collectEncryptedLogs(execResult: ExecutionResult): FunctionL2Log * @param execResult - The topmost execution result. * @returns All unencrypted logs. */ -export function collectUnencryptedLogs(execResult: ExecutionResult): FunctionL2Logs[] { +export function collectUnencryptedLogs(execResult: ExecutionResult): UnencryptedFunctionL2Logs[] { // without the .reverse(), the logs will be in a queue like fashion which is wrong as the kernel processes it like a stack. return [execResult.unencryptedLogs, ...[...execResult.nestedExecutions].reverse().flatMap(collectUnencryptedLogs)]; } diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index 003ecf44bc22..1c959d2ae9b6 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -214,7 +214,7 @@ describe('Private Execution test suite', () => { const [functionLogs] = collectUnencryptedLogs(result); expect(functionLogs.logs).toHaveLength(1); // Test that the log payload (ie ignoring address, selector, and header) matches what we emitted - expect(functionLogs.logs[0].subarray(-32).toString('hex')).toEqual(owner.toBuffer().toString('hex')); + expect(functionLogs.logs[0].data.subarray(-32).toString('hex')).toEqual(owner.toBuffer().toString('hex')); }); it('emits a field array as an unencrypted log', async () => { @@ -225,7 +225,7 @@ describe('Private Execution test suite', () => { expect(functionLogs.logs).toHaveLength(1); // Test that the log payload (ie ignoring address, selector, and header) matches what we emitted const expected = Buffer.concat(args[0].map(arg => arg.toBuffer())).toString('hex'); - expect(functionLogs.logs[0].subarray(-32 * 5).toString('hex')).toEqual(expected); + expect(functionLogs.logs[0].data.subarray(-32 * 5).toString('hex')).toEqual(expected); }); }); diff --git a/yarn-project/simulator/src/public/execution.ts b/yarn-project/simulator/src/public/execution.ts index e66a313bbe11..d0a5e387b06a 100644 --- a/yarn-project/simulator/src/public/execution.ts +++ b/yarn-project/simulator/src/public/execution.ts @@ -1,4 +1,4 @@ -import { FunctionL2Logs, SimulationError } from '@aztec/circuit-types'; +import { SimulationError, UnencryptedFunctionL2Logs } from '@aztec/circuit-types'; import { AztecAddress, ContractStorageRead, @@ -46,7 +46,7 @@ export interface PublicExecutionResult { * Unencrypted logs emitted during execution of this function call. * Note: These are preimages to `unencryptedLogsHash`. */ - unencryptedLogs: FunctionL2Logs; + unencryptedLogs: UnencryptedFunctionL2Logs; /** * Whether the execution reverted. */ @@ -154,7 +154,7 @@ export function checkValidStaticCall( newNullifiers: SideEffectLinkedToNoteHash[], contractStorageUpdateRequests: ContractStorageUpdateRequest[], newL2ToL1Messages: L2ToL1Message[], - unencryptedLogs: FunctionL2Logs, + unencryptedLogs: UnencryptedFunctionL2Logs, ) { if ( contractStorageUpdateRequests.length > 0 || diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index c7278091e589..13ffcecc79b5 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -1,4 +1,4 @@ -import { FunctionL2Logs } from '@aztec/circuit-types'; +import { UnencryptedFunctionL2Logs } from '@aztec/circuit-types'; import { Fr, GlobalVariables, Header, PublicCircuitPublicInputs } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -92,7 +92,7 @@ export async function executePublicFunction( contractStorageReads: [], contractStorageUpdateRequests: [], nestedExecutions: [], - unencryptedLogs: FunctionL2Logs.empty(), + unencryptedLogs: UnencryptedFunctionL2Logs.empty(), reverted, revertReason, }; diff --git a/yarn-project/simulator/src/public/public_execution_context.ts b/yarn-project/simulator/src/public/public_execution_context.ts index 69f9caa6edab..ab54bf1c7921 100644 --- a/yarn-project/simulator/src/public/public_execution_context.ts +++ b/yarn-project/simulator/src/public/public_execution_context.ts @@ -1,4 +1,4 @@ -import { FunctionL2Logs, NullifierMembershipWitness, UnencryptedL2Log } from '@aztec/circuit-types'; +import { NullifierMembershipWitness, UnencryptedFunctionL2Logs, UnencryptedL2Log } from '@aztec/circuit-types'; import { CallContext, FunctionData, FunctionSelector, GlobalVariables, Header } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -72,7 +72,7 @@ export class PublicExecutionContext extends TypedOracle { * Return the encrypted logs emitted during this execution. */ public getUnencryptedLogs() { - return new FunctionL2Logs(this.unencryptedLogs.map(log => log.toBuffer())); + return new UnencryptedFunctionL2Logs(this.unencryptedLogs); } /**