From a2741ae44ddd2b7b6e6602f0e47159f03be4f263 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 07:52:25 +0000 Subject: [PATCH 01/41] WIP --- yarn-project/pxe/src/database/database.ts | 14 +++++-------- yarn-project/pxe/src/database/memory_db.ts | 21 +++++++++++++------ .../pxe/src/pxe_service/pxe_service.ts | 6 ++++++ yarn-project/types/src/index.ts | 1 + yarn-project/types/src/interfaces/pxe.ts | 9 ++++++++ yarn-project/types/src/note_filter.ts | 18 ++++++++++++++++ 6 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 yarn-project/types/src/note_filter.ts diff --git a/yarn-project/pxe/src/database/database.ts b/yarn-project/pxe/src/database/database.ts index 8696d035c1cd..e53e514a3610 100644 --- a/yarn-project/pxe/src/database/database.ts +++ b/yarn-project/pxe/src/database/database.ts @@ -1,7 +1,7 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { ContractDatabase, MerkleTreeId, PublicKey } from '@aztec/types'; +import { ContractDatabase, MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; import { NoteSpendingInfoDao } from './note_spending_info_dao.js'; @@ -25,15 +25,11 @@ export interface Database extends ContractDatabase { getAuthWitness(messageHash: Fr): Promise; /** - * Get auxiliary transaction data based on contract address and storage slot. - * It searches for matching NoteSpendingInfoDao objects in the MemoryDB's noteSpendingInfoTable - * where both the contractAddress and storageSlot properties match the given inputs. - * - * @param contract - The contract address. - * @param storageSlot - A Fr object representing the storage slot to search for in the auxiliary data. - * @returns An array of NoteSpendingInfoDao objects that fulfill the contract address and storage slot criteria. + * Gets notes based on the provided filter. + * @param filter - The filter to apply to the notes. + * @returns The requested notes. */ - getNoteSpendingInfo(contract: AztecAddress, storageSlot: Fr): Promise; + getNoteSpendingInfo(filter: NoteFilter): Promise; /** * Add a NoteSpendingInfoDao instance to the noteSpendingInfoTable. diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 6058ac8cc53d..04f3baf78d08 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -2,7 +2,7 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { MerkleTreeId, PublicKey } from '@aztec/types'; +import { MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; import { MemoryContractDatabase } from '../contract_database/index.js'; import { Database } from './database.js'; @@ -54,13 +54,22 @@ export class MemoryDB extends MemoryContractDatabase implements Database { return Promise.resolve(); } - public getNoteSpendingInfo(contract: AztecAddress, storageSlot: Fr) { - const res = this.noteSpendingInfoTable.filter( + public async getNoteSpendingInfo(filter: NoteFilter): Promise { + let ownerPublicKey: PublicKey | undefined; + if (filter.owner !== undefined) { + const ownerCompleteAddress = await this.getCompleteAddress(filter.owner); + if (ownerCompleteAddress === undefined) { + throw new Error(`Owner ${filter.owner.toString()} not found in memory database`); + } + ownerPublicKey = ownerCompleteAddress.publicKey; + } + + return this.noteSpendingInfoTable.filter( noteSpendingInfo => - noteSpendingInfo.contractAddress.equals(contract) && - noteSpendingInfo.storageSlot.toBuffer().equals(storageSlot.toBuffer()), + (filter.contractAddress == undefined || noteSpendingInfo.contractAddress.equals(filter.contractAddress)) && + (filter.storageSlot == undefined || noteSpendingInfo.storageSlot.equals(filter.storageSlot!)) && + (ownerPublicKey == undefined || noteSpendingInfo.publicKey.equals(ownerPublicKey!)), ); - return Promise.resolve(res); } public removeNullifiedNoteSpendingInfo(nullifiers: Fr[], account: PublicKey) { diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index ec375cbad3db..435b37dbc67d 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -38,7 +38,9 @@ import { LogFilter, MerkleTreeId, NodeInfo, + NoteFilter, NotePreimage, + NoteSpendingInfo, PXE, SimulationError, Tx, @@ -204,6 +206,10 @@ export class PXEService implements PXE { return ownerNotes.map(n => n.notePreimage); } + public async getNotes(filter: NoteFilter): Promise { + return await this.db.getNoteSpendingInfo(filter); + } + public async addNote( account: AztecAddress, contractAddress: AztecAddress, diff --git a/yarn-project/types/src/index.ts b/yarn-project/types/src/index.ts index 9d41e4dcb674..4483f32a1735 100644 --- a/yarn-project/types/src/index.ts +++ b/yarn-project/types/src/index.ts @@ -4,6 +4,7 @@ export * from './contract_database.js'; export * from './contract_data.js'; export * from './function_call.js'; export * from './keys/index.js'; +export * from './note_filter.js'; export * from './l1_to_l2_message.js'; export * from './l2_block.js'; export * from './l2_block_context.js'; diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index 24ef850105e1..d4b2c22ff6f3 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -8,6 +8,7 @@ import { L2Tx, LogFilter, NotePreimage, + NoteSpendingInfo, Tx, TxExecutionRequest, TxHash, @@ -17,6 +18,7 @@ import { import { DeployedContract } from './deployed-contract.js'; import { NodeInfo } from './node-info.js'; import { SyncStatus } from './sync-status.js'; +import { NoteFilter } from '../note_filter.js'; // docs:start:pxe-interface /** @@ -171,6 +173,13 @@ export interface PXE { */ getPublicStorageAt(contract: AztecAddress, storageSlot: Fr): Promise; + /** + * Gets notes based on the provided filter. + * @param filter - The filter to apply to the notes. + * @returns The requested notes. + */ + getNotes(filter: NoteFilter): Promise; + /** * Adds a note to the database. Throw if the note hash of the note doesn't exist in the tree. * @param account - The account the note is associated with. diff --git a/yarn-project/types/src/note_filter.ts b/yarn-project/types/src/note_filter.ts new file mode 100644 index 000000000000..f0793dfb044a --- /dev/null +++ b/yarn-project/types/src/note_filter.ts @@ -0,0 +1,18 @@ +import { AztecAddress, Fr } from '@aztec/circuits.js'; + +import { TxHash } from './index.js'; + +/** + * A filter used to fetch Notes. + * @remarks This filter is applied as an intersection of all it's params. + */ +export type NoteFilter = { + /** Hash of a transaction from which to fetch the notes. */ + txHash?: TxHash; + /** The contract address the note belongs to. */ + contractAddress?: AztecAddress; + /** The specific storage location of the note on the contract. */ + storageSlot?: Fr; + /** The owner of the note (whose public key was used to encrypt the note). */ + owner?: AztecAddress; +}; From 81c5b0a095ab0d5253f16c84d3b7b4ed63b8ed5c Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 08:08:26 +0000 Subject: [PATCH 02/41] random tx hash mock --- yarn-project/p2p/src/service/known_txs.test.ts | 11 +++-------- yarn-project/p2p/src/service/tx_messages.test.ts | 11 +++-------- yarn-project/types/src/l2_block_context.ts | 2 +- yarn-project/types/src/mocks.ts | 4 +++- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/yarn-project/p2p/src/service/known_txs.test.ts b/yarn-project/p2p/src/service/known_txs.test.ts index 1b9de9d570a4..1f8345751f5d 100644 --- a/yarn-project/p2p/src/service/known_txs.test.ts +++ b/yarn-project/p2p/src/service/known_txs.test.ts @@ -1,5 +1,4 @@ -import { randomBytes } from '@aztec/foundation/crypto'; -import { TxHash } from '@aztec/types'; +import { randomTxHash } from '@aztec/types'; import { expect } from '@jest/globals'; import { Ed25519PeerId, PeerId } from '@libp2p/interface-peer-id'; @@ -13,16 +12,12 @@ const createMockPeerId = (peerId: string): PeerId => { }); }; -const createTxHash = () => { - return new TxHash(randomBytes(32)); -}; - describe('Known Txs', () => { it('Returns false when a peer has not seen a tx', () => { const knownTxs = new KnownTxLookup(); const peer = createMockPeerId('Peer 1'); - const txHash = createTxHash(); + const txHash = randomTxHash(); expect(knownTxs.hasPeerSeenTx(peer, txHash.toString())).toEqual(false); }); @@ -32,7 +27,7 @@ describe('Known Txs', () => { const peer = createMockPeerId('Peer 1'); const peer2 = createMockPeerId('Peer 2'); - const txHash = createTxHash(); + const txHash = randomTxHash(); knownTxs.addPeerForTx(peer, txHash.toString()); diff --git a/yarn-project/p2p/src/service/tx_messages.test.ts b/yarn-project/p2p/src/service/tx_messages.test.ts index cdbc0dc63538..3d112a902d1d 100644 --- a/yarn-project/p2p/src/service/tx_messages.test.ts +++ b/yarn-project/p2p/src/service/tx_messages.test.ts @@ -1,7 +1,6 @@ -import { Tx, TxHash, mockTx } from '@aztec/types'; +import { Tx, mockTx, randomTxHash } from '@aztec/types'; import { expect } from '@jest/globals'; -import { randomBytes } from 'crypto'; import { Messages, @@ -17,10 +16,6 @@ import { toTxMessage, } from './tx_messages.js'; -const makeTxHash = () => { - return new TxHash(randomBytes(32)); -}; - const verifyTx = (actual: Tx, expected: Tx) => { expect(actual.data!.toBuffer()).toEqual(expected.data?.toBuffer()); expect(actual.proof!.toBuffer()).toEqual(expected.proof!.toBuffer()); @@ -50,7 +45,7 @@ describe('Messages', () => { }); it('Correctly serializes and deserializes transaction hashes message', () => { - const txHashes = [makeTxHash(), makeTxHash(), makeTxHash()]; + const txHashes = [randomTxHash(), randomTxHash(), randomTxHash()]; const message = createTransactionHashesMessage(txHashes); expect(decodeMessageType(message)).toEqual(Messages.POOLED_TRANSACTION_HASHES); const decodedHashes = decodeTransactionHashesMessage(getEncodedMessage(message)); @@ -58,7 +53,7 @@ describe('Messages', () => { }); it('Correctly serializes and deserializes get transactions message', () => { - const txHashes = [makeTxHash(), makeTxHash(), makeTxHash()]; + const txHashes = [randomTxHash(), randomTxHash(), randomTxHash()]; const message = createGetTransactionsRequestMessage(txHashes); expect(decodeMessageType(message)).toEqual(Messages.GET_TRANSACTIONS); const decodedHashes = decodeGetTransactionsRequestMessage(getEncodedMessage(message)); diff --git a/yarn-project/types/src/l2_block_context.ts b/yarn-project/types/src/l2_block_context.ts index 0b0ab30b090a..338d81022755 100644 --- a/yarn-project/types/src/l2_block_context.ts +++ b/yarn-project/types/src/l2_block_context.ts @@ -16,7 +16,7 @@ export class L2BlockContext { /** * Returns the tx hash of the tx in the block at the given index. - * @param txIndex - The index of the tx. + * @param txIndex - The index of the tx in the block. * @returns The tx's hash. */ public getTxHash(txIndex: number): TxHash { diff --git a/yarn-project/types/src/mocks.ts b/yarn-project/types/src/mocks.ts index 3fded6d748d9..a52047b5c480 100644 --- a/yarn-project/types/src/mocks.ts +++ b/yarn-project/types/src/mocks.ts @@ -13,7 +13,7 @@ import { Tuple } from '@aztec/foundation/serialize'; import times from 'lodash.times'; import { DeployedContract, ExtendedContractData, FunctionL2Logs, TxL2Logs } from './index.js'; -import { Tx } from './tx/index.js'; +import { Tx, TxHash } from './tx/index.js'; /** * Testing utility to create empty logs composed from a single empty log. @@ -23,6 +23,8 @@ export function makeEmptyLogs(): TxL2Logs { return new TxL2Logs(functionLogs); } +export const randomTxHash = (): TxHash => new TxHash(randomBytes(32)); + export const mockTx = (seed = 1) => { return new Tx( makePrivateKernelPublicInputsFinal(seed), From 0ee21d61bc5adf0b76090f9ed8c77304a315df8b Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 09:15:29 +0000 Subject: [PATCH 03/41] WIP --- yarn-project/pxe/src/database/memory_db.ts | 1 + yarn-project/pxe/src/database/note_spending_info_dao.ts | 8 +++++++- yarn-project/pxe/src/note_processor/note_processor.ts | 4 +++- yarn-project/pxe/src/pxe_service/pxe_service.ts | 1 + yarn-project/types/src/interfaces/pxe.ts | 2 +- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 04f3baf78d08..7f6a20d3e8c5 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -67,6 +67,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { return this.noteSpendingInfoTable.filter( noteSpendingInfo => (filter.contractAddress == undefined || noteSpendingInfo.contractAddress.equals(filter.contractAddress)) && + (filter.txHash == undefined || noteSpendingInfo.txHash.equals(filter.txHash)) && (filter.storageSlot == undefined || noteSpendingInfo.storageSlot.equals(filter.storageSlot!)) && (ownerPublicKey == undefined || noteSpendingInfo.publicKey.equals(ownerPublicKey!)), ); diff --git a/yarn-project/pxe/src/database/note_spending_info_dao.ts b/yarn-project/pxe/src/database/note_spending_info_dao.ts index daac960c7e60..533d0abb7e0d 100644 --- a/yarn-project/pxe/src/database/note_spending_info_dao.ts +++ b/yarn-project/pxe/src/database/note_spending_info_dao.ts @@ -1,6 +1,6 @@ import { AztecAddress, Fr, PublicKey } from '@aztec/circuits.js'; import { Point } from '@aztec/foundation/fields'; -import { NotePreimage } from '@aztec/types'; +import { NotePreimage, TxHash, randomTxHash } from '@aztec/types'; /** * Represents the data access object for auxiliary transaction data. @@ -12,6 +12,10 @@ export interface NoteSpendingInfoDao { * The contract address this note is created in. */ contractAddress: AztecAddress; + /** + * The hash of the tx the note was created in. + */ + txHash: TxHash; /** * The nonce of the note. */ @@ -45,6 +49,7 @@ export interface NoteSpendingInfoDao { export const createRandomNoteSpendingInfoDao = ({ contractAddress = AztecAddress.random(), + txHash = randomTxHash(), nonce = Fr.random(), storageSlot = Fr.random(), notePreimage = NotePreimage.random(), @@ -54,6 +59,7 @@ export const createRandomNoteSpendingInfoDao = ({ publicKey = Point.random(), }: Partial = {}): NoteSpendingInfoDao => ({ contractAddress, + txHash, nonce, storageSlot, notePreimage, diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 823be99e7d3c..df01d2b6abeb 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -99,7 +99,8 @@ export class NoteProcessor { for (let blockIndex = 0; blockIndex < encryptedL2BlockLogs.length; ++blockIndex) { this.stats.blocks++; const { txLogs } = encryptedL2BlockLogs[blockIndex]; - const block = l2BlockContexts[blockIndex].block; + const blockContext = l2BlockContexts[blockIndex]; + const block = blockContext.block; const dataStartIndexForBlock = block.startNoteHashTreeSnapshot.nextAvailableLeafIndex; // We are using set for `userPertainingTxIndices` to avoid duplicates. This would happen in case there were @@ -145,6 +146,7 @@ export class NoteProcessor { siloedNullifier, index, publicKey: this.publicKey, + txHash: blockContext.getTxHash(indexOfTxInABlock), }); this.stats.decrypted++; } catch (e) { diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 435b37dbc67d..07c8afd19cfd 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -250,6 +250,7 @@ export class PXEService implements PXE { await this.db.addNoteSpendingInfo({ contractAddress, + txHash, storageSlot, notePreimage: preimage, nonce, diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index d4b2c22ff6f3..397e399e81bd 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -15,10 +15,10 @@ import { TxReceipt, } from '@aztec/types'; +import { NoteFilter } from '../note_filter.js'; import { DeployedContract } from './deployed-contract.js'; import { NodeInfo } from './node-info.js'; import { SyncStatus } from './sync-status.js'; -import { NoteFilter } from '../note_filter.js'; // docs:start:pxe-interface /** From f036951f6f6e64d83bb87769d40ca274925db222 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 09:55:56 +0000 Subject: [PATCH 04/41] WIP --- .../pxe/src/database/memory_db.test.ts | 4 +- yarn-project/pxe/src/database/memory_db.ts | 5 +- .../src/database/note_spending_info_dao.ts | 81 ---------------- yarn-project/types/src/index.ts | 2 +- yarn-project/types/src/interfaces/pxe.ts | 2 +- yarn-project/types/src/mocks.ts | 36 +++++++- yarn-project/types/src/notes/index.ts | 2 + .../types/src/{ => notes}/note_filter.ts | 2 +- .../types/src/notes/note_spending_info_dao.ts | 92 +++++++++++++++++++ 9 files changed, 136 insertions(+), 90 deletions(-) delete mode 100644 yarn-project/pxe/src/database/note_spending_info_dao.ts create mode 100644 yarn-project/types/src/notes/index.ts rename yarn-project/types/src/{ => notes}/note_filter.ts (93%) create mode 100644 yarn-project/types/src/notes/note_spending_info_dao.ts diff --git a/yarn-project/pxe/src/database/memory_db.test.ts b/yarn-project/pxe/src/database/memory_db.test.ts index d2536329eb6d..6188a6696a13 100644 --- a/yarn-project/pxe/src/database/memory_db.test.ts +++ b/yarn-project/pxe/src/database/memory_db.test.ts @@ -1,7 +1,7 @@ import { AztecAddress, Fr } from '@aztec/circuits.js'; import { MemoryDB } from './memory_db.js'; -import { NoteSpendingInfoDao, createRandomNoteSpendingInfoDao } from './note_spending_info_dao.js'; +import { NoteSpendingInfoDao, randomNoteSpendingInfoDao } from './note_spending_info_dao.js'; describe('Memory DB', () => { let db: MemoryDB; @@ -15,7 +15,7 @@ describe('Memory DB', () => { const storageSlot = Fr.random(); const createNote = (attributes: Partial = {}, sameStorage = true) => - createRandomNoteSpendingInfoDao({ + randomNoteSpendingInfoDao({ ...attributes, contractAddress: sameStorage ? contractAddress : AztecAddress.random(), storageSlot: sameStorage ? storageSlot : Fr.random(), diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 7f6a20d3e8c5..78b7591db696 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -2,11 +2,10 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; +import { MerkleTreeId, NoteFilter, NoteSpendingInfoDao, PublicKey } from '@aztec/types'; import { MemoryContractDatabase } from '../contract_database/index.js'; import { Database } from './database.js'; -import { NoteSpendingInfoDao, getNoteSpendingInfoDaoSize } from './note_spending_info_dao.js'; /** * The MemoryDB class provides an in-memory implementation of a database to manage transactions and auxiliary data. @@ -156,7 +155,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { } public estimateSize() { - const notesSize = this.noteSpendingInfoTable.reduce((sum, note) => sum + getNoteSpendingInfoDaoSize(note), 0); + const notesSize = this.noteSpendingInfoTable.reduce((sum, note) => sum + note.getSize(note), 0); const treeRootsSize = this.treeRoots ? Object.entries(this.treeRoots).length * Fr.SIZE_IN_BYTES : 0; const authWits = Object.entries(this.authWitnesses); const authWitsSize = authWits.reduce((sum, [key, value]) => sum + key.length + value.length * Fr.SIZE_IN_BYTES, 0); diff --git a/yarn-project/pxe/src/database/note_spending_info_dao.ts b/yarn-project/pxe/src/database/note_spending_info_dao.ts deleted file mode 100644 index 533d0abb7e0d..000000000000 --- a/yarn-project/pxe/src/database/note_spending_info_dao.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { AztecAddress, Fr, PublicKey } from '@aztec/circuits.js'; -import { Point } from '@aztec/foundation/fields'; -import { NotePreimage, TxHash, randomTxHash } from '@aztec/types'; - -/** - * Represents the data access object for auxiliary transaction data. - * Contains properties from the decrypted note, computed properties, and information about - * the public key used for encryption, as well as the location of the data in the tree. - */ -export interface NoteSpendingInfoDao { - /** - * The contract address this note is created in. - */ - contractAddress: AztecAddress; - /** - * The hash of the tx the note was created in. - */ - txHash: TxHash; - /** - * The nonce of the note. - */ - nonce: Fr; - /** - * The specific storage location of the note on the contract. - */ - storageSlot: Fr; - /** - * The preimage of the note, containing essential information about the note. - */ - notePreimage: NotePreimage; - /** - * Inner note hash of the note. This is customizable by the app circuit. - * We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash. - */ - innerNoteHash: Fr; - /** - * The nullifier of the note (siloed by contract address). - */ - siloedNullifier: Fr; - /** - * The location of the relevant note in the note hash tree. - */ - index: bigint; - /** - * The public key that was used to encrypt the data. - */ - publicKey: PublicKey; -} - -export const createRandomNoteSpendingInfoDao = ({ - contractAddress = AztecAddress.random(), - txHash = randomTxHash(), - nonce = Fr.random(), - storageSlot = Fr.random(), - notePreimage = NotePreimage.random(), - innerNoteHash = Fr.random(), - siloedNullifier = Fr.random(), - index = Fr.random().value, - publicKey = Point.random(), -}: Partial = {}): NoteSpendingInfoDao => ({ - contractAddress, - txHash, - nonce, - storageSlot, - notePreimage, - innerNoteHash, - siloedNullifier, - index, - publicKey, -}); - -/** - * Returns the size in bytes of a note spending info dao. - * @param note - The note. - * @returns - Its size in bytes. - */ -export function getNoteSpendingInfoDaoSize(note: NoteSpendingInfoDao) { - // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer - const indexSize = Math.ceil(Math.log2(Number(note.index))); - return 7 * Fr.SIZE_IN_BYTES + indexSize + 4 + note.notePreimage.items.length * Fr.SIZE_IN_BYTES; -} diff --git a/yarn-project/types/src/index.ts b/yarn-project/types/src/index.ts index 4483f32a1735..3ffc81251033 100644 --- a/yarn-project/types/src/index.ts +++ b/yarn-project/types/src/index.ts @@ -4,7 +4,7 @@ export * from './contract_database.js'; export * from './contract_data.js'; export * from './function_call.js'; export * from './keys/index.js'; -export * from './note_filter.js'; +export * from './notes/index.js'; export * from './l1_to_l2_message.js'; export * from './l2_block.js'; export * from './l2_block_context.js'; diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index 397e399e81bd..7c32ed4aaba4 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -15,7 +15,7 @@ import { TxReceipt, } from '@aztec/types'; -import { NoteFilter } from '../note_filter.js'; +import { NoteFilter } from '../notes/note_filter.js'; import { DeployedContract } from './deployed-contract.js'; import { NodeInfo } from './node-info.js'; import { SyncStatus } from './sync-status.js'; diff --git a/yarn-project/types/src/mocks.ts b/yarn-project/types/src/mocks.ts index a52047b5c480..6da0ba48587e 100644 --- a/yarn-project/types/src/mocks.ts +++ b/yarn-project/types/src/mocks.ts @@ -1,8 +1,11 @@ import { + AztecAddress, CompleteAddress, EthAddress, + Fr, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + Point, Proof, } from '@aztec/circuits.js'; import { makePrivateKernelPublicInputsFinal, makePublicCallRequest } from '@aztec/circuits.js/factories'; @@ -12,7 +15,14 @@ import { Tuple } from '@aztec/foundation/serialize'; import times from 'lodash.times'; -import { DeployedContract, ExtendedContractData, FunctionL2Logs, TxL2Logs } from './index.js'; +import { + DeployedContract, + ExtendedContractData, + FunctionL2Logs, + NotePreimage, + NoteSpendingInfoDao, + TxL2Logs, +} from './index.js'; import { Tx, TxHash } from './tx/index.js'; /** @@ -50,3 +60,27 @@ export const randomDeployedContract = async (): Promise => ({ completeAddress: await CompleteAddress.random(), portalContract: EthAddress.random(), }); + +export const randomNoteSpendingInfoDao = ( + contractAddress = AztecAddress.random(), + txHash = randomTxHash(), + nonce = Fr.random(), + storageSlot = Fr.random(), + notePreimage = NotePreimage.random(), + innerNoteHash = Fr.random(), + siloedNullifier = Fr.random(), + index = Fr.random().value, + publicKey = Point.random(), +) => { + return new NoteSpendingInfoDao( + contractAddress, + txHash, + nonce, + storageSlot, + notePreimage, + innerNoteHash, + siloedNullifier, + index, + publicKey, + ); +}; diff --git a/yarn-project/types/src/notes/index.ts b/yarn-project/types/src/notes/index.ts new file mode 100644 index 000000000000..9729d89d4bb0 --- /dev/null +++ b/yarn-project/types/src/notes/index.ts @@ -0,0 +1,2 @@ +export * from './note_filter.js'; +export * from './note_spending_info_dao.js'; diff --git a/yarn-project/types/src/note_filter.ts b/yarn-project/types/src/notes/note_filter.ts similarity index 93% rename from yarn-project/types/src/note_filter.ts rename to yarn-project/types/src/notes/note_filter.ts index f0793dfb044a..515dabb7c354 100644 --- a/yarn-project/types/src/note_filter.ts +++ b/yarn-project/types/src/notes/note_filter.ts @@ -1,6 +1,6 @@ import { AztecAddress, Fr } from '@aztec/circuits.js'; -import { TxHash } from './index.js'; +import { TxHash } from '../index.js'; /** * A filter used to fetch Notes. diff --git a/yarn-project/types/src/notes/note_spending_info_dao.ts b/yarn-project/types/src/notes/note_spending_info_dao.ts new file mode 100644 index 000000000000..ced6721aad6a --- /dev/null +++ b/yarn-project/types/src/notes/note_spending_info_dao.ts @@ -0,0 +1,92 @@ +import { AztecAddress, Fr, Point, PublicKey } from '@aztec/circuits.js'; +import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; +import { BufferReader, NotePreimage, TxHash } from '@aztec/types'; + +/** + * Represents the data access object for auxiliary transaction data. + * Contains properties from the decrypted note, computed properties, and information about + * the public key used for encryption, as well as the location of the data in the tree. + */ +export class NoteSpendingInfoDao { + constructor( + /** The preimage of the note, containing essential information about the note. */ + public notePreimage: NotePreimage, + /** The contract address this note is created in. */ + public contractAddress: AztecAddress, + /** The hash of the tx the note was created in. */ + public txHash: TxHash, + /** The nonce of the note. */ + public nonce: Fr, + /** The specific storage location of the note on the contract. */ + public storageSlot: Fr, + /** + * Inner note hash of the note. This is customizable by the app circuit. + * We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash. + */ + public innerNoteHash: Fr, + /** + * The nullifier of the note (siloed by contract address). + */ + public siloedNullifier: Fr, + /** + * The location of the relevant note in the note hash tree. + */ + public index: bigint, + /** + * The public key that was used to encrypt the data. + */ + public publicKey: PublicKey, + ) {} + + toBuffer(): Buffer { + return Buffer.concat([ + this.notePreimage.toBuffer(), + this.contractAddress.toBuffer(), + this.txHash.buffer, + this.nonce.toBuffer(), + this.storageSlot.toBuffer(), + this.innerNoteHash.toBuffer(), + this.siloedNullifier.toBuffer(), + toBufferBE(this.index, 32), + this.publicKey.toBuffer(), + ]); + } + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + + const notePreimage = NotePreimage.fromBuffer(reader); + const contractAddress = AztecAddress.fromBuffer(reader); + const txHash = new TxHash(reader.readBytes(TxHash.SIZE)); + const nonce = Fr.fromBuffer(reader); + const storageSlot = Fr.fromBuffer(reader); + const innerNoteHash = Fr.fromBuffer(reader); + const siloedNullifier = Fr.fromBuffer(reader); + const index = toBigIntBE(reader.readBytes(32)); + const publicKey = Point.fromBuffer(reader); + + return new this( + notePreimage, + contractAddress, + txHash, + nonce, + storageSlot, + innerNoteHash, + siloedNullifier, + index, + publicKey, + ); + } + + /** + * Returns the size in bytes of a note spending info dao. + * @param note - The note. + * @returns - Its size in bytes. + */ + public getSize(note: NoteSpendingInfoDao) { + // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer + const indexSize = Math.ceil(Math.log2(Number(note.index))); + return ( + note.notePreimage.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize + Point.SIZE_IN_BYTES + ); + } +} From 7a5f16fd9a5746a03e260a163741220ac028ced5 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 10:19:35 +0000 Subject: [PATCH 05/41] WIP --- .../aztec.js/src/utils/cheat_codes.ts | 5 ++- .../aztec.js/src/wallet/base_wallet.ts | 6 ++- .../src/guides/dapp_testing.test.ts | 8 +++- yarn-project/pxe/src/database/database.ts | 4 +- yarn-project/pxe/src/database/index.ts | 1 - .../pxe/src/database/memory_db.test.ts | 14 +++++-- .../src/note_processor/note_processor.test.ts | 3 +- .../pxe/src/note_processor/note_processor.ts | 34 +++++++++++----- .../pxe/src/pxe_service/pxe_service.ts | 40 +++++++------------ .../pxe/src/simulator_oracle/index.ts | 2 +- yarn-project/types/src/interfaces/pxe.ts | 17 +------- yarn-project/types/src/mocks.ts | 2 +- 12 files changed, 68 insertions(+), 68 deletions(-) diff --git a/yarn-project/aztec.js/src/utils/cheat_codes.ts b/yarn-project/aztec.js/src/utils/cheat_codes.ts index 8abc6ba5ee9e..50769d37237d 100644 --- a/yarn-project/aztec.js/src/utils/cheat_codes.ts +++ b/yarn-project/aztec.js/src/utils/cheat_codes.ts @@ -287,7 +287,8 @@ export class AztecCheatCodes { * @param slot - The storage slot to lookup * @returns The notes stored at the given slot */ - public loadPrivate(owner: AztecAddress, contract: AztecAddress, slot: Fr | bigint): Promise { - return this.pxe.getPrivateStorageAt(owner, contract, new Fr(slot)); + public async loadPrivate(owner: AztecAddress, contract: AztecAddress, slot: Fr | bigint): Promise { + const notes = await this.pxe.getNotes({ owner, contractAddress: contract, storageSlot: new Fr(slot) }); + return notes.map(note => note.notePreimage); } } diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index 6b215ee3ea6f..e65db4aefbd7 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -9,7 +9,9 @@ import { L2Tx, LogFilter, NodeInfo, + NoteFilter, NotePreimage, + NoteSpendingInfoDao, PXE, SyncStatus, Tx, @@ -69,8 +71,8 @@ export abstract class BaseWallet implements Wallet { getTxReceipt(txHash: TxHash): Promise { return this.pxe.getTxReceipt(txHash); } - getPrivateStorageAt(owner: AztecAddress, contract: AztecAddress, storageSlot: Fr): Promise { - return this.pxe.getPrivateStorageAt(owner, contract, storageSlot); + getNotes(filter: NoteFilter): Promise { + return this.pxe.getNotes(filter); } getPublicStorageAt(contract: AztecAddress, storageSlot: Fr): Promise { return this.pxe.getPublicStorageAt(contract, storageSlot); diff --git a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts index 92d3ed69e26c..61b5d7484471 100644 --- a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts +++ b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts @@ -186,8 +186,12 @@ describe('guides/dapp/testing', () => { it('checks private storage', async () => { // docs:start:private-storage - const notes = await pxe.getPrivateStorageAt(owner.getAddress(), token.address, ownerSlot); - const values = notes.map(note => note.items[0]); + const notes = await pxe.getNotes({ + owner: owner.getAddress(), + contractAddress: token.address, + storageSlot: ownerSlot, + }); + const values = notes.map(note => note.notePreimage.items[0]); const balance = values.reduce((sum, current) => sum + current.toBigInt(), 0n); expect(balance).toEqual(100n); // docs:end:private-storage diff --git a/yarn-project/pxe/src/database/database.ts b/yarn-project/pxe/src/database/database.ts index e53e514a3610..c0c0812662d4 100644 --- a/yarn-project/pxe/src/database/database.ts +++ b/yarn-project/pxe/src/database/database.ts @@ -1,9 +1,7 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { ContractDatabase, MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; - -import { NoteSpendingInfoDao } from './note_spending_info_dao.js'; +import { ContractDatabase, MerkleTreeId, NoteFilter, NoteSpendingInfoDao, PublicKey } from '@aztec/types'; /** * A database interface that provides methods for retrieving, adding, and removing transactional data related to Aztec diff --git a/yarn-project/pxe/src/database/index.ts b/yarn-project/pxe/src/database/index.ts index 0e59d6da7cd7..d1306dbafe06 100644 --- a/yarn-project/pxe/src/database/index.ts +++ b/yarn-project/pxe/src/database/index.ts @@ -1,3 +1,2 @@ export * from './database.js'; export * from './memory_db.js'; -export * from './note_spending_info_dao.js'; diff --git a/yarn-project/pxe/src/database/memory_db.test.ts b/yarn-project/pxe/src/database/memory_db.test.ts index 6188a6696a13..457b4ed530c3 100644 --- a/yarn-project/pxe/src/database/memory_db.test.ts +++ b/yarn-project/pxe/src/database/memory_db.test.ts @@ -1,7 +1,7 @@ import { AztecAddress, Fr } from '@aztec/circuits.js'; +import { NoteSpendingInfoDao, randomNoteSpendingInfoDao } from '@aztec/types'; import { MemoryDB } from './memory_db.js'; -import { NoteSpendingInfoDao, randomNoteSpendingInfoDao } from './note_spending_info_dao.js'; describe('Memory DB', () => { let db: MemoryDB; @@ -33,7 +33,10 @@ describe('Memory DB', () => { } for (let i = 0; i < notes.length; ++i) { - const result = await db.getNoteSpendingInfo(notes[i].contractAddress, notes[i].storageSlot); + const result = await db.getNoteSpendingInfo({ + contractAddress: notes[i].contractAddress, + storageSlot: notes[i].storageSlot, + }); expect(result).toEqual([notes[i]]); } }); @@ -43,7 +46,10 @@ describe('Memory DB', () => { await db.addNoteSpendingInfoBatch(notes); for (let i = 0; i < notes.length; ++i) { - const result = await db.getNoteSpendingInfo(notes[i].contractAddress, notes[i].storageSlot); + const result = await db.getNoteSpendingInfo({ + contractAddress: notes[i].contractAddress, + storageSlot: notes[i].storageSlot, + }); expect(result).toEqual([notes[i]]); } }); @@ -52,7 +58,7 @@ describe('Memory DB', () => { const notes = createNotes(3); await db.addNoteSpendingInfoBatch(notes); - const result = await db.getNoteSpendingInfo(contractAddress, storageSlot); + const result = await db.getNoteSpendingInfo({ contractAddress, storageSlot }); expect(result.length).toBe(notes.length); expect(result).toEqual(expect.objectContaining(notes)); }); 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 00e1018b37c0..0df089a30133 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -13,13 +13,14 @@ import { L2BlockContext, L2BlockL2Logs, NoteSpendingInfo, + NoteSpendingInfoDao, TxL2Logs, } from '@aztec/types'; import { jest } from '@jest/globals'; import { MockProxy, mock } from 'jest-mock-extended'; -import { Database, MemoryDB, NoteSpendingInfoDao } from '../database/index.js'; +import { Database, MemoryDB } from '../database/index.js'; import { NoteProcessor } from './note_processor.js'; const TXS_PER_BLOCK = 4; diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index df01d2b6abeb..e926191e077c 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -4,10 +4,18 @@ import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; -import { AztecNode, KeyStore, L2BlockContext, L2BlockL2Logs, NoteSpendingInfo, PublicKey } from '@aztec/types'; +import { + AztecNode, + KeyStore, + L2BlockContext, + L2BlockL2Logs, + NoteSpendingInfo, + NoteSpendingInfoDao, + PublicKey, +} from '@aztec/types'; import { NoteProcessorStats } from '@aztec/types/stats'; -import { Database, NoteSpendingInfoDao } from '../database/index.js'; +import { Database } from '../database/index.js'; import { getAcirSimulator } from '../simulator/index.js'; /** @@ -139,15 +147,19 @@ export class NoteProcessor { ); const index = BigInt(dataStartIndexForTx + commitmentIndex); excludedIndices.add(commitmentIndex); - noteSpendingInfoDaos.push({ - ...noteSpendingInfo, - nonce, - innerNoteHash, - siloedNullifier, - index, - publicKey: this.publicKey, - txHash: blockContext.getTxHash(indexOfTxInABlock), - }); + noteSpendingInfoDaos.push( + new NoteSpendingInfoDao( + noteSpendingInfo.notePreimage, + noteSpendingInfo.contractAddress, + blockContext.getTxHash(indexOfTxInABlock), + nonce, + noteSpendingInfo.storageSlot, + innerNoteHash, + siloedNullifier, + index, + this.publicKey, + ), + ); this.stats.decrypted++; } catch (e) { this.stats.failed++; diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 07c8afd19cfd..efe7990eb344 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -40,7 +40,7 @@ import { NodeInfo, NoteFilter, NotePreimage, - NoteSpendingInfo, + NoteSpendingInfoDao, PXE, SimulationError, Tx, @@ -194,19 +194,7 @@ export class PXEService implements PXE { return await this.node.getPublicStorageAt(contract, storageSlot.value); } - public async getPrivateStorageAt(owner: AztecAddress, contract: AztecAddress, storageSlot: Fr) { - if ((await this.getContractData(contract)) === undefined) { - throw new Error(`Contract ${contract.toString()} is not deployed`); - } - const notes = await this.db.getNoteSpendingInfo(contract, storageSlot); - const ownerCompleteAddress = await this.db.getCompleteAddress(owner); - if (!ownerCompleteAddress) throw new Error(`Owner ${owner} not registered in PXE`); - const { publicKey: ownerPublicKey } = ownerCompleteAddress; - const ownerNotes = notes.filter(n => n.publicKey.equals(ownerPublicKey)); - return ownerNotes.map(n => n.notePreimage); - } - - public async getNotes(filter: NoteFilter): Promise { + public async getNotes(filter: NoteFilter): Promise { return await this.db.getNoteSpendingInfo(filter); } @@ -248,17 +236,19 @@ export class PXEService implements PXE { throw new Error('The note has been destroyed.'); } - await this.db.addNoteSpendingInfo({ - contractAddress, - txHash, - storageSlot, - notePreimage: preimage, - nonce, - innerNoteHash, - siloedNullifier, - index, - publicKey, - }); + await this.db.addNoteSpendingInfo( + new NoteSpendingInfoDao( + preimage, + contractAddress, + txHash, + nonce, + storageSlot, + innerNoteHash, + siloedNullifier, + index, + publicKey, + ), + ); } public async getNoteNonces( diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 720df507636e..78e0d1980336 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -45,7 +45,7 @@ export class SimulatorOracle implements DBOracle { } async getNotes(contractAddress: AztecAddress, storageSlot: Fr) { - const noteDaos = await this.db.getNoteSpendingInfo(contractAddress, storageSlot); + const noteDaos = await this.db.getNoteSpendingInfo({ contractAddress, storageSlot }); return noteDaos.map( ({ contractAddress, storageSlot, nonce, notePreimage, innerNoteHash, siloedNullifier, index }) => ({ contractAddress, diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index 7c32ed4aaba4..d45f42e0bae4 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -8,7 +8,7 @@ import { L2Tx, LogFilter, NotePreimage, - NoteSpendingInfo, + NoteSpendingInfoDao, Tx, TxExecutionRequest, TxHash, @@ -150,19 +150,6 @@ export interface PXE { */ getTx(txHash: TxHash): Promise; - /** - * Retrieves the private storage data at a specified contract address and storage slot. Returns only data - * encrypted for the specified owner that has been already decrypted by the PXE Service. Note that there - * may be multiple notes for a user in a single slot. - * - * @param owner - The address for whom the private data is encrypted. - * @param contract - The AztecAddress of the target contract. - * @param storageSlot - The storage slot to be fetched. - * @returns A set of note preimages for the owner in that contract and slot. - * @throws If the contract is not deployed. - */ - getPrivateStorageAt(owner: AztecAddress, contract: AztecAddress, storageSlot: Fr): Promise; - /** * Retrieves the public storage data at a specified contract address and storage slot. * @@ -178,7 +165,7 @@ export interface PXE { * @param filter - The filter to apply to the notes. * @returns The requested notes. */ - getNotes(filter: NoteFilter): Promise; + getNotes(filter: NoteFilter): Promise; /** * Adds a note to the database. Throw if the note hash of the note doesn't exist in the tree. diff --git a/yarn-project/types/src/mocks.ts b/yarn-project/types/src/mocks.ts index 6da0ba48587e..1f8ae07aa7d2 100644 --- a/yarn-project/types/src/mocks.ts +++ b/yarn-project/types/src/mocks.ts @@ -73,11 +73,11 @@ export const randomNoteSpendingInfoDao = ( publicKey = Point.random(), ) => { return new NoteSpendingInfoDao( + notePreimage, contractAddress, txHash, nonce, storageSlot, - notePreimage, innerNoteHash, siloedNullifier, index, From 724d6cd6fdd21ca3691e18245eb2eb245b86855c Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 10:25:49 +0000 Subject: [PATCH 06/41] fix --- yarn-project/types/src/mocks.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn-project/types/src/mocks.ts b/yarn-project/types/src/mocks.ts index 1f8ae07aa7d2..4d9954a48f88 100644 --- a/yarn-project/types/src/mocks.ts +++ b/yarn-project/types/src/mocks.ts @@ -61,17 +61,17 @@ export const randomDeployedContract = async (): Promise => ({ portalContract: EthAddress.random(), }); -export const randomNoteSpendingInfoDao = ( +export const randomNoteSpendingInfoDao = ({ + notePreimage = NotePreimage.random(), contractAddress = AztecAddress.random(), txHash = randomTxHash(), nonce = Fr.random(), storageSlot = Fr.random(), - notePreimage = NotePreimage.random(), innerNoteHash = Fr.random(), siloedNullifier = Fr.random(), index = Fr.random().value, publicKey = Point.random(), -) => { +}: Partial = {}) => { return new NoteSpendingInfoDao( notePreimage, contractAddress, From d3f64889898bb4300ecac637675687d0da6f5883 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 11:23:50 +0000 Subject: [PATCH 07/41] fix --- yarn-project/aztec.js/src/pxe_client.ts | 2 ++ yarn-project/pxe/src/pxe_http/pxe_http_server.ts | 2 ++ yarn-project/types/src/notes/note_spending_info_dao.ts | 9 +++++++++ 3 files changed, 13 insertions(+) diff --git a/yarn-project/aztec.js/src/pxe_client.ts b/yarn-project/aztec.js/src/pxe_client.ts index 4e03af4ffbce..c5c784f533e7 100644 --- a/yarn-project/aztec.js/src/pxe_client.ts +++ b/yarn-project/aztec.js/src/pxe_client.ts @@ -17,6 +17,7 @@ import { L2Tx, LogId, NotePreimage, + NoteSpendingInfoDao, PXE, Tx, TxExecutionRequest, @@ -43,6 +44,7 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], true)) Fr, GrumpkinScalar, NotePreimage, + NoteSpendingInfoDao, AuthWitness, L2Tx, LogId, 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 64eb01c1f56f..c6b4b63e18fa 100644 --- a/yarn-project/pxe/src/pxe_http/pxe_http_server.ts +++ b/yarn-project/pxe/src/pxe_http/pxe_http_server.ts @@ -13,6 +13,7 @@ import { L2Tx, LogId, NotePreimage, + NoteSpendingInfoDao, PXE, Tx, TxExecutionRequest, @@ -48,6 +49,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer { Fr, GrumpkinScalar, NotePreimage, + NoteSpendingInfoDao, AuthWitness, L2Block, L2Tx, diff --git a/yarn-project/types/src/notes/note_spending_info_dao.ts b/yarn-project/types/src/notes/note_spending_info_dao.ts index ced6721aad6a..fd30772de60d 100644 --- a/yarn-project/types/src/notes/note_spending_info_dao.ts +++ b/yarn-project/types/src/notes/note_spending_info_dao.ts @@ -77,6 +77,15 @@ export class NoteSpendingInfoDao { ); } + toString() { + return '0x' + this.toBuffer().toString('hex'); + } + + static fromString(str: string) { + const hex = str.replace(/^0x/, ''); + return NotePreimage.fromBuffer(Buffer.from(hex, 'hex')); + } + /** * Returns the size in bytes of a note spending info dao. * @param note - The note. From 06ba89085a3a420f946fcdbfd81b4d464c611a65 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 12:02:21 +0000 Subject: [PATCH 08/41] serialization test --- .../types/src/notes/note_spending_info_dao.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 yarn-project/types/src/notes/note_spending_info_dao.test.ts diff --git a/yarn-project/types/src/notes/note_spending_info_dao.test.ts b/yarn-project/types/src/notes/note_spending_info_dao.test.ts new file mode 100644 index 000000000000..deb07f9fc77a --- /dev/null +++ b/yarn-project/types/src/notes/note_spending_info_dao.test.ts @@ -0,0 +1,10 @@ +import { randomNoteSpendingInfoDao } from '../mocks.js'; +import { NoteSpendingInfoDao } from './note_spending_info_dao.js'; + +describe('note_spending_info', () => { + it('convert to and from buffer', () => { + const noteSpendingInfoDao = randomNoteSpendingInfoDao(); + const buf = noteSpendingInfoDao.toBuffer(); + expect(NoteSpendingInfoDao.fromBuffer(buf)).toEqual(noteSpendingInfoDao); + }); +}); From 826aa1aae38e0cd9dbca0389157cc6e6c05f6e23 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 12:57:57 +0000 Subject: [PATCH 09/41] including notes in receipt --- yarn-project/aztec.js/src/contract/sent_tx.ts | 18 +++++++++++++++++- yarn-project/types/src/tx/tx_receipt.ts | 6 +++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/yarn-project/aztec.js/src/contract/sent_tx.ts b/yarn-project/aztec.js/src/contract/sent_tx.ts index f61f2d669faa..437c0777b7c9 100644 --- a/yarn-project/aztec.js/src/contract/sent_tx.ts +++ b/yarn-project/aztec.js/src/contract/sent_tx.ts @@ -1,6 +1,6 @@ import { FieldsOf } from '@aztec/circuits.js'; import { retryUntil } from '@aztec/foundation/retry'; -import { GetUnencryptedLogsResponse, PXE, TxHash, TxReceipt, TxStatus } from '@aztec/types'; +import { GetUnencryptedLogsResponse, NoteSpendingInfoDao, PXE, TxHash, TxReceipt, TxStatus } from '@aztec/types'; import every from 'lodash.every'; @@ -15,12 +15,15 @@ export type WaitOpts = { * If false, then any queries that depend on state set by this transaction may return stale data. Defaults to true. **/ waitForNotesSync?: boolean; + /** Whether newly created notes should be included in the receipt. */ + getNotes?: boolean; }; const DefaultWaitOpts: WaitOpts = { timeout: 60, interval: 1, waitForNotesSync: true, + getNotes: false, }; /** @@ -61,6 +64,9 @@ export class SentTx { const receipt = await this.waitForReceipt(opts); if (receipt.status !== TxStatus.MINED) throw new Error(`Transaction ${await this.getTxHash()} was ${receipt.status}`); + if (opts?.getNotes) { + receipt.notes = await this.pxe.getNotes({ txHash: await this.getTxHash() }); + } return receipt; } @@ -74,6 +80,16 @@ export class SentTx { return this.pxe.getUnencryptedLogs({ txHash: await this.getTxHash() }); } + /** + * Gets notes created in this tx. + * @remarks This function will wait for the tx to be mined if it hasn't been already. + * @returns The requested notes. + */ + public async getNotes(): Promise { + await this.wait(); + return this.pxe.getNotes({ txHash: await this.getTxHash() }); + } + protected async waitForReceipt(opts?: WaitOpts): Promise { const txHash = await this.getTxHash(); return await retryUntil( diff --git a/yarn-project/types/src/tx/tx_receipt.ts b/yarn-project/types/src/tx/tx_receipt.ts index 5d2a167b3753..7a27d16d05fb 100644 --- a/yarn-project/types/src/tx/tx_receipt.ts +++ b/yarn-project/types/src/tx/tx_receipt.ts @@ -1,5 +1,5 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; -import { TxHash } from '@aztec/types'; +import { NoteSpendingInfoDao, TxHash } from '@aztec/types'; /** * Possible status of a transaction. @@ -40,6 +40,10 @@ export class TxReceipt { * The deployed contract's address. */ public contractAddress?: AztecAddress, + /** + * Notes created in this tx. + */ + public notes?: NoteSpendingInfoDao[], ) {} /** From 6b2de274798a564edb692c446d34d144fca55cfa Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 12:59:20 +0000 Subject: [PATCH 10/41] checking whether the a note wsa created using getNotes --- yarn-project/end-to-end/src/e2e_token_contract.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/e2e_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_token_contract.test.ts index 9fa8c8ce8ea6..58e7e5bf0020 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract.test.ts @@ -168,9 +168,13 @@ describe('e2e_token_contract', () => { it('redeem as recipient', async () => { await addPendingShieldNoteToPXE(0, amount, secretHash, txHash); const txClaim = asset.methods.redeem_shield(accounts[0].address, amount, secret).send(); - const receiptClaim = await txClaim.wait(); + const receiptClaim = await txClaim.wait({ getNotes: true }); expect(receiptClaim.status).toBe(TxStatus.MINED); tokenSim.redeemShield(accounts[0].address, amount); + // 1 note should be created containing `amount` of tokens + const notes = receiptClaim.notes!; + expect(notes.length).toBe(1); + expect(notes[0].notePreimage.items[0].toBigInt()).toBe(amount); }); }); From 5724b82b8d938dc2cc33055edec45638fb770922 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 13:34:16 +0000 Subject: [PATCH 11/41] fix --- yarn-project/types/src/notes/note_spending_info_dao.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/types/src/notes/note_spending_info_dao.ts b/yarn-project/types/src/notes/note_spending_info_dao.ts index fd30772de60d..57733a79ed22 100644 --- a/yarn-project/types/src/notes/note_spending_info_dao.ts +++ b/yarn-project/types/src/notes/note_spending_info_dao.ts @@ -83,7 +83,7 @@ export class NoteSpendingInfoDao { static fromString(str: string) { const hex = str.replace(/^0x/, ''); - return NotePreimage.fromBuffer(Buffer.from(hex, 'hex')); + return NoteSpendingInfoDao.fromBuffer(Buffer.from(hex, 'hex')); } /** From 29102c7acb7e18c3194174ad0b25e62daccf1638 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 13:54:42 +0000 Subject: [PATCH 12/41] refactor: NoteSpendingInfoDao --> ExtendedNote --- yarn-project/aztec.js/src/contract/sent_tx.ts | 4 +-- yarn-project/aztec.js/src/pxe_client.ts | 4 +-- .../aztec.js/src/wallet/base_wallet.ts | 4 +-- yarn-project/pxe/src/database/database.ts | 31 +++++++------------ .../pxe/src/database/memory_db.test.ts | 18 +++++------ yarn-project/pxe/src/database/memory_db.ts | 26 ++++++++-------- .../src/note_processor/note_processor.test.ts | 18 +++++------ .../pxe/src/note_processor/note_processor.ts | 24 +++++++------- .../pxe/src/pxe_http/pxe_http_server.ts | 4 +-- .../pxe/src/pxe_service/pxe_service.ts | 10 +++--- .../pxe/src/simulator_oracle/index.ts | 2 +- yarn-project/types/src/interfaces/pxe.ts | 4 +-- yarn-project/types/src/mocks.ts | 8 ++--- .../types/src/notes/extended_note.test.ts | 10 ++++++ ..._spending_info_dao.ts => extended_note.ts} | 10 +++--- yarn-project/types/src/notes/index.ts | 2 +- .../src/notes/note_spending_info_dao.test.ts | 10 ------ yarn-project/types/src/tx/tx_receipt.ts | 4 +-- 18 files changed, 92 insertions(+), 101 deletions(-) create mode 100644 yarn-project/types/src/notes/extended_note.test.ts rename yarn-project/types/src/notes/{note_spending_info_dao.ts => extended_note.ts} (88%) delete mode 100644 yarn-project/types/src/notes/note_spending_info_dao.test.ts diff --git a/yarn-project/aztec.js/src/contract/sent_tx.ts b/yarn-project/aztec.js/src/contract/sent_tx.ts index 437c0777b7c9..2e617f4724fb 100644 --- a/yarn-project/aztec.js/src/contract/sent_tx.ts +++ b/yarn-project/aztec.js/src/contract/sent_tx.ts @@ -1,6 +1,6 @@ import { FieldsOf } from '@aztec/circuits.js'; import { retryUntil } from '@aztec/foundation/retry'; -import { GetUnencryptedLogsResponse, NoteSpendingInfoDao, PXE, TxHash, TxReceipt, TxStatus } from '@aztec/types'; +import { ExtendedNote, GetUnencryptedLogsResponse, PXE, TxHash, TxReceipt, TxStatus } from '@aztec/types'; import every from 'lodash.every'; @@ -85,7 +85,7 @@ export class SentTx { * @remarks This function will wait for the tx to be mined if it hasn't been already. * @returns The requested notes. */ - public async getNotes(): Promise { + public async getNotes(): Promise { await this.wait(); return this.pxe.getNotes({ txHash: await this.getTxHash() }); } diff --git a/yarn-project/aztec.js/src/pxe_client.ts b/yarn-project/aztec.js/src/pxe_client.ts index c5c784f533e7..7c0d4c29edc2 100644 --- a/yarn-project/aztec.js/src/pxe_client.ts +++ b/yarn-project/aztec.js/src/pxe_client.ts @@ -12,12 +12,12 @@ import { AuthWitness, ContractData, ExtendedContractData, + ExtendedNote, ExtendedUnencryptedL2Log, L2BlockL2Logs, L2Tx, LogId, NotePreimage, - NoteSpendingInfoDao, PXE, Tx, TxExecutionRequest, @@ -44,7 +44,7 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], true)) Fr, GrumpkinScalar, NotePreimage, - NoteSpendingInfoDao, + ExtendedNote, AuthWitness, L2Tx, LogId, diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index e65db4aefbd7..4a412f854b06 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -4,6 +4,7 @@ import { ContractData, DeployedContract, ExtendedContractData, + ExtendedNote, FunctionCall, GetUnencryptedLogsResponse, L2Tx, @@ -11,7 +12,6 @@ import { NodeInfo, NoteFilter, NotePreimage, - NoteSpendingInfoDao, PXE, SyncStatus, Tx, @@ -71,7 +71,7 @@ export abstract class BaseWallet implements Wallet { getTxReceipt(txHash: TxHash): Promise { return this.pxe.getTxReceipt(txHash); } - getNotes(filter: NoteFilter): Promise { + getNotes(filter: NoteFilter): Promise { return this.pxe.getNotes(filter); } getPublicStorageAt(contract: AztecAddress, storageSlot: Fr): Promise { diff --git a/yarn-project/pxe/src/database/database.ts b/yarn-project/pxe/src/database/database.ts index c0c0812662d4..b94d1c7016f6 100644 --- a/yarn-project/pxe/src/database/database.ts +++ b/yarn-project/pxe/src/database/database.ts @@ -1,7 +1,7 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { ContractDatabase, MerkleTreeId, NoteFilter, NoteSpendingInfoDao, PublicKey } from '@aztec/types'; +import { ContractDatabase, ExtendedNote, MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; /** * A database interface that provides methods for retrieving, adding, and removing transactional data related to Aztec @@ -27,38 +27,31 @@ export interface Database extends ContractDatabase { * @param filter - The filter to apply to the notes. * @returns The requested notes. */ - getNoteSpendingInfo(filter: NoteFilter): Promise; + getExtendedNotes(filter: NoteFilter): Promise; /** - * Add a NoteSpendingInfoDao instance to the noteSpendingInfoTable. - * This function is used to store auxiliary data related to a transaction, - * such as contract address and storage slot, in the database. - * - * @param noteSpendingInfoDao - The NoteSpendingInfoDao instance containing the auxiliary data of a transaction. - * @returns A promise that resolves when the auxiliary data is added to the database. + * Adds ExtendedNote to DB. + * @param extendedNote - The note to add. */ - addNoteSpendingInfo(noteSpendingInfoDao: NoteSpendingInfoDao): Promise; + addExtendedNote(extendedNote: ExtendedNote): Promise; /** - * Adds an array of NoteSpendingInfoDaos to the noteSpendingInfoTable. - * This function is used to insert multiple transaction auxiliary data objects into the database at once, + * Adds an array of ExtendedNotes. + * This function is used to insert multiple extended notes to the database at once, * which can improve performance when dealing with large numbers of transactions. * - * @param noteSpendingInfoDaos - An array of NoteSpendingInfoDao instances representing the auxiliary data of transactions. - * @returns A Promise that resolves when all NoteSpendingInfoDaos have been successfully added to the noteSpendingInfoTable. + * @param extendedNotes - An array of ExtendedNote instances. */ - addNoteSpendingInfoBatch(noteSpendingInfoDaos: NoteSpendingInfoDao[]): Promise; + addExtendedNotes(extendedNotes: ExtendedNote[]): Promise; /** - * Remove nullified transaction auxiliary data records associated with the given account and nullifiers. - * The function filters the records based on matching account and nullifier values, and updates the - * noteSpendingInfoTable with the remaining records. It returns an array of removed NoteSpendingInfoDao instances. + * Remove nullified notes associated with the given account and nullifiers. * * @param nullifiers - An array of Fr instances representing nullifiers to be matched. * @param account - A PublicKey instance representing the account for which the records are being removed. - * @returns A Promise resolved with an array of removed NoteSpendingInfoDao instances. + * @returns Removed notes. */ - removeNullifiedNoteSpendingInfo(nullifiers: Fr[], account: PublicKey): Promise; + removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise; /** * Retrieve the stored Merkle tree roots from the database. diff --git a/yarn-project/pxe/src/database/memory_db.test.ts b/yarn-project/pxe/src/database/memory_db.test.ts index 457b4ed530c3..cc6f92a1d46f 100644 --- a/yarn-project/pxe/src/database/memory_db.test.ts +++ b/yarn-project/pxe/src/database/memory_db.test.ts @@ -1,5 +1,5 @@ import { AztecAddress, Fr } from '@aztec/circuits.js'; -import { NoteSpendingInfoDao, randomNoteSpendingInfoDao } from '@aztec/types'; +import { ExtendedNote, randomExtendedNote } from '@aztec/types'; import { MemoryDB } from './memory_db.js'; @@ -14,8 +14,8 @@ describe('Memory DB', () => { const contractAddress = AztecAddress.random(); const storageSlot = Fr.random(); - const createNote = (attributes: Partial = {}, sameStorage = true) => - randomNoteSpendingInfoDao({ + const createNote = (attributes: Partial = {}, sameStorage = true) => + randomExtendedNote({ ...attributes, contractAddress: sameStorage ? contractAddress : AztecAddress.random(), storageSlot: sameStorage ? storageSlot : Fr.random(), @@ -29,11 +29,11 @@ describe('Memory DB', () => { it('should add and get notes', async () => { const notes = createNotes(3, false); for (let i = 0; i < notes.length; ++i) { - await db.addNoteSpendingInfo(notes[i]); + await db.addExtendedNote(notes[i]); } for (let i = 0; i < notes.length; ++i) { - const result = await db.getNoteSpendingInfo({ + const result = await db.getExtendedNotes({ contractAddress: notes[i].contractAddress, storageSlot: notes[i].storageSlot, }); @@ -43,10 +43,10 @@ describe('Memory DB', () => { it('should batch add notes', async () => { const notes = createNotes(3, false); - await db.addNoteSpendingInfoBatch(notes); + await db.addExtendedNotes(notes); for (let i = 0; i < notes.length; ++i) { - const result = await db.getNoteSpendingInfo({ + const result = await db.getExtendedNotes({ contractAddress: notes[i].contractAddress, storageSlot: notes[i].storageSlot, }); @@ -56,9 +56,9 @@ describe('Memory DB', () => { it('should get all notes with the same contract storage slot', async () => { const notes = createNotes(3); - await db.addNoteSpendingInfoBatch(notes); + await db.addExtendedNotes(notes); - const result = await db.getNoteSpendingInfo({ contractAddress, storageSlot }); + const result = await db.getExtendedNotes({ contractAddress, storageSlot }); expect(result.length).toBe(notes.length); expect(result).toEqual(expect.objectContaining(notes)); }); diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 78b7591db696..40cfa2ca1ba3 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -2,7 +2,7 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { MerkleTreeId, NoteFilter, NoteSpendingInfoDao, PublicKey } from '@aztec/types'; +import { ExtendedNote, MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; import { MemoryContractDatabase } from '../contract_database/index.js'; import { Database } from './database.js'; @@ -14,7 +14,7 @@ import { Database } from './database.js'; * As an in-memory database, the stored data will not persist beyond the life of the application instance. */ export class MemoryDB extends MemoryContractDatabase implements Database { - private noteSpendingInfoTable: NoteSpendingInfoDao[] = []; + private extendedNotesTable: ExtendedNote[] = []; private treeRoots: Record | undefined; private globalVariablesHash: Fr | undefined; private addresses: CompleteAddress[] = []; @@ -43,17 +43,17 @@ export class MemoryDB extends MemoryContractDatabase implements Database { return Promise.resolve(this.authWitnesses[messageHash.toString()]); } - public addNoteSpendingInfo(noteSpendingInfoDao: NoteSpendingInfoDao) { - this.noteSpendingInfoTable.push(noteSpendingInfoDao); + public addExtendedNote(extendedNote: ExtendedNote) { + this.extendedNotesTable.push(extendedNote); return Promise.resolve(); } - public addNoteSpendingInfoBatch(noteSpendingInfoDaos: NoteSpendingInfoDao[]) { - this.noteSpendingInfoTable.push(...noteSpendingInfoDaos); + public addExtendedNotes(extendedNotes: ExtendedNote[]) { + this.extendedNotesTable.push(...extendedNotes); return Promise.resolve(); } - public async getNoteSpendingInfo(filter: NoteFilter): Promise { + public async getExtendedNotes(filter: NoteFilter): Promise { let ownerPublicKey: PublicKey | undefined; if (filter.owner !== undefined) { const ownerCompleteAddress = await this.getCompleteAddress(filter.owner); @@ -63,7 +63,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { ownerPublicKey = ownerCompleteAddress.publicKey; } - return this.noteSpendingInfoTable.filter( + return this.extendedNotesTable.filter( noteSpendingInfo => (filter.contractAddress == undefined || noteSpendingInfo.contractAddress.equals(filter.contractAddress)) && (filter.txHash == undefined || noteSpendingInfo.txHash.equals(filter.txHash)) && @@ -72,10 +72,10 @@ export class MemoryDB extends MemoryContractDatabase implements Database { ); } - public removeNullifiedNoteSpendingInfo(nullifiers: Fr[], account: PublicKey) { + public removeNullifiedNotes(nullifiers: Fr[], account: PublicKey) { const nullifierSet = new Set(nullifiers.map(nullifier => nullifier.toString())); - const [remaining, removed] = this.noteSpendingInfoTable.reduce( - (acc: [NoteSpendingInfoDao[], NoteSpendingInfoDao[]], noteSpendingInfo) => { + const [remaining, removed] = this.extendedNotesTable.reduce( + (acc: [ExtendedNote[], ExtendedNote[]], noteSpendingInfo) => { const nullifier = noteSpendingInfo.siloedNullifier.toString(); if (noteSpendingInfo.publicKey.equals(account) && nullifierSet.has(nullifier)) { acc[1].push(noteSpendingInfo); @@ -87,7 +87,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { [[], []], ); - this.noteSpendingInfoTable = remaining; + this.extendedNotesTable = remaining; return Promise.resolve(removed); } @@ -155,7 +155,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { } public estimateSize() { - const notesSize = this.noteSpendingInfoTable.reduce((sum, note) => sum + note.getSize(note), 0); + const notesSize = this.extendedNotesTable.reduce((sum, note) => sum + note.getSize(note), 0); const treeRootsSize = this.treeRoots ? Object.entries(this.treeRoots).length * Fr.SIZE_IN_BYTES : 0; const authWits = Object.entries(this.authWitnesses); const authWitsSize = authWits.reduce((sum, [key, value]) => sum + key.length + value.length * Fr.SIZE_IN_BYTES, 0); 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 0df089a30133..cee19c3f3697 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -5,6 +5,7 @@ import { Point } from '@aztec/foundation/fields'; import { ConstantKeyPair } from '@aztec/key-store'; import { AztecNode, + ExtendedNote, FunctionL2Logs, INITIAL_L2_BLOCK_NUM, KeyPair, @@ -13,7 +14,6 @@ import { L2BlockContext, L2BlockL2Logs, NoteSpendingInfo, - NoteSpendingInfoDao, TxL2Logs, } from '@aztec/types'; @@ -30,7 +30,7 @@ describe('Note Processor', () => { let grumpkin: Grumpkin; let database: Database; let aztecNode: ReturnType>; - let addNoteSpendingInfoBatchSpy: any; + let addExtendedNotesSpy: any; let noteProcessor: NoteProcessor; let owner: KeyPair; let keyStore: MockProxy; @@ -121,7 +121,7 @@ describe('Note Processor', () => { beforeEach(() => { database = new MemoryDB(); - addNoteSpendingInfoBatchSpy = jest.spyOn(database, 'addNoteSpendingInfoBatch'); + addExtendedNotesSpy = jest.spyOn(database, 'addExtendedNotes'); aztecNode = mock(); keyStore = mock(); @@ -147,15 +147,15 @@ describe('Note Processor', () => { }); afterEach(() => { - addNoteSpendingInfoBatchSpy.mockReset(); + addExtendedNotesSpy.mockReset(); }); it('should store a note that belongs to us', async () => { const { blockContexts, encryptedLogsArr, ownedNoteSpendingInfos } = mockData([[2]]); await noteProcessor.process(blockContexts, encryptedLogsArr); - expect(addNoteSpendingInfoBatchSpy).toHaveBeenCalledTimes(1); - expect(addNoteSpendingInfoBatchSpy).toHaveBeenCalledWith([ + expect(addExtendedNotesSpy).toHaveBeenCalledTimes(1); + expect(addExtendedNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ ...ownedNoteSpendingInfos[0], index: BigInt(firstBlockDataStartIndex + 2), @@ -175,8 +175,8 @@ describe('Note Processor', () => { ); await noteProcessor.process(blockContexts, encryptedLogsArr); - expect(addNoteSpendingInfoBatchSpy).toHaveBeenCalledTimes(1); - expect(addNoteSpendingInfoBatchSpy).toHaveBeenCalledWith([ + expect(addExtendedNotesSpy).toHaveBeenCalledTimes(1); + expect(addExtendedNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ ...ownedNoteSpendingInfos[0], // Index 1 log in the 2nd tx. @@ -208,7 +208,7 @@ describe('Note Processor', () => { const { blockContexts, encryptedLogsArr, ownedNoteSpendingInfos } = mockData([[0, 2], [], [0, 1, 3]], 0, 0, notes); await noteProcessor.process(blockContexts, encryptedLogsArr); - const addedInfos: NoteSpendingInfoDao[] = addNoteSpendingInfoBatchSpy.mock.calls[0][0]; + const addedInfos: ExtendedNote[] = addExtendedNotesSpy.mock.calls[0][0]; expect(addedInfos).toEqual([ expect.objectContaining({ ...ownedNoteSpendingInfos[0] }), expect.objectContaining({ ...ownedNoteSpendingInfos[1] }), diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index e926191e077c..6b03a306a7a0 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -6,11 +6,11 @@ import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; import { AztecNode, + ExtendedNote, KeyStore, L2BlockContext, L2BlockL2Logs, NoteSpendingInfo, - NoteSpendingInfoDao, PublicKey, } from '@aztec/types'; import { NoteProcessorStats } from '@aztec/types/stats'; @@ -29,7 +29,7 @@ interface ProcessedData { /** * A collection of data access objects for note spending info. */ - noteSpendingInfoDaos: NoteSpendingInfoDao[]; + extendedNotes: ExtendedNote[]; } /** @@ -113,7 +113,7 @@ export class NoteProcessor { // We are using set for `userPertainingTxIndices` to avoid duplicates. This would happen in case there were // multiple encrypted logs in a tx pertaining to a user. - const noteSpendingInfoDaos: NoteSpendingInfoDao[] = []; + const extendedNotes: ExtendedNote[] = []; const privateKey = await this.keyStore.getAccountPrivateKey(this.publicKey); // Iterate over all the encrypted logs and try decrypting them. If successful, store the note spending info. @@ -147,8 +147,8 @@ export class NoteProcessor { ); const index = BigInt(dataStartIndexForTx + commitmentIndex); excludedIndices.add(commitmentIndex); - noteSpendingInfoDaos.push( - new NoteSpendingInfoDao( + extendedNotes.push( + new ExtendedNote( noteSpendingInfo.notePreimage, noteSpendingInfo.contractAddress, blockContext.getTxHash(indexOfTxInABlock), @@ -172,7 +172,7 @@ export class NoteProcessor { blocksAndNoteSpendingInfo.push({ blockContext: l2BlockContexts[blockIndex], - noteSpendingInfoDaos, + extendedNotes, }); } @@ -267,13 +267,13 @@ https://github.com/AztecProtocol/aztec-packages/issues/1641`; * transaction auxiliary data from the database. This function keeps track of new nullifiers * and ensures all other transactions are updated with newly settled block information. * - * @param blocksAndNoteSpendingInfo - Array of objects containing L2BlockContexts, user-pertaining transaction indices, and NoteSpendingInfoDaos. + * @param blocksAndNoteSpendingInfo - Array of objects containing L2BlockContexts, user-pertaining transaction indices, and ExtendedNotes. */ private async processBlocksAndNoteSpendingInfo(blocksAndNoteSpendingInfo: ProcessedData[]) { - const noteSpendingInfoDaosBatch = blocksAndNoteSpendingInfo.flatMap(b => b.noteSpendingInfoDaos); - if (noteSpendingInfoDaosBatch.length) { - await this.db.addNoteSpendingInfoBatch(noteSpendingInfoDaosBatch); - noteSpendingInfoDaosBatch.forEach(noteSpendingInfo => { + const extendedNotesBatch = blocksAndNoteSpendingInfo.flatMap(b => b.extendedNotes); + if (extendedNotesBatch.length) { + await this.db.addExtendedNotes(extendedNotesBatch); + extendedNotesBatch.forEach(noteSpendingInfo => { this.log( `Added note spending info for contract ${noteSpendingInfo.contractAddress} at slot ${ noteSpendingInfo.storageSlot @@ -283,7 +283,7 @@ https://github.com/AztecProtocol/aztec-packages/issues/1641`; } const newNullifiers: Fr[] = blocksAndNoteSpendingInfo.flatMap(b => b.blockContext.block.newNullifiers); - const removedNoteSpendingInfo = await this.db.removeNullifiedNoteSpendingInfo(newNullifiers, this.publicKey); + const removedNoteSpendingInfo = await this.db.removeNullifiedNotes(newNullifiers, this.publicKey); removedNoteSpendingInfo.forEach(noteSpendingInfo => { this.log( `Removed note spending info for contract ${noteSpendingInfo.contractAddress} at slot ${ 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 c6b4b63e18fa..e41cdec28d96 100644 --- a/yarn-project/pxe/src/pxe_http/pxe_http_server.ts +++ b/yarn-project/pxe/src/pxe_http/pxe_http_server.ts @@ -7,13 +7,13 @@ import { CompleteAddress, ContractData, ExtendedContractData, + ExtendedNote, ExtendedUnencryptedL2Log, L2Block, L2BlockL2Logs, L2Tx, LogId, NotePreimage, - NoteSpendingInfoDao, PXE, Tx, TxExecutionRequest, @@ -49,7 +49,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer { Fr, GrumpkinScalar, NotePreimage, - NoteSpendingInfoDao, + ExtendedNote, AuthWitness, L2Block, L2Tx, diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index efe7990eb344..ec324e289e15 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -30,6 +30,7 @@ import { ContractData, DeployedContract, ExtendedContractData, + ExtendedNote, FunctionCall, GetUnencryptedLogsResponse, KeyStore, @@ -40,7 +41,6 @@ import { NodeInfo, NoteFilter, NotePreimage, - NoteSpendingInfoDao, PXE, SimulationError, Tx, @@ -194,8 +194,8 @@ export class PXEService implements PXE { return await this.node.getPublicStorageAt(contract, storageSlot.value); } - public async getNotes(filter: NoteFilter): Promise { - return await this.db.getNoteSpendingInfo(filter); + public async getNotes(filter: NoteFilter): Promise { + return await this.db.getExtendedNotes(filter); } public async addNote( @@ -236,8 +236,8 @@ export class PXEService implements PXE { throw new Error('The note has been destroyed.'); } - await this.db.addNoteSpendingInfo( - new NoteSpendingInfoDao( + await this.db.addExtendedNote( + new ExtendedNote( preimage, contractAddress, txHash, diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 78e0d1980336..7461ffa32e37 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -45,7 +45,7 @@ export class SimulatorOracle implements DBOracle { } async getNotes(contractAddress: AztecAddress, storageSlot: Fr) { - const noteDaos = await this.db.getNoteSpendingInfo({ contractAddress, storageSlot }); + const noteDaos = await this.db.getExtendedNotes({ contractAddress, storageSlot }); return noteDaos.map( ({ contractAddress, storageSlot, nonce, notePreimage, innerNoteHash, siloedNullifier, index }) => ({ contractAddress, diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index d45f42e0bae4..1c83d27b7c4e 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -4,11 +4,11 @@ import { CompleteAddress, ContractData, ExtendedContractData, + ExtendedNote, GetUnencryptedLogsResponse, L2Tx, LogFilter, NotePreimage, - NoteSpendingInfoDao, Tx, TxExecutionRequest, TxHash, @@ -165,7 +165,7 @@ export interface PXE { * @param filter - The filter to apply to the notes. * @returns The requested notes. */ - getNotes(filter: NoteFilter): Promise; + getNotes(filter: NoteFilter): Promise; /** * Adds a note to the database. Throw if the note hash of the note doesn't exist in the tree. diff --git a/yarn-project/types/src/mocks.ts b/yarn-project/types/src/mocks.ts index 4d9954a48f88..4d7078f6d6df 100644 --- a/yarn-project/types/src/mocks.ts +++ b/yarn-project/types/src/mocks.ts @@ -18,9 +18,9 @@ import times from 'lodash.times'; import { DeployedContract, ExtendedContractData, + ExtendedNote, FunctionL2Logs, NotePreimage, - NoteSpendingInfoDao, TxL2Logs, } from './index.js'; import { Tx, TxHash } from './tx/index.js'; @@ -61,7 +61,7 @@ export const randomDeployedContract = async (): Promise => ({ portalContract: EthAddress.random(), }); -export const randomNoteSpendingInfoDao = ({ +export const randomExtendedNote = ({ notePreimage = NotePreimage.random(), contractAddress = AztecAddress.random(), txHash = randomTxHash(), @@ -71,8 +71,8 @@ export const randomNoteSpendingInfoDao = ({ siloedNullifier = Fr.random(), index = Fr.random().value, publicKey = Point.random(), -}: Partial = {}) => { - return new NoteSpendingInfoDao( +}: Partial = {}) => { + return new ExtendedNote( notePreimage, contractAddress, txHash, diff --git a/yarn-project/types/src/notes/extended_note.test.ts b/yarn-project/types/src/notes/extended_note.test.ts new file mode 100644 index 000000000000..0b5f8c89edb6 --- /dev/null +++ b/yarn-project/types/src/notes/extended_note.test.ts @@ -0,0 +1,10 @@ +import { randomExtendedNote } from '../mocks.js'; +import { ExtendedNote } from './extended_note.js'; + +describe('Extended Note', () => { + it('convert to and from buffer', () => { + const extendedNote = randomExtendedNote(); + const buf = extendedNote.toBuffer(); + expect(ExtendedNote.fromBuffer(buf)).toEqual(extendedNote); + }); +}); diff --git a/yarn-project/types/src/notes/note_spending_info_dao.ts b/yarn-project/types/src/notes/extended_note.ts similarity index 88% rename from yarn-project/types/src/notes/note_spending_info_dao.ts rename to yarn-project/types/src/notes/extended_note.ts index 57733a79ed22..027b29baebbe 100644 --- a/yarn-project/types/src/notes/note_spending_info_dao.ts +++ b/yarn-project/types/src/notes/extended_note.ts @@ -3,11 +3,9 @@ import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; import { BufferReader, NotePreimage, TxHash } from '@aztec/types'; /** - * Represents the data access object for auxiliary transaction data. - * Contains properties from the decrypted note, computed properties, and information about - * the public key used for encryption, as well as the location of the data in the tree. + * A note with contextual data. */ -export class NoteSpendingInfoDao { +export class ExtendedNote { constructor( /** The preimage of the note, containing essential information about the note. */ public notePreimage: NotePreimage, @@ -83,7 +81,7 @@ export class NoteSpendingInfoDao { static fromString(str: string) { const hex = str.replace(/^0x/, ''); - return NoteSpendingInfoDao.fromBuffer(Buffer.from(hex, 'hex')); + return ExtendedNote.fromBuffer(Buffer.from(hex, 'hex')); } /** @@ -91,7 +89,7 @@ export class NoteSpendingInfoDao { * @param note - The note. * @returns - Its size in bytes. */ - public getSize(note: NoteSpendingInfoDao) { + public getSize(note: ExtendedNote) { // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer const indexSize = Math.ceil(Math.log2(Number(note.index))); return ( diff --git a/yarn-project/types/src/notes/index.ts b/yarn-project/types/src/notes/index.ts index 9729d89d4bb0..cba821999853 100644 --- a/yarn-project/types/src/notes/index.ts +++ b/yarn-project/types/src/notes/index.ts @@ -1,2 +1,2 @@ export * from './note_filter.js'; -export * from './note_spending_info_dao.js'; +export * from './extended_note.js'; diff --git a/yarn-project/types/src/notes/note_spending_info_dao.test.ts b/yarn-project/types/src/notes/note_spending_info_dao.test.ts deleted file mode 100644 index deb07f9fc77a..000000000000 --- a/yarn-project/types/src/notes/note_spending_info_dao.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { randomNoteSpendingInfoDao } from '../mocks.js'; -import { NoteSpendingInfoDao } from './note_spending_info_dao.js'; - -describe('note_spending_info', () => { - it('convert to and from buffer', () => { - const noteSpendingInfoDao = randomNoteSpendingInfoDao(); - const buf = noteSpendingInfoDao.toBuffer(); - expect(NoteSpendingInfoDao.fromBuffer(buf)).toEqual(noteSpendingInfoDao); - }); -}); diff --git a/yarn-project/types/src/tx/tx_receipt.ts b/yarn-project/types/src/tx/tx_receipt.ts index 7a27d16d05fb..a2df85aaf7fe 100644 --- a/yarn-project/types/src/tx/tx_receipt.ts +++ b/yarn-project/types/src/tx/tx_receipt.ts @@ -1,5 +1,5 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; -import { NoteSpendingInfoDao, TxHash } from '@aztec/types'; +import { ExtendedNote, TxHash } from '@aztec/types'; /** * Possible status of a transaction. @@ -43,7 +43,7 @@ export class TxReceipt { /** * Notes created in this tx. */ - public notes?: NoteSpendingInfoDao[], + public notes?: ExtendedNote[], ) {} /** From d44fb9c2ed09d39c47d34ee9554a1d88daa1e13e Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 14:02:04 +0000 Subject: [PATCH 13/41] refactor: NoteSpendingInfo -> L1NotePayload --- .../src/client/client_execution_context.ts | 4 +- .../src/note_processor/note_processor.test.ts | 18 ++++----- .../pxe/src/note_processor/note_processor.ts | 6 +-- .../src/logs/note_spending_info/index.ts | 2 +- .../l1_note_payload.test.ts | 38 +++++++++++++++++++ ...te_spending_info.ts => l1_note_payload.ts} | 15 ++++---- .../note_spending_info.test.ts | 38 ------------------- 7 files changed, 61 insertions(+), 60 deletions(-) create mode 100644 yarn-project/types/src/logs/note_spending_info/l1_note_payload.test.ts rename yarn-project/types/src/logs/note_spending_info/{note_spending_info.ts => l1_note_payload.ts} (83%) delete mode 100644 yarn-project/types/src/logs/note_spending_info/note_spending_info.test.ts diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 0b64bcfd3328..c2c3574930e4 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -15,7 +15,7 @@ import { FunctionAbi, FunctionArtifact, countArgumentsSize } from '@aztec/founda import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { AuthWitness, FunctionL2Logs, NotePreimage, NoteSpendingInfo, UnencryptedL2Log } from '@aztec/types'; +import { AuthWitness, FunctionL2Logs, L1NotePayload, NotePreimage, UnencryptedL2Log } from '@aztec/types'; import { NoteData, @@ -289,7 +289,7 @@ export class ClientExecutionContext extends ViewDataOracle { */ public emitEncryptedLog(contractAddress: AztecAddress, storageSlot: Fr, publicKey: Point, preimage: Fr[]) { const notePreimage = new NotePreimage(preimage); - const noteSpendingInfo = new NoteSpendingInfo(notePreimage, contractAddress, storageSlot); + const noteSpendingInfo = new L1NotePayload(notePreimage, contractAddress, storageSlot); const encryptedNotePreimage = noteSpendingInfo.toEncryptedBuffer(publicKey, this.curve); this.encryptedLogs.push(encryptedNotePreimage); } 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 cee19c3f3697..bfd8dc142591 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -10,10 +10,10 @@ import { INITIAL_L2_BLOCK_NUM, KeyPair, KeyStore, + L1NotePayload, L2Block, L2BlockContext, L2BlockL2Logs, - NoteSpendingInfo, TxL2Logs, } from '@aztec/types'; @@ -48,9 +48,9 @@ describe('Note Processor', () => { ); // ownedData: [tx1, tx2, ...], the numbers in each tx represents the indices of the note hashes the account owns. - const createEncryptedLogsAndOwnedNoteSpendingInfo = (ownedData: number[][], ownedNotes: NoteSpendingInfo[]) => { - const newNotes: NoteSpendingInfo[] = []; - const ownedNoteSpendingInfo: NoteSpendingInfo[] = []; + const createEncryptedLogsAndOwnedNoteSpendingInfo = (ownedData: number[][], ownedNotes: L1NotePayload[]) => { + const newNotes: L1NotePayload[] = []; + const ownedNoteSpendingInfo: L1NotePayload[] = []; const txLogs: TxL2Logs[] = []; let usedOwnedNote = 0; for (let i = 0; i < TXS_PER_BLOCK; ++i) { @@ -63,7 +63,7 @@ describe('Note Processor', () => { for (let noteIndex = 0; noteIndex < MAX_NEW_COMMITMENTS_PER_TX; ++noteIndex) { const isOwner = ownedDataIndices.includes(noteIndex); const publicKey = isOwner ? owner.getPublicKey() : Point.random(); - const note = (isOwner && ownedNotes[usedOwnedNote]) || NoteSpendingInfo.random(); + const note = (isOwner && ownedNotes[usedOwnedNote]) || L1NotePayload.random(); usedOwnedNote += note === ownedNotes[usedOwnedNote] ? 1 : 0; newNotes.push(note); if (isOwner) { @@ -84,7 +84,7 @@ describe('Note Processor', () => { ownedData: number[][], prependedBlocks = 0, appendedBlocks = 0, - ownedNotes: NoteSpendingInfo[] = [], + ownedNotes: L1NotePayload[] = [], ) => { if (ownedData.length > TXS_PER_BLOCK) { throw new Error(`Tx size should be less than ${TXS_PER_BLOCK}.`); @@ -92,7 +92,7 @@ describe('Note Processor', () => { const blockContexts: L2BlockContext[] = []; const encryptedLogsArr: L2BlockL2Logs[] = []; - const ownedNoteSpendingInfos: NoteSpendingInfo[] = []; + const ownedNoteSpendingInfos: L1NotePayload[] = []; const numberOfBlocks = prependedBlocks + appendedBlocks + 1; for (let i = 0; i < numberOfBlocks; ++i) { const block = L2Block.random(firstBlockNum + i, TXS_PER_BLOCK); @@ -201,8 +201,8 @@ describe('Note Processor', () => { }); it('should be able to recover two notes with the same preimage', async () => { - const note = NoteSpendingInfo.random(); - const note2 = NoteSpendingInfo.random(); + const note = L1NotePayload.random(); + const note2 = L1NotePayload.random(); // All notes expect one have the same contract address, storage slot, and preimage. const notes = [note, note, note, note2, note]; const { blockContexts, encryptedLogsArr, ownedNoteSpendingInfos } = mockData([[0, 2], [], [0, 1, 3]], 0, 0, notes); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 6b03a306a7a0..79397b7feb73 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -8,9 +8,9 @@ import { AztecNode, ExtendedNote, KeyStore, + L1NotePayload, L2BlockContext, L2BlockL2Logs, - NoteSpendingInfo, PublicKey, } from '@aztec/types'; import { NoteProcessorStats } from '@aztec/types/stats'; @@ -135,7 +135,7 @@ export class NoteProcessor { for (const functionLogs of txFunctionLogs) { for (const logs of functionLogs.logs) { this.stats.seen++; - const noteSpendingInfo = NoteSpendingInfo.fromEncryptedBuffer(logs, privateKey, curve); + const noteSpendingInfo = L1NotePayload.fromEncryptedBuffer(logs, privateKey, curve); if (noteSpendingInfo) { // We have successfully decrypted the data. try { @@ -200,7 +200,7 @@ export class NoteProcessor { private async findNoteIndexAndNullifier( commitments: Fr[], firstNullifier: Fr, - { contractAddress, storageSlot, notePreimage }: NoteSpendingInfo, + { contractAddress, storageSlot, notePreimage }: L1NotePayload, excludedIndices: Set, ) { const wasm = await CircuitsWasm.get(); diff --git a/yarn-project/types/src/logs/note_spending_info/index.ts b/yarn-project/types/src/logs/note_spending_info/index.ts index 532086ccee20..1abc71795523 100644 --- a/yarn-project/types/src/logs/note_spending_info/index.ts +++ b/yarn-project/types/src/logs/note_spending_info/index.ts @@ -1,3 +1,3 @@ export * from './encrypt_buffer.js'; export * from './note_preimage.js'; -export * from './note_spending_info.js'; +export * from './l1_note_payload.js'; diff --git a/yarn-project/types/src/logs/note_spending_info/l1_note_payload.test.ts b/yarn-project/types/src/logs/note_spending_info/l1_note_payload.test.ts new file mode 100644 index 000000000000..0c06f70eadfb --- /dev/null +++ b/yarn-project/types/src/logs/note_spending_info/l1_note_payload.test.ts @@ -0,0 +1,38 @@ +import { CircuitsWasm } from '@aztec/circuits.js'; +import { Grumpkin } from '@aztec/circuits.js/barretenberg'; +import { GrumpkinScalar, Point } from '@aztec/foundation/fields'; + +import { L1NotePayload } from './l1_note_payload.js'; + +describe('L1 Note Payload', () => { + let grumpkin: Grumpkin; + + beforeAll(async () => { + grumpkin = new Grumpkin(await CircuitsWasm.get()); + }); + + it('convert to and from buffer', () => { + const payload = L1NotePayload.random(); + const buf = payload.toBuffer(); + expect(L1NotePayload.fromBuffer(buf)).toEqual(payload); + }); + + it('convert to and from encrypted buffer', () => { + const payload = L1NotePayload.random(); + const ownerPrivKey = GrumpkinScalar.random(); + const ownerPubKey = grumpkin.mul(Grumpkin.generator, ownerPrivKey); + const encrypted = payload.toEncryptedBuffer(ownerPubKey, grumpkin); + const decrypted = L1NotePayload.fromEncryptedBuffer(encrypted, ownerPrivKey, grumpkin); + expect(decrypted).not.toBeUndefined(); + expect(decrypted).toEqual(payload); + }); + + it('return undefined if unable to decrypt the encrypted buffer', () => { + const payload = L1NotePayload.random(); + const ownerPubKey = Point.random(); + const encrypted = payload.toEncryptedBuffer(ownerPubKey, grumpkin); + const randomPrivKey = GrumpkinScalar.random(); + const decrypted = L1NotePayload.fromEncryptedBuffer(encrypted, randomPrivKey, grumpkin); + expect(decrypted).toBeUndefined(); + }); +}); diff --git a/yarn-project/types/src/logs/note_spending_info/note_spending_info.ts b/yarn-project/types/src/logs/note_spending_info/l1_note_payload.ts similarity index 83% rename from yarn-project/types/src/logs/note_spending_info/note_spending_info.ts rename to yarn-project/types/src/logs/note_spending_info/l1_note_payload.ts index e45c25562d83..12ee1ba2b6cb 100644 --- a/yarn-project/types/src/logs/note_spending_info/note_spending_info.ts +++ b/yarn-project/types/src/logs/note_spending_info/l1_note_payload.ts @@ -8,10 +8,11 @@ import { decryptBuffer, encryptBuffer } from './encrypt_buffer.js'; import { NotePreimage } from './note_preimage.js'; /** - * A class which wraps the data required to compute a nullifier/to spend a note. Along with that this class contains + * A class which wraps note data which is pushed on L1. + * @remarks This data is required to compute a nullifier/to spend a note. Along with that this class contains * the necessary functionality to encrypt and decrypt the data. */ -export class NoteSpendingInfo { +export class L1NotePayload { constructor( /** * Preimage which can be used along with private key to compute nullifier. @@ -32,9 +33,9 @@ export class NoteSpendingInfo { * @param buffer - Buffer or BufferReader object to deserialize. * @returns An instance of NoteSpendingInfo. */ - static fromBuffer(buffer: Buffer | BufferReader): NoteSpendingInfo { + static fromBuffer(buffer: Buffer | BufferReader): L1NotePayload { const reader = BufferReader.asReader(buffer); - return new NoteSpendingInfo(reader.readObject(NotePreimage), reader.readObject(AztecAddress), reader.readFr()); + return new L1NotePayload(reader.readObject(NotePreimage), reader.readObject(AztecAddress), reader.readFr()); } /** @@ -67,12 +68,12 @@ export class NoteSpendingInfo { data: Buffer, ownerPrivKey: GrumpkinPrivateKey, curve: Grumpkin, - ): NoteSpendingInfo | undefined { + ): L1NotePayload | undefined { const buf = decryptBuffer(data, ownerPrivKey, curve); if (!buf) { return; } - return NoteSpendingInfo.fromBuffer(buf); + return L1NotePayload.fromBuffer(buf); } /** @@ -80,6 +81,6 @@ export class NoteSpendingInfo { * @returns A random NoteSpendingInfo object. */ static random() { - return new NoteSpendingInfo(NotePreimage.random(), AztecAddress.random(), Fr.random()); + return new L1NotePayload(NotePreimage.random(), AztecAddress.random(), Fr.random()); } } diff --git a/yarn-project/types/src/logs/note_spending_info/note_spending_info.test.ts b/yarn-project/types/src/logs/note_spending_info/note_spending_info.test.ts deleted file mode 100644 index 9dac462c9467..000000000000 --- a/yarn-project/types/src/logs/note_spending_info/note_spending_info.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { CircuitsWasm } from '@aztec/circuits.js'; -import { Grumpkin } from '@aztec/circuits.js/barretenberg'; -import { GrumpkinScalar, Point } from '@aztec/foundation/fields'; - -import { NoteSpendingInfo } from './note_spending_info.js'; - -describe('note_spending_info', () => { - let grumpkin: Grumpkin; - - beforeAll(async () => { - grumpkin = new Grumpkin(await CircuitsWasm.get()); - }); - - it('convert to and from buffer', () => { - const noteSpendingInfo = NoteSpendingInfo.random(); - const buf = noteSpendingInfo.toBuffer(); - expect(NoteSpendingInfo.fromBuffer(buf)).toEqual(noteSpendingInfo); - }); - - it('convert to and from encrypted buffer', () => { - const noteSpendingInfo = NoteSpendingInfo.random(); - const ownerPrivKey = GrumpkinScalar.random(); - const ownerPubKey = grumpkin.mul(Grumpkin.generator, ownerPrivKey); - const encrypted = noteSpendingInfo.toEncryptedBuffer(ownerPubKey, grumpkin); - const decrypted = NoteSpendingInfo.fromEncryptedBuffer(encrypted, ownerPrivKey, grumpkin); - expect(decrypted).not.toBeUndefined(); - expect(decrypted).toEqual(noteSpendingInfo); - }); - - it('return undefined if unable to decrypt the encrypted buffer', () => { - const noteSpendingInfo = NoteSpendingInfo.random(); - const ownerPubKey = Point.random(); - const encrypted = noteSpendingInfo.toEncryptedBuffer(ownerPubKey, grumpkin); - const randomPrivKey = GrumpkinScalar.random(); - const decrypted = NoteSpendingInfo.fromEncryptedBuffer(encrypted, randomPrivKey, grumpkin); - expect(decrypted).toBeUndefined(); - }); -}); From 24e53010ddaccaea1c93bcb0518674f4d411dfc0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 14:17:24 +0000 Subject: [PATCH 14/41] cleanup --- .../src/client/client_execution_context.ts | 4 +- .../pxe/src/database/memory_db.test.ts | 2 +- yarn-project/pxe/src/database/memory_db.ts | 20 ++++---- .../src/note_processor/note_processor.test.ts | 48 +++++++++--------- .../pxe/src/note_processor/note_processor.ts | 50 +++++++++---------- yarn-project/types/src/logs/index.ts | 2 +- .../browserify-cipher.d.ts | 0 .../encrypt_buffer.test.ts | 0 .../encrypt_buffer.ts | 0 .../index.ts | 0 .../l1_note_payload.test.ts | 0 .../l1_note_payload.ts | 26 +++++----- .../note_preimage.test.ts | 0 .../note_preimage.ts | 0 14 files changed, 76 insertions(+), 76 deletions(-) rename yarn-project/types/src/logs/{note_spending_info => l1_note_payload}/browserify-cipher.d.ts (100%) rename yarn-project/types/src/logs/{note_spending_info => l1_note_payload}/encrypt_buffer.test.ts (100%) rename yarn-project/types/src/logs/{note_spending_info => l1_note_payload}/encrypt_buffer.ts (100%) rename yarn-project/types/src/logs/{note_spending_info => l1_note_payload}/index.ts (100%) rename yarn-project/types/src/logs/{note_spending_info => l1_note_payload}/l1_note_payload.test.ts (100%) rename yarn-project/types/src/logs/{note_spending_info => l1_note_payload}/l1_note_payload.ts (71%) rename yarn-project/types/src/logs/{note_spending_info => l1_note_payload}/note_preimage.test.ts (100%) rename yarn-project/types/src/logs/{note_spending_info => l1_note_payload}/note_preimage.ts (100%) diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index c2c3574930e4..b82dd38d3f21 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -289,8 +289,8 @@ export class ClientExecutionContext extends ViewDataOracle { */ public emitEncryptedLog(contractAddress: AztecAddress, storageSlot: Fr, publicKey: Point, preimage: Fr[]) { const notePreimage = new NotePreimage(preimage); - const noteSpendingInfo = new L1NotePayload(notePreimage, contractAddress, storageSlot); - const encryptedNotePreimage = noteSpendingInfo.toEncryptedBuffer(publicKey, this.curve); + const l1NotePayload = new L1NotePayload(notePreimage, contractAddress, storageSlot); + const encryptedNotePreimage = l1NotePayload.toEncryptedBuffer(publicKey, this.curve); this.encryptedLogs.push(encryptedNotePreimage); } diff --git a/yarn-project/pxe/src/database/memory_db.test.ts b/yarn-project/pxe/src/database/memory_db.test.ts index cc6f92a1d46f..a368b7dd4d64 100644 --- a/yarn-project/pxe/src/database/memory_db.test.ts +++ b/yarn-project/pxe/src/database/memory_db.test.ts @@ -10,7 +10,7 @@ describe('Memory DB', () => { db = new MemoryDB(); }); - describe('NoteSpendingInfo', () => { + describe('ExtendedNote', () => { const contractAddress = AztecAddress.random(); const storageSlot = Fr.random(); diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 40cfa2ca1ba3..20bcd22621af 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -64,23 +64,23 @@ export class MemoryDB extends MemoryContractDatabase implements Database { } return this.extendedNotesTable.filter( - noteSpendingInfo => - (filter.contractAddress == undefined || noteSpendingInfo.contractAddress.equals(filter.contractAddress)) && - (filter.txHash == undefined || noteSpendingInfo.txHash.equals(filter.txHash)) && - (filter.storageSlot == undefined || noteSpendingInfo.storageSlot.equals(filter.storageSlot!)) && - (ownerPublicKey == undefined || noteSpendingInfo.publicKey.equals(ownerPublicKey!)), + note => + (filter.contractAddress == undefined || note.contractAddress.equals(filter.contractAddress)) && + (filter.txHash == undefined || note.txHash.equals(filter.txHash)) && + (filter.storageSlot == undefined || note.storageSlot.equals(filter.storageSlot!)) && + (ownerPublicKey == undefined || note.publicKey.equals(ownerPublicKey!)), ); } public removeNullifiedNotes(nullifiers: Fr[], account: PublicKey) { const nullifierSet = new Set(nullifiers.map(nullifier => nullifier.toString())); const [remaining, removed] = this.extendedNotesTable.reduce( - (acc: [ExtendedNote[], ExtendedNote[]], noteSpendingInfo) => { - const nullifier = noteSpendingInfo.siloedNullifier.toString(); - if (noteSpendingInfo.publicKey.equals(account) && nullifierSet.has(nullifier)) { - acc[1].push(noteSpendingInfo); + (acc: [ExtendedNote[], ExtendedNote[]], note) => { + const nullifier = note.siloedNullifier.toString(); + if (note.publicKey.equals(account) && nullifierSet.has(nullifier)) { + acc[1].push(note); } else { - acc[0].push(noteSpendingInfo); + acc[0].push(note); } return acc; }, 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 bfd8dc142591..f81a6504f372 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -48,9 +48,9 @@ describe('Note Processor', () => { ); // ownedData: [tx1, tx2, ...], the numbers in each tx represents the indices of the note hashes the account owns. - const createEncryptedLogsAndOwnedNoteSpendingInfo = (ownedData: number[][], ownedNotes: L1NotePayload[]) => { + const createEncryptedLogsAndOwnedL1NotePayloads = (ownedData: number[][], ownedNotes: L1NotePayload[]) => { const newNotes: L1NotePayload[] = []; - const ownedNoteSpendingInfo: L1NotePayload[] = []; + const ownedL1NotePayloads: L1NotePayload[] = []; const txLogs: TxL2Logs[] = []; let usedOwnedNote = 0; for (let i = 0; i < TXS_PER_BLOCK; ++i) { @@ -67,7 +67,7 @@ describe('Note Processor', () => { usedOwnedNote += note === ownedNotes[usedOwnedNote] ? 1 : 0; newNotes.push(note); if (isOwner) { - ownedNoteSpendingInfo.push(note); + ownedL1NotePayloads.push(note); } const log = note.toEncryptedBuffer(publicKey, grumpkin); // 1 tx containing 1 function invocation containing 1 log @@ -77,7 +77,7 @@ describe('Note Processor', () => { } const encryptedLogs = new L2BlockL2Logs(txLogs); - return { newNotes, ownedNoteSpendingInfo, encryptedLogs }; + return { newNotes, ownedL1NotePayloads, encryptedLogs }; }; const mockData = ( @@ -92,25 +92,25 @@ describe('Note Processor', () => { const blockContexts: L2BlockContext[] = []; const encryptedLogsArr: L2BlockL2Logs[] = []; - const ownedNoteSpendingInfos: L1NotePayload[] = []; + const ownedL1NotePayloads: L1NotePayload[] = []; const numberOfBlocks = prependedBlocks + appendedBlocks + 1; for (let i = 0; i < numberOfBlocks; ++i) { const block = L2Block.random(firstBlockNum + i, TXS_PER_BLOCK); block.startNoteHashTreeSnapshot.nextAvailableLeafIndex = firstBlockDataStartIndex + i * numCommitmentsPerBlock; const isTargetBlock = i === prependedBlocks; - const { newNotes, encryptedLogs, ownedNoteSpendingInfo } = createEncryptedLogsAndOwnedNoteSpendingInfo( + const { newNotes, encryptedLogs, ownedL1NotePayloads: payloads } = createEncryptedLogsAndOwnedL1NotePayloads( isTargetBlock ? ownedData : [], isTargetBlock ? ownedNotes : [], ); encryptedLogsArr.push(encryptedLogs); - ownedNoteSpendingInfos.push(...ownedNoteSpendingInfo); + ownedL1NotePayloads.push(...payloads); block.newCommitments = newNotes.map(n => computeMockNoteHash(n.notePreimage.items)); const randomBlockContext = new L2BlockContext(block); blockContexts.push(randomBlockContext); } - return { blockContexts, encryptedLogsArr, ownedNoteSpendingInfos }; + return { blockContexts, encryptedLogsArr, ownedL1NotePayloads }; }; beforeAll(async () => { @@ -151,13 +151,13 @@ describe('Note Processor', () => { }); it('should store a note that belongs to us', async () => { - const { blockContexts, encryptedLogsArr, ownedNoteSpendingInfos } = mockData([[2]]); + const { blockContexts, encryptedLogsArr, ownedL1NotePayloads } = mockData([[2]]); await noteProcessor.process(blockContexts, encryptedLogsArr); expect(addExtendedNotesSpy).toHaveBeenCalledTimes(1); expect(addExtendedNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ - ...ownedNoteSpendingInfos[0], + ...ownedL1NotePayloads[0], index: BigInt(firstBlockDataStartIndex + 2), }), ]); @@ -168,7 +168,7 @@ describe('Note Processor', () => { const appendedBlocks = 1; const thisBlockDataStartIndex = firstBlockDataStartIndex + prependedBlocks * numCommitmentsPerBlock; - const { blockContexts, encryptedLogsArr, ownedNoteSpendingInfos } = mockData( + const { blockContexts, encryptedLogsArr, ownedL1NotePayloads } = mockData( [[], [1], [], [0, 2]], prependedBlocks, appendedBlocks, @@ -178,17 +178,17 @@ describe('Note Processor', () => { expect(addExtendedNotesSpy).toHaveBeenCalledTimes(1); expect(addExtendedNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ - ...ownedNoteSpendingInfos[0], + ...ownedL1NotePayloads[0], // Index 1 log in the 2nd tx. index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (2 - 1) + 1), }), expect.objectContaining({ - ...ownedNoteSpendingInfos[1], + ...ownedL1NotePayloads[1], // Index 0 log in the 4th tx. index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 0), }), expect.objectContaining({ - ...ownedNoteSpendingInfos[2], + ...ownedL1NotePayloads[2], // Index 2 log in the 4th tx. index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 2), }), @@ -205,21 +205,21 @@ describe('Note Processor', () => { const note2 = L1NotePayload.random(); // All notes expect one have the same contract address, storage slot, and preimage. const notes = [note, note, note, note2, note]; - const { blockContexts, encryptedLogsArr, ownedNoteSpendingInfos } = mockData([[0, 2], [], [0, 1, 3]], 0, 0, notes); + const { blockContexts, encryptedLogsArr, ownedL1NotePayloads } = mockData([[0, 2], [], [0, 1, 3]], 0, 0, notes); await noteProcessor.process(blockContexts, encryptedLogsArr); const addedInfos: ExtendedNote[] = addExtendedNotesSpy.mock.calls[0][0]; expect(addedInfos).toEqual([ - expect.objectContaining({ ...ownedNoteSpendingInfos[0] }), - expect.objectContaining({ ...ownedNoteSpendingInfos[1] }), - expect.objectContaining({ ...ownedNoteSpendingInfos[2] }), - expect.objectContaining({ ...ownedNoteSpendingInfos[3] }), - expect.objectContaining({ ...ownedNoteSpendingInfos[4] }), + expect.objectContaining({ ...ownedL1NotePayloads[0] }), + expect.objectContaining({ ...ownedL1NotePayloads[1] }), + expect.objectContaining({ ...ownedL1NotePayloads[2] }), + expect.objectContaining({ ...ownedL1NotePayloads[3] }), + expect.objectContaining({ ...ownedL1NotePayloads[4] }), ]); - expect(ownedNoteSpendingInfos[0]).toEqual(ownedNoteSpendingInfos[1]); - expect(ownedNoteSpendingInfos[1]).toEqual(ownedNoteSpendingInfos[2]); - expect(ownedNoteSpendingInfos[2]).toEqual(ownedNoteSpendingInfos[4]); - expect(ownedNoteSpendingInfos[3]).not.toEqual(ownedNoteSpendingInfos[4]); + expect(ownedL1NotePayloads[0]).toEqual(ownedL1NotePayloads[1]); + expect(ownedL1NotePayloads[1]).toEqual(ownedL1NotePayloads[2]); + expect(ownedL1NotePayloads[2]).toEqual(ownedL1NotePayloads[4]); + expect(ownedL1NotePayloads[3]).not.toEqual(ownedL1NotePayloads[4]); // Check that every note has a different nonce. const nonceSet = new Set(); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 79397b7feb73..998dc6aebfde 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -100,7 +100,7 @@ export class NoteProcessor { return; } - const blocksAndNoteSpendingInfo: ProcessedData[] = []; + const blocksAndNotes: ProcessedData[] = []; const curve = await Grumpkin.new(); // Iterate over both blocks and encrypted logs. @@ -135,25 +135,25 @@ export class NoteProcessor { for (const functionLogs of txFunctionLogs) { for (const logs of functionLogs.logs) { this.stats.seen++; - const noteSpendingInfo = L1NotePayload.fromEncryptedBuffer(logs, privateKey, curve); - if (noteSpendingInfo) { + const payload = L1NotePayload.fromEncryptedBuffer(logs, privateKey, curve); + if (payload) { // We have successfully decrypted the data. try { const { commitmentIndex, nonce, innerNoteHash, siloedNullifier } = await this.findNoteIndexAndNullifier( newCommitments, newNullifiers[0], - noteSpendingInfo, + payload, excludedIndices, ); const index = BigInt(dataStartIndexForTx + commitmentIndex); excludedIndices.add(commitmentIndex); extendedNotes.push( new ExtendedNote( - noteSpendingInfo.notePreimage, - noteSpendingInfo.contractAddress, + payload.notePreimage, + payload.contractAddress, blockContext.getTxHash(indexOfTxInABlock), nonce, - noteSpendingInfo.storageSlot, + payload.storageSlot, innerNoteHash, siloedNullifier, index, @@ -170,13 +170,13 @@ export class NoteProcessor { } } - blocksAndNoteSpendingInfo.push({ + blocksAndNotes.push({ blockContext: l2BlockContexts[blockIndex], extendedNotes, }); } - await this.processBlocksAndNoteSpendingInfo(blocksAndNoteSpendingInfo); + await this.processBlocksAndNotes(blocksAndNotes); this.syncedToBlock = l2BlockContexts[l2BlockContexts.length - 1].block.number; this.log(`Synched block ${this.syncedToBlock}`); @@ -187,13 +187,13 @@ export class NoteProcessor { * commitment for the current tx matches this value. * Compute the nullifier for a given transaction auxiliary data. * The nullifier is calculated using the private key of the account, - * contract address, and note preimage associated with the noteSpendingInfo. + * contract address, and note preimage associated with the l1NotePayload. * This method assists in identifying spent commitments in the private state. * @param commitments - Commitments in the tx. One of them should be the note's commitment. * @param firstNullifier - First nullifier in the tx. - * @param noteSpendingInfo - An instance of NoteSpendingInfo containing transaction details. + * @param l1NotePayload - An instance of l1NotePayload containing transaction details. * @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same - * NoteSpendingInfo. We need to find a different index for each replicate. + * l1NotePayload. We need to find a different index for each replicate. * @returns Information for a decrypted note, including the index of its commitment, nonce, inner note * hash, and the siloed nullifier. Throw if cannot find the nonce for the note. */ @@ -267,28 +267,28 @@ https://github.com/AztecProtocol/aztec-packages/issues/1641`; * transaction auxiliary data from the database. This function keeps track of new nullifiers * and ensures all other transactions are updated with newly settled block information. * - * @param blocksAndNoteSpendingInfo - Array of objects containing L2BlockContexts, user-pertaining transaction indices, and ExtendedNotes. + * @param blocksAndNotes - Array of objects containing L2BlockContexts, user-pertaining transaction indices, and ExtendedNotes. */ - private async processBlocksAndNoteSpendingInfo(blocksAndNoteSpendingInfo: ProcessedData[]) { - const extendedNotesBatch = blocksAndNoteSpendingInfo.flatMap(b => b.extendedNotes); + private async processBlocksAndNotes(blocksAndNotes: ProcessedData[]) { + const extendedNotesBatch = blocksAndNotes.flatMap(b => b.extendedNotes); if (extendedNotesBatch.length) { await this.db.addExtendedNotes(extendedNotesBatch); - extendedNotesBatch.forEach(noteSpendingInfo => { + extendedNotesBatch.forEach(note => { this.log( - `Added note spending info for contract ${noteSpendingInfo.contractAddress} at slot ${ - noteSpendingInfo.storageSlot - } with nullifier ${noteSpendingInfo.siloedNullifier.toString()}`, + `Added note for contract ${note.contractAddress} at slot ${ + note.storageSlot + } with nullifier ${note.siloedNullifier.toString()}`, ); }); } - const newNullifiers: Fr[] = blocksAndNoteSpendingInfo.flatMap(b => b.blockContext.block.newNullifiers); - const removedNoteSpendingInfo = await this.db.removeNullifiedNotes(newNullifiers, this.publicKey); - removedNoteSpendingInfo.forEach(noteSpendingInfo => { + const newNullifiers: Fr[] = blocksAndNotes.flatMap(b => b.blockContext.block.newNullifiers); + const removedNotes = await this.db.removeNullifiedNotes(newNullifiers, this.publicKey); + removedNotes.forEach(note => { this.log( - `Removed note spending info for contract ${noteSpendingInfo.contractAddress} at slot ${ - noteSpendingInfo.storageSlot - } with nullifier ${noteSpendingInfo.siloedNullifier.toString()}`, + `Removed note spending info for contract ${note.contractAddress} at slot ${ + note.storageSlot + } with nullifier ${note.siloedNullifier.toString()}`, ); }); } diff --git a/yarn-project/types/src/logs/index.ts b/yarn-project/types/src/logs/index.ts index a495dfb6a7b2..98a84492c189 100644 --- a/yarn-project/types/src/logs/index.ts +++ b/yarn-project/types/src/logs/index.ts @@ -5,7 +5,7 @@ export * from './l2_logs_source.js'; export * from './log_id.js'; export * from './log_type.js'; export * from './log_filter.js'; -export * from './note_spending_info/index.js'; +export * from './l1_note_payload/index.js'; export * from './tx_l2_logs.js'; export * from './unencrypted_l2_log.js'; export * from './extended_unencrypted_l2_log.js'; diff --git a/yarn-project/types/src/logs/note_spending_info/browserify-cipher.d.ts b/yarn-project/types/src/logs/l1_note_payload/browserify-cipher.d.ts similarity index 100% rename from yarn-project/types/src/logs/note_spending_info/browserify-cipher.d.ts rename to yarn-project/types/src/logs/l1_note_payload/browserify-cipher.d.ts diff --git a/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.test.ts b/yarn-project/types/src/logs/l1_note_payload/encrypt_buffer.test.ts similarity index 100% rename from yarn-project/types/src/logs/note_spending_info/encrypt_buffer.test.ts rename to yarn-project/types/src/logs/l1_note_payload/encrypt_buffer.test.ts diff --git a/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.ts b/yarn-project/types/src/logs/l1_note_payload/encrypt_buffer.ts similarity index 100% rename from yarn-project/types/src/logs/note_spending_info/encrypt_buffer.ts rename to yarn-project/types/src/logs/l1_note_payload/encrypt_buffer.ts diff --git a/yarn-project/types/src/logs/note_spending_info/index.ts b/yarn-project/types/src/logs/l1_note_payload/index.ts similarity index 100% rename from yarn-project/types/src/logs/note_spending_info/index.ts rename to yarn-project/types/src/logs/l1_note_payload/index.ts diff --git a/yarn-project/types/src/logs/note_spending_info/l1_note_payload.test.ts b/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.test.ts similarity index 100% rename from yarn-project/types/src/logs/note_spending_info/l1_note_payload.test.ts rename to yarn-project/types/src/logs/l1_note_payload/l1_note_payload.test.ts diff --git a/yarn-project/types/src/logs/note_spending_info/l1_note_payload.ts b/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts similarity index 71% rename from yarn-project/types/src/logs/note_spending_info/l1_note_payload.ts rename to yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts index 12ee1ba2b6cb..2a555c101b18 100644 --- a/yarn-project/types/src/logs/note_spending_info/l1_note_payload.ts +++ b/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts @@ -29,9 +29,9 @@ export class L1NotePayload { ) {} /** - * Deserializes the NoteSpendingInfo object from a Buffer. + * Deserializes the L1NotePayload object from a Buffer. * @param buffer - Buffer or BufferReader object to deserialize. - * @returns An instance of NoteSpendingInfo. + * @returns An instance of L1NotePayload. */ static fromBuffer(buffer: Buffer | BufferReader): L1NotePayload { const reader = BufferReader.asReader(buffer); @@ -39,18 +39,18 @@ export class L1NotePayload { } /** - * Serializes the NoteSpendingInfo object into a Buffer. - * @returns Buffer representation of the NoteSpendingInfo object. + * Serializes the L1NotePayload object into a Buffer. + * @returns Buffer representation of the L1NotePayload object. */ toBuffer() { return serializeToBuffer([this.notePreimage, this.contractAddress, this.storageSlot]); } /** - * Encrypt the NoteSpendingInfo object using the owner's public key and the ephemeral private key. - * @param ownerPubKey - Public key of the owner of the NoteSpendingInfo object. + * Encrypt the L1NotePayload object using the owner's public key and the ephemeral private key. + * @param ownerPubKey - Public key of the owner of the L1NotePayload object. * @param curve - The curve instance to use. - * @returns The encrypted NoteSpendingInfo object. + * @returns The encrypted L1NotePayload object. */ public toEncryptedBuffer(ownerPubKey: PublicKey, curve: Grumpkin): Buffer { const ephPrivKey: GrumpkinPrivateKey = GrumpkinScalar.random(); @@ -58,11 +58,11 @@ export class L1NotePayload { } /** - * Decrypts the NoteSpendingInfo object using the owner's private key. - * @param data - Encrypted NoteSpendingInfo object. - * @param ownerPrivKey - Private key of the owner of the NoteSpendingInfo object. + * Decrypts the L1NotePayload object using the owner's private key. + * @param data - Encrypted L1NotePayload object. + * @param ownerPrivKey - Private key of the owner of the L1NotePayload object. * @param curve - The curve instance to use. - * @returns Instance of NoteSpendingInfo if the decryption was successful, undefined otherwise. + * @returns Instance of L1NotePayload if the decryption was successful, undefined otherwise. */ static fromEncryptedBuffer( data: Buffer, @@ -77,8 +77,8 @@ export class L1NotePayload { } /** - * Create a random NoteSpendingInfo object (useful for testing purposes). - * @returns A random NoteSpendingInfo object. + * Create a random L1NotePayload object (useful for testing purposes). + * @returns A random L1NotePayload object. */ static random() { return new L1NotePayload(NotePreimage.random(), AztecAddress.random(), Fr.random()); diff --git a/yarn-project/types/src/logs/note_spending_info/note_preimage.test.ts b/yarn-project/types/src/logs/l1_note_payload/note_preimage.test.ts similarity index 100% rename from yarn-project/types/src/logs/note_spending_info/note_preimage.test.ts rename to yarn-project/types/src/logs/l1_note_payload/note_preimage.test.ts diff --git a/yarn-project/types/src/logs/note_spending_info/note_preimage.ts b/yarn-project/types/src/logs/l1_note_payload/note_preimage.ts similarity index 100% rename from yarn-project/types/src/logs/note_spending_info/note_preimage.ts rename to yarn-project/types/src/logs/l1_note_payload/note_preimage.ts From 8fbefe1ac3723e447f77290d62ab759a3d04a273 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 14:21:43 +0000 Subject: [PATCH 15/41] cleanup 2 --- .../pxe/src/note_processor/note_processor.test.ts | 9 +++++---- yarn-project/pxe/src/note_processor/note_processor.ts | 6 +++--- yarn-project/types/src/notes/extended_note.ts | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) 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 f81a6504f372..684ee55ac38b 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -99,10 +99,11 @@ describe('Note Processor', () => { block.startNoteHashTreeSnapshot.nextAvailableLeafIndex = firstBlockDataStartIndex + i * numCommitmentsPerBlock; const isTargetBlock = i === prependedBlocks; - const { newNotes, encryptedLogs, ownedL1NotePayloads: payloads } = createEncryptedLogsAndOwnedL1NotePayloads( - isTargetBlock ? ownedData : [], - isTargetBlock ? ownedNotes : [], - ); + const { + newNotes, + encryptedLogs, + ownedL1NotePayloads: payloads, + } = createEncryptedLogsAndOwnedL1NotePayloads(isTargetBlock ? ownedData : [], isTargetBlock ? ownedNotes : []); encryptedLogsArr.push(encryptedLogs); ownedL1NotePayloads.push(...payloads); block.newCommitments = newNotes.map(n => computeMockNoteHash(n.notePreimage.items)); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 998dc6aebfde..4acae9f4d2de 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -27,7 +27,7 @@ interface ProcessedData { */ blockContext: L2BlockContext; /** - * A collection of data access objects for note spending info. + * A processed extended notes. */ extendedNotes: ExtendedNote[]; } @@ -116,7 +116,7 @@ export class NoteProcessor { const extendedNotes: ExtendedNote[] = []; const privateKey = await this.keyStore.getAccountPrivateKey(this.publicKey); - // Iterate over all the encrypted logs and try decrypting them. If successful, store the note spending info. + // Iterate over all the encrypted logs and try decrypting them. If successful, store the note. for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) { this.stats.txs++; const dataStartIndexForTx = dataStartIndexForBlock + indexOfTxInABlock * MAX_NEW_COMMITMENTS_PER_TX; @@ -286,7 +286,7 @@ https://github.com/AztecProtocol/aztec-packages/issues/1641`; const removedNotes = await this.db.removeNullifiedNotes(newNullifiers, this.publicKey); removedNotes.forEach(note => { this.log( - `Removed note spending info for contract ${note.contractAddress} at slot ${ + `Removed note for contract ${note.contractAddress} at slot ${ note.storageSlot } with nullifier ${note.siloedNullifier.toString()}`, ); diff --git a/yarn-project/types/src/notes/extended_note.ts b/yarn-project/types/src/notes/extended_note.ts index 027b29baebbe..9a852c4223e5 100644 --- a/yarn-project/types/src/notes/extended_note.ts +++ b/yarn-project/types/src/notes/extended_note.ts @@ -85,7 +85,7 @@ export class ExtendedNote { } /** - * Returns the size in bytes of a note spending info dao. + * Returns the size in bytes of the extended note. * @param note - The note. * @returns - Its size in bytes. */ From 2dab8437a4fd287bd8a035ffd7cdaff4d1066651 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 14:29:28 +0000 Subject: [PATCH 16/41] refactor: NotePreimage --> Note --- .../src/client/client_execution_context.ts | 4 +-- yarn-project/aztec.js/src/index.ts | 2 +- yarn-project/aztec.js/src/pxe_client.ts | 4 +-- .../aztec.js/src/utils/cheat_codes.ts | 4 +-- .../aztec.js/src/wallet/base_wallet.ts | 6 ++-- .../src/e2e_lending_contract.test.ts | 4 +-- .../pxe/src/pxe_http/pxe_http_server.ts | 4 +-- .../pxe/src/pxe_service/pxe_service.ts | 6 ++-- yarn-project/types/src/interfaces/pxe.ts | 6 ++-- .../types/src/logs/l1_note_payload/index.ts | 2 +- .../logs/l1_note_payload/l1_note_payload.ts | 8 ++--- .../{note_preimage.test.ts => note.test.ts} | 8 ++--- .../{note_preimage.ts => note.ts} | 31 +++++++++---------- yarn-project/types/src/mocks.ts | 11 ++----- yarn-project/types/src/notes/extended_note.ts | 6 ++-- 15 files changed, 49 insertions(+), 57 deletions(-) rename yarn-project/types/src/logs/l1_note_payload/{note_preimage.test.ts => note.test.ts} (51%) rename yarn-project/types/src/logs/l1_note_payload/{note_preimage.ts => note.ts} (51%) diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index b82dd38d3f21..a3b4d576933b 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -15,7 +15,7 @@ import { FunctionAbi, FunctionArtifact, countArgumentsSize } from '@aztec/founda import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { AuthWitness, FunctionL2Logs, L1NotePayload, NotePreimage, UnencryptedL2Log } from '@aztec/types'; +import { AuthWitness, FunctionL2Logs, L1NotePayload, Note, UnencryptedL2Log } from '@aztec/types'; import { NoteData, @@ -288,7 +288,7 @@ export class ClientExecutionContext extends ViewDataOracle { * @param preimage - The preimage of the note. */ public emitEncryptedLog(contractAddress: AztecAddress, storageSlot: Fr, publicKey: Point, preimage: Fr[]) { - const notePreimage = new NotePreimage(preimage); + const notePreimage = new Note(preimage); const l1NotePayload = new L1NotePayload(notePreimage, contractAddress, storageSlot); const encryptedNotePreimage = l1NotePayload.toEncryptedBuffer(publicKey, this.curve); this.encryptedLogs.push(encryptedNotePreimage); diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index b84e13839461..51b1ece3df3c 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -19,7 +19,7 @@ export { L2BlockL2Logs, LogFilter, NodeInfo, - NotePreimage, + Note as NotePreimage, PackedArguments, PublicKey, PXE, diff --git a/yarn-project/aztec.js/src/pxe_client.ts b/yarn-project/aztec.js/src/pxe_client.ts index 7c0d4c29edc2..c50cdc848de3 100644 --- a/yarn-project/aztec.js/src/pxe_client.ts +++ b/yarn-project/aztec.js/src/pxe_client.ts @@ -17,7 +17,7 @@ import { L2BlockL2Logs, L2Tx, LogId, - NotePreimage, + Note, PXE, Tx, TxExecutionRequest, @@ -43,7 +43,7 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], true)) Point, Fr, GrumpkinScalar, - NotePreimage, + Note, ExtendedNote, AuthWitness, L2Tx, diff --git a/yarn-project/aztec.js/src/utils/cheat_codes.ts b/yarn-project/aztec.js/src/utils/cheat_codes.ts index 50769d37237d..a9119c632088 100644 --- a/yarn-project/aztec.js/src/utils/cheat_codes.ts +++ b/yarn-project/aztec.js/src/utils/cheat_codes.ts @@ -3,7 +3,7 @@ import { pedersenHashInputs } from '@aztec/circuits.js/barretenberg'; import { toBigIntBE, toHex } from '@aztec/foundation/bigint-buffer'; import { keccak } from '@aztec/foundation/crypto'; import { createDebugLogger } from '@aztec/foundation/log'; -import { NotePreimage, PXE } from '@aztec/types'; +import { Note, PXE } from '@aztec/types'; import fs from 'fs'; @@ -287,7 +287,7 @@ export class AztecCheatCodes { * @param slot - The storage slot to lookup * @returns The notes stored at the given slot */ - public async loadPrivate(owner: AztecAddress, contract: AztecAddress, slot: Fr | bigint): Promise { + public async loadPrivate(owner: AztecAddress, contract: AztecAddress, slot: Fr | bigint): Promise { const notes = await this.pxe.getNotes({ owner, contractAddress: contract, storageSlot: new Fr(slot) }); return notes.map(note => note.notePreimage); } diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index 4a412f854b06..58548fc2b2f8 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -10,8 +10,8 @@ import { L2Tx, LogFilter, NodeInfo, + Note, NoteFilter, - NotePreimage, PXE, SyncStatus, Tx, @@ -81,13 +81,13 @@ export abstract class BaseWallet implements Wallet { account: AztecAddress, contract: AztecAddress, storageSlot: Fr, - preimage: NotePreimage, + preimage: Note, txHash: TxHash, nonce?: Fr, ): Promise { return this.pxe.addNote(account, contract, storageSlot, preimage, txHash, nonce); } - getNoteNonces(contract: AztecAddress, storageSlot: Fr, preimage: NotePreimage, txHash: TxHash): Promise { + getNoteNonces(contract: AztecAddress, storageSlot: Fr, preimage: Note, txHash: TxHash): Promise { return this.pxe.getNoteNonces(contract, storageSlot, preimage, txHash); } viewTx(functionName: string, args: any[], to: AztecAddress, from?: AztecAddress | undefined): Promise { diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 07a09a145589..0484130ff93d 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -9,7 +9,7 @@ import { import { CompleteAddress } from '@aztec/circuits.js'; import { DebugLogger } from '@aztec/foundation/log'; import { LendingContract, PriceFeedContract, TokenContract } from '@aztec/noir-contracts/types'; -import { NotePreimage, TxStatus } from '@aztec/types'; +import { Note, TxStatus } from '@aztec/types'; import { jest } from '@jest/globals'; @@ -120,7 +120,7 @@ describe('e2e_lending_contract', () => { await Promise.all([a, b].map(waitForSuccess)); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(mintAmount), secretHash]); + const preimage = new Note([new Fr(mintAmount), secretHash]); const txHash = await b.getTxHash(); await wallet.addNote(accounts[0].address, asset.address, storageSlot, preimage, txHash); 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 e41cdec28d96..665fd47b6485 100644 --- a/yarn-project/pxe/src/pxe_http/pxe_http_server.ts +++ b/yarn-project/pxe/src/pxe_http/pxe_http_server.ts @@ -13,7 +13,7 @@ import { L2BlockL2Logs, L2Tx, LogId, - NotePreimage, + Note, PXE, Tx, TxExecutionRequest, @@ -48,7 +48,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer { Point, Fr, GrumpkinScalar, - NotePreimage, + Note, ExtendedNote, AuthWitness, L2Block, diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index ec324e289e15..a9453f9e0632 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -39,8 +39,8 @@ import { LogFilter, MerkleTreeId, NodeInfo, + Note, NoteFilter, - NotePreimage, PXE, SimulationError, Tx, @@ -202,7 +202,7 @@ export class PXEService implements PXE { account: AztecAddress, contractAddress: AztecAddress, storageSlot: Fr, - preimage: NotePreimage, + preimage: Note, txHash: TxHash, nonce?: Fr, ) { @@ -254,7 +254,7 @@ export class PXEService implements PXE { public async getNoteNonces( contractAddress: AztecAddress, storageSlot: Fr, - preimage: NotePreimage, + preimage: Note, txHash: TxHash, ): Promise { const tx = await this.node.getTx(txHash); diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index 1c83d27b7c4e..6f2ead7ed7be 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -8,7 +8,7 @@ import { GetUnencryptedLogsResponse, L2Tx, LogFilter, - NotePreimage, + Note, Tx, TxExecutionRequest, TxHash, @@ -180,7 +180,7 @@ export interface PXE { account: AztecAddress, contract: AztecAddress, storageSlot: Fr, - preimage: NotePreimage, + preimage: Note, txHash: TxHash, nonce?: Fr, ): Promise; @@ -194,7 +194,7 @@ export interface PXE { * @returns The nonces of the note. * @remarks More than single nonce may be returned since there might be more than one note with the same preimage. */ - getNoteNonces(contract: AztecAddress, storageSlot: Fr, preimage: NotePreimage, txHash: TxHash): Promise; + getNoteNonces(contract: AztecAddress, storageSlot: Fr, preimage: Note, txHash: TxHash): Promise; /** * Simulate the execution of a view (read-only) function on a deployed contract without actually modifying state. diff --git a/yarn-project/types/src/logs/l1_note_payload/index.ts b/yarn-project/types/src/logs/l1_note_payload/index.ts index 1abc71795523..48f979409938 100644 --- a/yarn-project/types/src/logs/l1_note_payload/index.ts +++ b/yarn-project/types/src/logs/l1_note_payload/index.ts @@ -1,3 +1,3 @@ export * from './encrypt_buffer.js'; -export * from './note_preimage.js'; +export * from './note.js'; export * from './l1_note_payload.js'; diff --git a/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts b/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts index 2a555c101b18..dbb4329408b9 100644 --- a/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts +++ b/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts @@ -5,7 +5,7 @@ import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { BufferReader } from '@aztec/foundation/serialize'; import { decryptBuffer, encryptBuffer } from './encrypt_buffer.js'; -import { NotePreimage } from './note_preimage.js'; +import { Note } from './note.js'; /** * A class which wraps note data which is pushed on L1. @@ -17,7 +17,7 @@ export class L1NotePayload { /** * Preimage which can be used along with private key to compute nullifier. */ - public notePreimage: NotePreimage, + public notePreimage: Note, /** * Address of the contract this tx is interacting with. */ @@ -35,7 +35,7 @@ export class L1NotePayload { */ static fromBuffer(buffer: Buffer | BufferReader): L1NotePayload { const reader = BufferReader.asReader(buffer); - return new L1NotePayload(reader.readObject(NotePreimage), reader.readObject(AztecAddress), reader.readFr()); + return new L1NotePayload(reader.readObject(Note), reader.readObject(AztecAddress), reader.readFr()); } /** @@ -81,6 +81,6 @@ export class L1NotePayload { * @returns A random L1NotePayload object. */ static random() { - return new L1NotePayload(NotePreimage.random(), AztecAddress.random(), Fr.random()); + return new L1NotePayload(Note.random(), AztecAddress.random(), Fr.random()); } } diff --git a/yarn-project/types/src/logs/l1_note_payload/note_preimage.test.ts b/yarn-project/types/src/logs/l1_note_payload/note.test.ts similarity index 51% rename from yarn-project/types/src/logs/l1_note_payload/note_preimage.test.ts rename to yarn-project/types/src/logs/l1_note_payload/note.test.ts index dfed1ca38f8f..82d79d37ec9c 100644 --- a/yarn-project/types/src/logs/l1_note_payload/note_preimage.test.ts +++ b/yarn-project/types/src/logs/l1_note_payload/note.test.ts @@ -1,12 +1,12 @@ import { Fr } from '@aztec/foundation/fields'; -import { NotePreimage } from './note_preimage.js'; +import { Note } from './note.js'; -describe('note_preimage', () => { +describe('note', () => { it('convert to and from buffer', () => { const fields = Array.from({ length: 5 }).map(() => Fr.random()); - const notePreimage = new NotePreimage(fields); + const notePreimage = new Note(fields); const buf = notePreimage.toBuffer(); - expect(NotePreimage.fromBuffer(buf)).toEqual(notePreimage); + expect(Note.fromBuffer(buf)).toEqual(notePreimage); }); }); diff --git a/yarn-project/types/src/logs/l1_note_payload/note_preimage.ts b/yarn-project/types/src/logs/l1_note_payload/note.ts similarity index 51% rename from yarn-project/types/src/logs/l1_note_payload/note_preimage.ts rename to yarn-project/types/src/logs/l1_note_payload/note.ts index 3d8491479844..4d0bdb17b240 100644 --- a/yarn-project/types/src/logs/l1_note_payload/note_preimage.ts +++ b/yarn-project/types/src/logs/l1_note_payload/note.ts @@ -3,36 +3,35 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader } from '@aztec/foundation/serialize'; /** - * The NotePreimage class represents a vector of Fr (finite field) elements, used for constructing - * and manipulating preimages of zk-SNARK commitments in the AZTEC protocol. This class provides - * methods to create a NotePreimage instance from a buffer or generate a random one. It extends - * the Vector class, which allows for additional operations on the underlying field elements. + * The Note class represents a Note emitted from a Noir contract as a vector of Fr (finite field) elements. + * This data also represents a preimage to a note hash. This class extends the Vector class, which allows for + * additional operations on the underlying field elements. */ -export class NotePreimage extends Vector { +export class Note extends Vector { /** - * Create a NotePreimage instance from a Buffer or BufferReader. + * Create a Note instance from a Buffer or BufferReader. * The input 'buffer' can be either a Buffer containing the serialized Fr elements or a BufferReader instance. - * This function reads the Fr elements in the buffer and constructs a NotePreimage with them. + * This function reads the Fr elements in the buffer and constructs a Note with them. * * @param buffer - The Buffer or BufferReader containing the serialized Fr elements. - * @returns A NotePreimage instance containing the deserialized Fr elements. + * @returns A Note instance containing the deserialized Fr elements. */ static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - return new NotePreimage(reader.readVector(Fr)); + return new Note(reader.readVector(Fr)); } /** - * Generates a random NotePreimage instance with a variable number of items. + * Generates a random Note instance with a variable number of items. * The number of items is determined by a random value between 1 and 10 (inclusive). - * Each item in the NotePreimage is generated using the Fr.random() method. + * Each item in the Note is generated using the Fr.random() method. * - * @returns A randomly generated NotePreimage instance. + * @returns A randomly generated Note instance. */ static random() { const numItems = Math.floor(Math.random() * 10) + 1; const items = Array.from({ length: numItems }, () => Fr.random()); - return new NotePreimage(items); + return new Note(items); } /** @@ -44,12 +43,12 @@ export class NotePreimage extends Vector { } /** - * Creates a new NotePreimage instance from a hex string. + * Creates a new Note instance from a hex string. * @param str - Hex representation. - * @returns A NotePreimage instance. + * @returns A Note instance. */ static fromString(str: string) { const hex = str.replace(/^0x/, ''); - return NotePreimage.fromBuffer(Buffer.from(hex, 'hex')); + return Note.fromBuffer(Buffer.from(hex, 'hex')); } } diff --git a/yarn-project/types/src/mocks.ts b/yarn-project/types/src/mocks.ts index 4d7078f6d6df..57f7b397f1db 100644 --- a/yarn-project/types/src/mocks.ts +++ b/yarn-project/types/src/mocks.ts @@ -15,14 +15,7 @@ import { Tuple } from '@aztec/foundation/serialize'; import times from 'lodash.times'; -import { - DeployedContract, - ExtendedContractData, - ExtendedNote, - FunctionL2Logs, - NotePreimage, - TxL2Logs, -} from './index.js'; +import { DeployedContract, ExtendedContractData, ExtendedNote, FunctionL2Logs, Note, TxL2Logs } from './index.js'; import { Tx, TxHash } from './tx/index.js'; /** @@ -62,7 +55,7 @@ export const randomDeployedContract = async (): Promise => ({ }); export const randomExtendedNote = ({ - notePreimage = NotePreimage.random(), + notePreimage = Note.random(), contractAddress = AztecAddress.random(), txHash = randomTxHash(), nonce = Fr.random(), diff --git a/yarn-project/types/src/notes/extended_note.ts b/yarn-project/types/src/notes/extended_note.ts index 9a852c4223e5..c3075039c65d 100644 --- a/yarn-project/types/src/notes/extended_note.ts +++ b/yarn-project/types/src/notes/extended_note.ts @@ -1,6 +1,6 @@ import { AztecAddress, Fr, Point, PublicKey } from '@aztec/circuits.js'; import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; -import { BufferReader, NotePreimage, TxHash } from '@aztec/types'; +import { BufferReader, Note, TxHash } from '@aztec/types'; /** * A note with contextual data. @@ -8,7 +8,7 @@ import { BufferReader, NotePreimage, TxHash } from '@aztec/types'; export class ExtendedNote { constructor( /** The preimage of the note, containing essential information about the note. */ - public notePreimage: NotePreimage, + public notePreimage: Note, /** The contract address this note is created in. */ public contractAddress: AztecAddress, /** The hash of the tx the note was created in. */ @@ -52,7 +52,7 @@ export class ExtendedNote { static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - const notePreimage = NotePreimage.fromBuffer(reader); + const notePreimage = Note.fromBuffer(reader); const contractAddress = AztecAddress.fromBuffer(reader); const txHash = new TxHash(reader.readBytes(TxHash.SIZE)); const nonce = Fr.fromBuffer(reader); From d3c9722a6bec6bd730f792a3d59ac451693430ee Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Oct 2023 14:56:05 +0000 Subject: [PATCH 17/41] WIP --- .../acir-simulator/src/acvm/oracle/oracle.ts | 4 +- .../src/client/client_execution_context.ts | 8 +-- .../acir-simulator/src/client/simulator.ts | 62 +++++-------------- .../aztec-sandbox/src/examples/token.ts | 4 +- yarn-project/aztec.js/src/index.ts | 2 +- .../aztec.js/src/utils/cheat_codes.ts | 4 +- .../token/src/tests/token.contract.test.ts | 4 +- yarn-project/cli/src/index.ts | 6 +- .../end-to-end/src/e2e_2_pxes.test.ts | 4 +- .../src/e2e_escrow_contract.test.ts | 6 +- .../e2e_multiple_accounts_1_enc_key.test.ts | 4 +- .../src/e2e_sandbox_example.test.ts | 6 +- .../end-to-end/src/e2e_token_contract.test.ts | 6 +- .../src/guides/dapp_testing.test.ts | 12 ++-- .../writing_an_account_contract.test.ts | 4 +- .../end-to-end/src/sample-dapp/index.mjs | 4 +- .../end-to-end/src/sample-dapp/index.test.mjs | 4 +- yarn-project/end-to-end/src/shared/browser.ts | 4 +- .../src/shared/cross_chain_test_harness.ts | 4 +- .../src/note_processor/note_processor.test.ts | 2 +- .../pxe/src/note_processor/note_processor.ts | 11 +--- .../pxe/src/pxe_service/pxe_service.ts | 4 +- .../pxe/src/simulator_oracle/index.ts | 22 +++---- yarn-project/types/src/interfaces/pxe.ts | 12 ++-- .../logs/l1_note_payload/l1_note_payload.ts | 6 +- .../src/logs/l1_note_payload/note.test.ts | 6 +- .../types/src/logs/l1_note_payload/note.ts | 2 +- yarn-project/types/src/mocks.ts | 4 +- yarn-project/types/src/notes/extended_note.ts | 30 ++++----- 29 files changed, 104 insertions(+), 147 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts index 4e242ecc5434..caf9d602d516 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts @@ -103,10 +103,10 @@ export class Oracle { return returnData.concat(paddedZeros); } - notifyCreatedNote([storageSlot]: ACVMField[], preimage: ACVMField[], [innerNoteHash]: ACVMField[]): ACVMField { + notifyCreatedNote([storageSlot]: ACVMField[], note: ACVMField[], [innerNoteHash]: ACVMField[]): ACVMField { this.typedOracle.notifyCreatedNote( fromACVMField(storageSlot), - preimage.map(fromACVMField), + note.map(fromACVMField), fromACVMField(innerNoteHash), ); return toACVMField(0); diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index a3b4d576933b..73dd1a4e4fa2 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -288,10 +288,10 @@ export class ClientExecutionContext extends ViewDataOracle { * @param preimage - The preimage of the note. */ public emitEncryptedLog(contractAddress: AztecAddress, storageSlot: Fr, publicKey: Point, preimage: Fr[]) { - const notePreimage = new Note(preimage); - const l1NotePayload = new L1NotePayload(notePreimage, contractAddress, storageSlot); - const encryptedNotePreimage = l1NotePayload.toEncryptedBuffer(publicKey, this.curve); - this.encryptedLogs.push(encryptedNotePreimage); + const note = new Note(preimage); + const l1NotePayload = new L1NotePayload(note, contractAddress, storageSlot); + const encryptedNote = l1NotePayload.toEncryptedBuffer(publicKey, this.curve); + this.encryptedLogs.push(encryptedNote); } /** diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 46521e35c606..2bd7b0a0e0a3 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -152,19 +152,14 @@ export class AcirSimulator { * @param contractAddress - The address of the contract. * @param nonce - The nonce of the note hash. * @param storageSlot - The storage slot. - * @param notePreimage - The note preimage. + * @param note - The note preimage. * @returns The nullifier. */ - public async computeNoteHashAndNullifier( - contractAddress: AztecAddress, - nonce: Fr, - storageSlot: Fr, - notePreimage: Fr[], - ) { + public async computeNoteHashAndNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { let artifact: FunctionArtifactWithDebugMetadata | undefined = undefined; // Brute force - for (let i = notePreimage.length; i < MAX_NOTE_FIELDS_LENGTH; i++) { + for (let i = note.length; i < MAX_NOTE_FIELDS_LENGTH; i++) { const signature = `compute_note_hash_and_nullifier(Field,Field,Field,[Field;${i}])`; const selector = FunctionSelector.fromSignature(signature); try { @@ -182,7 +177,7 @@ export class AcirSimulator { } const preimageLen = (artifact.parameters[3].type as ArrayType).length; - const extendedPreimage = notePreimage.concat(Array(preimageLen - notePreimage.length).fill(Fr.ZERO)); + const extendedPreimage = note.concat(Array(preimageLen - note.length).fill(Fr.ZERO)); const execRequest: FunctionCall = { to: AztecAddress.ZERO, @@ -208,16 +203,11 @@ export class AcirSimulator { * Computes the inner note hash of a note, which contains storage slot and the custom note hash. * @param contractAddress - The address of the contract. * @param storageSlot - The storage slot. - * @param notePreimage - The note preimage. + * @param note - The note preimage. * @returns The note hash. */ - public async computeInnerNoteHash(contractAddress: AztecAddress, storageSlot: Fr, notePreimage: Fr[]) { - const { innerNoteHash } = await this.computeNoteHashAndNullifier( - contractAddress, - Fr.ZERO, - storageSlot, - notePreimage, - ); + public async computeInnerNoteHash(contractAddress: AztecAddress, storageSlot: Fr, note: Fr[]) { + const { innerNoteHash } = await this.computeNoteHashAndNullifier(contractAddress, Fr.ZERO, storageSlot, note); return innerNoteHash; } @@ -226,21 +216,11 @@ export class AcirSimulator { * @param contractAddress - The address of the contract. * @param nonce - The nonce of the note hash. * @param storageSlot - The storage slot. - * @param notePreimage - The note preimage. + * @param note - The note preimage. * @returns The note hash. */ - public async computeUniqueSiloedNoteHash( - contractAddress: AztecAddress, - nonce: Fr, - storageSlot: Fr, - notePreimage: Fr[], - ) { - const { uniqueSiloedNoteHash } = await this.computeNoteHashAndNullifier( - contractAddress, - nonce, - storageSlot, - notePreimage, - ); + public async computeUniqueSiloedNoteHash(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { + const { uniqueSiloedNoteHash } = await this.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note); return uniqueSiloedNoteHash; } @@ -249,16 +229,11 @@ export class AcirSimulator { * @param contractAddress - The address of the contract. * @param nonce - The nonce of the note hash. * @param storageSlot - The storage slot. - * @param notePreimage - The note preimage. + * @param note - The note preimage. * @returns The note hash. */ - public async computeSiloedNoteHash(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, notePreimage: Fr[]) { - const { siloedNoteHash } = await this.computeNoteHashAndNullifier( - contractAddress, - nonce, - storageSlot, - notePreimage, - ); + public async computeSiloedNoteHash(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { + const { siloedNoteHash } = await this.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note); return siloedNoteHash; } @@ -267,16 +242,11 @@ export class AcirSimulator { * @param contractAddress - The address of the contract. * @param nonce - The nonce of the unique note hash. * @param storageSlot - The storage slot. - * @param notePreimage - The note preimage. + * @param note - The note preimage. * @returns The note hash. */ - public async computeInnerNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, notePreimage: Fr[]) { - const { innerNullifier } = await this.computeNoteHashAndNullifier( - contractAddress, - nonce, - storageSlot, - notePreimage, - ); + public async computeInnerNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { + const { innerNullifier } = await this.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note); return innerNullifier; } } diff --git a/yarn-project/aztec-sandbox/src/examples/token.ts b/yarn-project/aztec-sandbox/src/examples/token.ts index 82f85e8cd451..12349ec8ed29 100644 --- a/yarn-project/aztec-sandbox/src/examples/token.ts +++ b/yarn-project/aztec-sandbox/src/examples/token.ts @@ -2,7 +2,7 @@ import { AccountWallet, Fr, GrumpkinScalar, - NotePreimage, + Note, computeMessageSecretHash, createPXEClient, getUnsafeSchnorrAccount, @@ -56,7 +56,7 @@ async function main() { // Add the newly created "pending shield" note to PXE const pendingShieldsStorageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new NotePreimage([new Fr(ALICE_MINT_BALANCE), aliceSecretHash]); + const preimage = new Note([new Fr(ALICE_MINT_BALANCE), aliceSecretHash]); await pxe.addNote(alice.address, token.address, pendingShieldsStorageSlot, preimage, receipt.txHash); // Make the tokens spendable by redeeming them using the secret (converts the "pending shield note" created above diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index 51b1ece3df3c..f164c0663e8f 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -19,7 +19,7 @@ export { L2BlockL2Logs, LogFilter, NodeInfo, - Note as NotePreimage, + Note, PackedArguments, PublicKey, PXE, diff --git a/yarn-project/aztec.js/src/utils/cheat_codes.ts b/yarn-project/aztec.js/src/utils/cheat_codes.ts index a9119c632088..23f814d8f73e 100644 --- a/yarn-project/aztec.js/src/utils/cheat_codes.ts +++ b/yarn-project/aztec.js/src/utils/cheat_codes.ts @@ -288,7 +288,7 @@ export class AztecCheatCodes { * @returns The notes stored at the given slot */ public async loadPrivate(owner: AztecAddress, contract: AztecAddress, slot: Fr | bigint): Promise { - const notes = await this.pxe.getNotes({ owner, contractAddress: contract, storageSlot: new Fr(slot) }); - return notes.map(note => note.notePreimage); + const extendedNotes = await this.pxe.getNotes({ owner, contractAddress: contract, storageSlot: new Fr(slot) }); + return extendedNotes.map(extendedNote => extendedNote.note); } } diff --git a/yarn-project/boxes/token/src/tests/token.contract.test.ts b/yarn-project/boxes/token/src/tests/token.contract.test.ts index e0bda34fbfdb..0a5d75aef41a 100644 --- a/yarn-project/boxes/token/src/tests/token.contract.test.ts +++ b/yarn-project/boxes/token/src/tests/token.contract.test.ts @@ -3,7 +3,7 @@ import { TokenSimulator } from './token_simulator.js'; import { AccountWallet, Fr, - NotePreimage, + Note, PXE, TxHash, TxStatus, @@ -42,7 +42,7 @@ describe('e2e_token_contract', () => { const addPendingShieldNoteToPXE = async (accountIndex: number, amount: bigint, secretHash: Fr, txHash: TxHash) => { const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new NotePreimage([new Fr(amount), secretHash]); + const preimage = new Note([new Fr(amount), secretHash]); await wallets[accountIndex].addNote(accounts[0].address, asset.address, storageSlot, preimage, txHash); }; diff --git a/yarn-project/cli/src/index.ts b/yarn-project/cli/src/index.ts index fa72b0dc1b6d..1d0830208319 100644 --- a/yarn-project/cli/src/index.ts +++ b/yarn-project/cli/src/index.ts @@ -5,7 +5,7 @@ import { EthAddress, Fr, GrumpkinScalar, - NotePreimage, + Note, generatePublicKey, getSchnorrAccount, isContractDeployed, @@ -585,10 +585,10 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { .argument('', 'Aztec address of the contract.', parseAztecAddress) .argument('', 'The storage slot of the note.', parseField) .argument('', 'The tx hash of the tx containing the note.', parseTxHash) - .requiredOption('-p, --preimage [notePreimage...]', 'Note preimage.', []) + .requiredOption('-p, --preimage [note...]', 'Note preimage.', []) .addOption(pxeOption) .action(async (address, contractAddress, storageSlot, txHash, options) => { - const preimage = new NotePreimage(parseFields(options.preimage)); + const preimage = new Note(parseFields(options.preimage)); const client = await createCompatibleClient(options.rpcUrl, debugLogger); await client.addNote(address, contractAddress, storageSlot, preimage, txHash); }); diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index ae644c661708..aa6d35c72711 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -1,4 +1,4 @@ -import { AztecAddress, NotePreimage, Wallet, computeMessageSecretHash } from '@aztec/aztec.js'; +import { AztecAddress, Note, Wallet, computeMessageSecretHash } from '@aztec/aztec.js'; import { DebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; import { toBigInt } from '@aztec/foundation/serialize'; @@ -97,7 +97,7 @@ describe('e2e_2_pxes', () => { expect(receipt.status).toEqual(TxStatus.MINED); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(balance), secretHash]); + const preimage = new Note([new Fr(balance), secretHash]); await pxe.addNote(recipient, contract.address, storageSlot, preimage, receipt.txHash); expect((await contract.methods.redeem_shield(recipient, balance, secret).send().wait()).status).toEqual( diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index f693a074c821..41d26eebd6e7 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -2,7 +2,7 @@ import { AccountWallet, AztecAddress, BatchCall, - NotePreimage, + Note, computeMessageSecretHash, generatePublicKey, } from '@aztec/aztec.js'; @@ -66,7 +66,7 @@ describe('e2e_escrow_contract', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); - const preimage = new NotePreimage([new Fr(mintAmount), secretHash]); + const preimage = new Note([new Fr(mintAmount), secretHash]); await pxe.addNote(escrowContract.address, token.address, pendingShieldsStorageSlot, preimage, receipt.txHash); expect( @@ -112,7 +112,7 @@ describe('e2e_escrow_contract', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); - const preimage = new NotePreimage([new Fr(mintAmount), secretHash]); + const preimage = new Note([new Fr(mintAmount), secretHash]); await pxe.addNote(owner, token.address, pendingShieldsStorageSlot, preimage, receipt.txHash); expect((await token.methods.redeem_shield(owner, mintAmount, secret).send().wait()).status).toEqual(TxStatus.MINED); diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index 85cca3baeb0b..37e02e718e1f 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -1,6 +1,6 @@ import { AztecAddress, - NotePreimage, + Note, Wallet, computeMessageSecretHash, generatePublicKey, @@ -75,7 +75,7 @@ describe('e2e_multiple_accounts_1_enc_key', () => { expect(receipt.status).toEqual(TxStatus.MINED); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(initialBalance), secretHash]); + const preimage = new Note([new Fr(initialBalance), secretHash]); await pxe.addNote(accounts[0], token.address, storageSlot, preimage, receipt.txHash); expect((await token.methods.redeem_shield(accounts[0], initialBalance, secret).send().wait()).status).toEqual( diff --git a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts index 76a3e1d14f4f..766a423261fd 100644 --- a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts +++ b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts @@ -1,7 +1,7 @@ // docs:start:imports import { Fr, - NotePreimage, + Note, PXE, computeMessageSecretHash, createDebugLogger, @@ -76,7 +76,7 @@ describe('e2e_sandbox_example', () => { // Add the newly created "pending shield" note to PXE const pendingShieldsStorageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new NotePreimage([new Fr(initialSupply), aliceSecretHash]); + const preimage = new Note([new Fr(initialSupply), aliceSecretHash]); await pxe.addNote(alice, contract.address, pendingShieldsStorageSlot, preimage, receipt.txHash); // Make the tokens spendable by redeeming them using the secret (converts the "pending shield note" created above @@ -142,7 +142,7 @@ describe('e2e_sandbox_example', () => { logger(`Minting ${mintQuantity} tokens to Bob...`); const mintPrivateReceipt = await tokenContractBob.methods.mint_private(mintQuantity, bobSecretHash).send().wait(); - const bobPendingShield = new NotePreimage([new Fr(mintQuantity), bobSecretHash]); + const bobPendingShield = new Note([new Fr(mintQuantity), bobSecretHash]); await pxe.addNote(bob, contract.address, pendingShieldsStorageSlot, bobPendingShield, mintPrivateReceipt.txHash); await tokenContractBob.methods.redeem_shield(bob, mintQuantity, bobSecret).send().wait(); diff --git a/yarn-project/end-to-end/src/e2e_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_token_contract.test.ts index 58e7e5bf0020..a5439d835cc8 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract.test.ts @@ -1,6 +1,6 @@ import { AccountWallet, - NotePreimage, + Note, TxHash, TxStatus, computeAuthWitMessageHash, @@ -31,7 +31,7 @@ describe('e2e_token_contract', () => { const addPendingShieldNoteToPXE = async (accountIndex: number, amount: bigint, secretHash: Fr, txHash: TxHash) => { const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new NotePreimage([new Fr(amount), secretHash]); + const preimage = new Note([new Fr(amount), secretHash]); await wallets[accountIndex].addNote(accounts[0].address, asset.address, storageSlot, preimage, txHash); }; @@ -174,7 +174,7 @@ describe('e2e_token_contract', () => { // 1 note should be created containing `amount` of tokens const notes = receiptClaim.notes!; expect(notes.length).toBe(1); - expect(notes[0].notePreimage.items[0].toBigInt()).toBe(amount); + expect(notes[0].note.items[0].toBigInt()).toBe(amount); }); }); diff --git a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts index 61b5d7484471..717723f5f11e 100644 --- a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts +++ b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts @@ -3,7 +3,7 @@ import { AccountWallet, CheatCodes, Fr, - NotePreimage, + Note, PXE, computeMessageSecretHash, createAccount, @@ -48,7 +48,7 @@ describe('guides/dapp/testing', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(mintAmount), secretHash]); + const preimage = new Note([new Fr(mintAmount), secretHash]); await pxe.addNote(recipientAddress, token.address, storageSlot, preimage, receipt.txHash); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); @@ -87,7 +87,7 @@ describe('guides/dapp/testing', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new NotePreimage([new Fr(mintAmount), secretHash]); + const preimage = new Note([new Fr(mintAmount), secretHash]); await pxe.addNote(recipientAddress, token.address, storageSlot, preimage, receipt.txHash); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); @@ -119,7 +119,7 @@ describe('guides/dapp/testing', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(mintAmount), secretHash]); + const preimage = new Note([new Fr(mintAmount), secretHash]); await pxe.addNote(recipientAddress, token.address, storageSlot, preimage, receipt.txHash); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); @@ -172,7 +172,7 @@ describe('guides/dapp/testing', () => { const receipt = await token.methods.mint_private(100n, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(mintAmount), secretHash]); + const preimage = new Note([new Fr(mintAmount), secretHash]); await pxe.addNote(ownerAddress, token.address, storageSlot, preimage, receipt.txHash); await token.methods.redeem_shield(ownerAddress, 100n, secret).send().wait(); @@ -191,7 +191,7 @@ describe('guides/dapp/testing', () => { contractAddress: token.address, storageSlot: ownerSlot, }); - const values = notes.map(note => note.notePreimage.items[0]); + const values = notes.map(note => note.note.items[0]); const balance = values.reduce((sum, current) => sum + current.toBigInt(), 0n); expect(balance).toEqual(100n); // docs:end:private-storage diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index f7c7c2a7ca18..7622bbae3aa1 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -4,7 +4,7 @@ import { BaseAccountContract, CompleteAddress, Fr, - NotePreimage, + Note, computeMessageSecretHash, } from '@aztec/aztec.js'; import { GrumpkinPrivateKey, GrumpkinScalar } from '@aztec/circuits.js'; @@ -71,7 +71,7 @@ describe('guides/writing_an_account_contract', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(mintAmount), secretHash]); + const preimage = new Note([new Fr(mintAmount), secretHash]); await pxe.addNote(address, token.address, storageSlot, preimage, receipt.txHash); await token.methods.redeem_shield({ address }, mintAmount, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/sample-dapp/index.mjs b/yarn-project/end-to-end/src/sample-dapp/index.mjs index 3aad3e254b92..c2e7b5a67967 100644 --- a/yarn-project/end-to-end/src/sample-dapp/index.mjs +++ b/yarn-project/end-to-end/src/sample-dapp/index.mjs @@ -1,7 +1,7 @@ import { Fr, L2BlockL2Logs, - NotePreimage, + Note, computeMessageSecretHash, createPXEClient, getSandboxAccountsWallets, @@ -44,7 +44,7 @@ async function mintPrivateFunds(pxe) { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(mintAmount), secretHash]); + const preimage = new Note([new Fr(mintAmount), secretHash]); await pxe.addNote(owner.getAddress(), token.address, storageSlot, preimage, receipt.txHash); await token.methods.redeem_shield(owner.getAddress(), mintAmount, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/sample-dapp/index.test.mjs b/yarn-project/end-to-end/src/sample-dapp/index.test.mjs index 76b8f3019dea..144e1ad75023 100644 --- a/yarn-project/end-to-end/src/sample-dapp/index.test.mjs +++ b/yarn-project/end-to-end/src/sample-dapp/index.test.mjs @@ -1,5 +1,5 @@ import { createSandbox } from '@aztec/aztec-sandbox'; -import { Contract, Fr, NotePreimage, computeMessageSecretHash, createAccount } from '@aztec/aztec.js'; +import { Contract, Fr, Note, computeMessageSecretHash, createAccount } from '@aztec/aztec.js'; import { TokenContractArtifact } from '@aztec/noir-contracts/artifacts'; describe('token', () => { @@ -18,7 +18,7 @@ describe('token', () => { const receipt = await token.methods.mint_private(initialBalance, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(initialBalance), secretHash]); + const preimage = new Note([new Fr(initialBalance), secretHash]); await pxe.addNote(owner.getAddress(), token.address, storageSlot, preimage, receipt.txHash); await token.methods.redeem_shield({ address: owner.getAddress() }, initialBalance, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/shared/browser.ts b/yarn-project/end-to-end/src/shared/browser.ts index e876272feb7e..f2b00a45f70f 100644 --- a/yarn-project/end-to-end/src/shared/browser.ts +++ b/yarn-project/end-to-end/src/shared/browser.ts @@ -175,7 +175,7 @@ export const browserTestSuite = (setup: () => Server, pageLogger: AztecJs.DebugL getUnsafeSchnorrAccount, Contract, Fr, - NotePreimage, + Note, computeMessageSecretHash, getSandboxAccountsWallets, } = window.AztecJs; @@ -202,7 +202,7 @@ export const browserTestSuite = (setup: () => Server, pageLogger: AztecJs.DebugL const mintPrivateReceipt = await token.methods.mint_private(initialBalance, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(initialBalance), secretHash]); + const preimage = new Note([new Fr(initialBalance), secretHash]); await pxe.addNote(ownerAddress, token.address, storageSlot, preimage, mintPrivateReceipt.txHash); await token.methods.redeem_shield(ownerAddress, initialBalance, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index e76d58caab9f..2e07540575ad 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -4,7 +4,7 @@ import { DebugLogger, EthAddress, Fr, - NotePreimage, + Note, PXE, TxHash, TxStatus, @@ -411,7 +411,7 @@ export class CrossChainTestHarness { async addPendingShieldNoteToPXE(shieldAmount: bigint, secretHash: Fr, txHash: TxHash) { this.logger('Adding note to PXE'); const storageSlot = new Fr(5); - const preimage = new NotePreimage([new Fr(shieldAmount), secretHash]); + const preimage = new Note([new Fr(shieldAmount), secretHash]); await this.pxeService.addNote(this.ownerAddress, this.l2Token.address, storageSlot, preimage, txHash); } 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 684ee55ac38b..55a4cf937f0b 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -106,7 +106,7 @@ describe('Note Processor', () => { } = createEncryptedLogsAndOwnedL1NotePayloads(isTargetBlock ? ownedData : [], isTargetBlock ? ownedNotes : []); encryptedLogsArr.push(encryptedLogs); ownedL1NotePayloads.push(...payloads); - block.newCommitments = newNotes.map(n => computeMockNoteHash(n.notePreimage.items)); + block.newCommitments = newNotes.map(n => computeMockNoteHash(n.note.items)); const randomBlockContext = new L2BlockContext(block); blockContexts.push(randomBlockContext); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 4acae9f4d2de..f43545126ae8 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -149,7 +149,7 @@ export class NoteProcessor { excludedIndices.add(commitmentIndex); extendedNotes.push( new ExtendedNote( - payload.notePreimage, + payload.note, payload.contractAddress, blockContext.getTxHash(indexOfTxInABlock), nonce, @@ -200,7 +200,7 @@ export class NoteProcessor { private async findNoteIndexAndNullifier( commitments: Fr[], firstNullifier: Fr, - { contractAddress, storageSlot, notePreimage }: L1NotePayload, + { contractAddress, storageSlot, note }: L1NotePayload, excludedIndices: Set, ) { const wasm = await CircuitsWasm.get(); @@ -218,12 +218,7 @@ export class NoteProcessor { const expectedNonce = computeCommitmentNonce(wasm, firstNullifier, commitmentIndex); ({ innerNoteHash, siloedNoteHash, uniqueSiloedNoteHash, innerNullifier } = - await this.simulator.computeNoteHashAndNullifier( - contractAddress, - expectedNonce, - storageSlot, - notePreimage.items, - )); + await this.simulator.computeNoteHashAndNullifier(contractAddress, expectedNonce, storageSlot, note.items)); if (commitment.equals(uniqueSiloedNoteHash)) { nonce = expectedNonce; break; diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index a9453f9e0632..d18ff7c00115 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -254,7 +254,7 @@ export class PXEService implements PXE { public async getNoteNonces( contractAddress: AztecAddress, storageSlot: Fr, - preimage: Note, + note: Note, txHash: TxHash, ): Promise { const tx = await this.node.getTx(txHash); @@ -276,7 +276,7 @@ export class PXEService implements PXE { contractAddress, nonce, storageSlot, - preimage.items, + note.items, ); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) // Remove this once notes added from public also include nonces. diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 7461ffa32e37..8efe31577c4c 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -46,18 +46,16 @@ export class SimulatorOracle implements DBOracle { async getNotes(contractAddress: AztecAddress, storageSlot: Fr) { const noteDaos = await this.db.getExtendedNotes({ contractAddress, storageSlot }); - return noteDaos.map( - ({ contractAddress, storageSlot, nonce, notePreimage, innerNoteHash, siloedNullifier, index }) => ({ - contractAddress, - storageSlot, - nonce, - preimage: notePreimage.items, - innerNoteHash, - siloedNullifier, - // PXE can use this index to get full MembershipWitness - index, - }), - ); + return noteDaos.map(({ contractAddress, storageSlot, nonce, note, innerNoteHash, siloedNullifier, index }) => ({ + contractAddress, + storageSlot, + nonce, + preimage: note.items, + innerNoteHash, + siloedNullifier, + // PXE can use this index to get full MembershipWitness + index, + })); } async getFunctionArtifact( diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index 6f2ead7ed7be..4489811e88c5 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -172,7 +172,7 @@ export interface PXE { * @param account - The account the note is associated with. * @param contract - The contract address of the note. * @param storageSlot - The storage slot of the note. - * @param preimage - The note preimage. + * @param note - The note to add. * @param txHash - The tx hash of the tx containing the note. * @param nonce - The nonce of the note. If undefined, will look for the first index that matches the preimage. */ @@ -180,21 +180,21 @@ export interface PXE { account: AztecAddress, contract: AztecAddress, storageSlot: Fr, - preimage: Note, + note: Note, txHash: TxHash, nonce?: Fr, ): Promise; /** - * Finds the nonce(s) for a note in a tx with given preimage at a specified contract address and storage slot. + * Finds the nonce(s) for a note in a tx with given a note at a specified contract address and storage slot. * @param contract - The contract address of the note. * @param storageSlot - The storage slot of the note. - * @param preimage - The note preimage. + * @param note - The note as emitted from Noir contract. * @param txHash - The tx hash of the tx containing the note. * @returns The nonces of the note. - * @remarks More than single nonce may be returned since there might be more than one note with the same preimage. + * @remarks More than single nonce may be returned since there might be more than one nonce for a given note. */ - getNoteNonces(contract: AztecAddress, storageSlot: Fr, preimage: Note, txHash: TxHash): Promise; + getNoteNonces(contract: AztecAddress, storageSlot: Fr, note: Note, txHash: TxHash): Promise; /** * Simulate the execution of a view (read-only) function on a deployed contract without actually modifying state. diff --git a/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts b/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts index dbb4329408b9..f543fc0cfc6d 100644 --- a/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts +++ b/yarn-project/types/src/logs/l1_note_payload/l1_note_payload.ts @@ -15,9 +15,9 @@ import { Note } from './note.js'; export class L1NotePayload { constructor( /** - * Preimage which can be used along with private key to compute nullifier. + * A note as emitted from Noir contract. Can be used along with private key to compute nullifier. */ - public notePreimage: Note, + public note: Note, /** * Address of the contract this tx is interacting with. */ @@ -43,7 +43,7 @@ export class L1NotePayload { * @returns Buffer representation of the L1NotePayload object. */ toBuffer() { - return serializeToBuffer([this.notePreimage, this.contractAddress, this.storageSlot]); + return serializeToBuffer([this.note, this.contractAddress, this.storageSlot]); } /** diff --git a/yarn-project/types/src/logs/l1_note_payload/note.test.ts b/yarn-project/types/src/logs/l1_note_payload/note.test.ts index 82d79d37ec9c..fd55db8121bf 100644 --- a/yarn-project/types/src/logs/l1_note_payload/note.test.ts +++ b/yarn-project/types/src/logs/l1_note_payload/note.test.ts @@ -5,8 +5,8 @@ import { Note } from './note.js'; describe('note', () => { it('convert to and from buffer', () => { const fields = Array.from({ length: 5 }).map(() => Fr.random()); - const notePreimage = new Note(fields); - const buf = notePreimage.toBuffer(); - expect(Note.fromBuffer(buf)).toEqual(notePreimage); + const note = new Note(fields); + const buf = note.toBuffer(); + expect(Note.fromBuffer(buf)).toEqual(note); }); }); diff --git a/yarn-project/types/src/logs/l1_note_payload/note.ts b/yarn-project/types/src/logs/l1_note_payload/note.ts index 4d0bdb17b240..9bc9e066efd1 100644 --- a/yarn-project/types/src/logs/l1_note_payload/note.ts +++ b/yarn-project/types/src/logs/l1_note_payload/note.ts @@ -35,7 +35,7 @@ export class Note extends Vector { } /** - * Returns a hex representation of this preimage. + * Returns a hex representation of the note. * @returns A hex string with the vector length as first element. */ toString() { diff --git a/yarn-project/types/src/mocks.ts b/yarn-project/types/src/mocks.ts index 57f7b397f1db..1a0dcf73b8ab 100644 --- a/yarn-project/types/src/mocks.ts +++ b/yarn-project/types/src/mocks.ts @@ -55,7 +55,7 @@ export const randomDeployedContract = async (): Promise => ({ }); export const randomExtendedNote = ({ - notePreimage = Note.random(), + note = Note.random(), contractAddress = AztecAddress.random(), txHash = randomTxHash(), nonce = Fr.random(), @@ -66,7 +66,7 @@ export const randomExtendedNote = ({ publicKey = Point.random(), }: Partial = {}) => { return new ExtendedNote( - notePreimage, + note, contractAddress, txHash, nonce, diff --git a/yarn-project/types/src/notes/extended_note.ts b/yarn-project/types/src/notes/extended_note.ts index c3075039c65d..2ee8cc5ec7a1 100644 --- a/yarn-project/types/src/notes/extended_note.ts +++ b/yarn-project/types/src/notes/extended_note.ts @@ -7,8 +7,8 @@ import { BufferReader, Note, TxHash } from '@aztec/types'; */ export class ExtendedNote { constructor( - /** The preimage of the note, containing essential information about the note. */ - public notePreimage: Note, + /** The note as emitted from the Noir contract. */ + public note: Note, /** The contract address this note is created in. */ public contractAddress: AztecAddress, /** The hash of the tx the note was created in. */ @@ -22,23 +22,17 @@ export class ExtendedNote { * We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash. */ public innerNoteHash: Fr, - /** - * The nullifier of the note (siloed by contract address). - */ + /** The nullifier of the note (siloed by contract address). */ public siloedNullifier: Fr, - /** - * The location of the relevant note in the note hash tree. - */ + /** The location of the relevant note in the note hash tree. */ public index: bigint, - /** - * The public key that was used to encrypt the data. - */ + /** The public key that was used to encrypt the data. */ public publicKey: PublicKey, ) {} toBuffer(): Buffer { return Buffer.concat([ - this.notePreimage.toBuffer(), + this.note.toBuffer(), this.contractAddress.toBuffer(), this.txHash.buffer, this.nonce.toBuffer(), @@ -52,7 +46,7 @@ export class ExtendedNote { static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - const notePreimage = Note.fromBuffer(reader); + const note = Note.fromBuffer(reader); const contractAddress = AztecAddress.fromBuffer(reader); const txHash = new TxHash(reader.readBytes(TxHash.SIZE)); const nonce = Fr.fromBuffer(reader); @@ -63,7 +57,7 @@ export class ExtendedNote { const publicKey = Point.fromBuffer(reader); return new this( - notePreimage, + note, contractAddress, txHash, nonce, @@ -86,14 +80,14 @@ export class ExtendedNote { /** * Returns the size in bytes of the extended note. - * @param note - The note. + * @param extendedNote - The extended note. * @returns - Its size in bytes. */ - public getSize(note: ExtendedNote) { + public getSize(extendedNote: ExtendedNote) { // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer - const indexSize = Math.ceil(Math.log2(Number(note.index))); + const indexSize = Math.ceil(Math.log2(Number(extendedNote.index))); return ( - note.notePreimage.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize + Point.SIZE_IN_BYTES + extendedNote.note.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize + Point.SIZE_IN_BYTES ); } } From 78393ee3270e84db458619045c356438fbb1983e Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 06:45:43 +0000 Subject: [PATCH 18/41] WIP on renaming preimage --- .../acir-simulator/src/client/simulator.ts | 10 +++++----- yarn-project/aztec-sandbox/src/examples/token.ts | 4 ++-- .../boxes/token/src/tests/token.contract.test.ts | 4 ++-- yarn-project/cli/src/index.ts | 6 +++--- yarn-project/end-to-end/src/e2e_2_pxes.test.ts | 4 ++-- .../end-to-end/src/e2e_escrow_contract.test.ts | 8 ++++---- .../end-to-end/src/e2e_lending_contract.test.ts | 4 ++-- .../src/e2e_multiple_accounts_1_enc_key.test.ts | 4 ++-- .../end-to-end/src/e2e_sandbox_example.test.ts | 4 ++-- .../end-to-end/src/e2e_token_contract.test.ts | 4 ++-- .../end-to-end/src/guides/dapp_testing.test.ts | 16 ++++++++-------- .../guides/writing_an_account_contract.test.ts | 4 ++-- .../end-to-end/src/sample-dapp/index.mjs | 4 ++-- .../end-to-end/src/sample-dapp/index.test.mjs | 4 ++-- yarn-project/end-to-end/src/shared/browser.ts | 4 ++-- .../src/shared/cross_chain_test_harness.ts | 4 ++-- 16 files changed, 44 insertions(+), 44 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 2bd7b0a0e0a3..91e8a2aad097 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -152,7 +152,7 @@ export class AcirSimulator { * @param contractAddress - The address of the contract. * @param nonce - The nonce of the note hash. * @param storageSlot - The storage slot. - * @param note - The note preimage. + * @param note - The note. * @returns The nullifier. */ public async computeNoteHashAndNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { @@ -203,7 +203,7 @@ export class AcirSimulator { * Computes the inner note hash of a note, which contains storage slot and the custom note hash. * @param contractAddress - The address of the contract. * @param storageSlot - The storage slot. - * @param note - The note preimage. + * @param note - The note. * @returns The note hash. */ public async computeInnerNoteHash(contractAddress: AztecAddress, storageSlot: Fr, note: Fr[]) { @@ -216,7 +216,7 @@ export class AcirSimulator { * @param contractAddress - The address of the contract. * @param nonce - The nonce of the note hash. * @param storageSlot - The storage slot. - * @param note - The note preimage. + * @param note - The note. * @returns The note hash. */ public async computeUniqueSiloedNoteHash(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { @@ -229,7 +229,7 @@ export class AcirSimulator { * @param contractAddress - The address of the contract. * @param nonce - The nonce of the note hash. * @param storageSlot - The storage slot. - * @param note - The note preimage. + * @param note - The note. * @returns The note hash. */ public async computeSiloedNoteHash(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { @@ -242,7 +242,7 @@ export class AcirSimulator { * @param contractAddress - The address of the contract. * @param nonce - The nonce of the unique note hash. * @param storageSlot - The storage slot. - * @param note - The note preimage. + * @param note - The note. * @returns The note hash. */ public async computeInnerNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { diff --git a/yarn-project/aztec-sandbox/src/examples/token.ts b/yarn-project/aztec-sandbox/src/examples/token.ts index 12349ec8ed29..4cb22e6a7fdf 100644 --- a/yarn-project/aztec-sandbox/src/examples/token.ts +++ b/yarn-project/aztec-sandbox/src/examples/token.ts @@ -56,8 +56,8 @@ async function main() { // Add the newly created "pending shield" note to PXE const pendingShieldsStorageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new Note([new Fr(ALICE_MINT_BALANCE), aliceSecretHash]); - await pxe.addNote(alice.address, token.address, pendingShieldsStorageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(ALICE_MINT_BALANCE), aliceSecretHash]); + await pxe.addNote(alice.address, token.address, pendingShieldsStorageSlot, note, receipt.txHash); // Make the tokens spendable by redeeming them using the secret (converts the "pending shield note" created above // to a "token note") diff --git a/yarn-project/boxes/token/src/tests/token.contract.test.ts b/yarn-project/boxes/token/src/tests/token.contract.test.ts index 0a5d75aef41a..eda449643d3d 100644 --- a/yarn-project/boxes/token/src/tests/token.contract.test.ts +++ b/yarn-project/boxes/token/src/tests/token.contract.test.ts @@ -42,8 +42,8 @@ describe('e2e_token_contract', () => { const addPendingShieldNoteToPXE = async (accountIndex: number, amount: bigint, secretHash: Fr, txHash: TxHash) => { const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new Note([new Fr(amount), secretHash]); - await wallets[accountIndex].addNote(accounts[0].address, asset.address, storageSlot, preimage, txHash); + const note = new Note([new Fr(amount), secretHash]); + await wallets[accountIndex].addNote(accounts[0].address, asset.address, storageSlot, note, txHash); }; beforeAll(async () => { diff --git a/yarn-project/cli/src/index.ts b/yarn-project/cli/src/index.ts index 1d0830208319..0a7b22e79e3d 100644 --- a/yarn-project/cli/src/index.ts +++ b/yarn-project/cli/src/index.ts @@ -585,12 +585,12 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { .argument('', 'Aztec address of the contract.', parseAztecAddress) .argument('', 'The storage slot of the note.', parseField) .argument('', 'The tx hash of the tx containing the note.', parseTxHash) - .requiredOption('-p, --preimage [note...]', 'Note preimage.', []) + .requiredOption('-n, --note [note...]', 'The members of a Note serialized as hex strings.', []) .addOption(pxeOption) .action(async (address, contractAddress, storageSlot, txHash, options) => { - const preimage = new Note(parseFields(options.preimage)); + const note = new Note(parseFields(options.note)); const client = await createCompatibleClient(options.rpcUrl, debugLogger); - await client.addNote(address, contractAddress, storageSlot, preimage, txHash); + await client.addNote(address, contractAddress, storageSlot, note, txHash); }); // Helper for users to decode hex strings into structs if needed. diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index aa6d35c72711..a4493366d670 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -97,8 +97,8 @@ describe('e2e_2_pxes', () => { expect(receipt.status).toEqual(TxStatus.MINED); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(balance), secretHash]); - await pxe.addNote(recipient, contract.address, storageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(balance), secretHash]); + await pxe.addNote(recipient, contract.address, storageSlot, note, receipt.txHash); expect((await contract.methods.redeem_shield(recipient, balance, secret).send().wait()).status).toEqual( TxStatus.MINED, diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index 41d26eebd6e7..4a80cfa1830c 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -66,8 +66,8 @@ describe('e2e_escrow_contract', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); - const preimage = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(escrowContract.address, token.address, pendingShieldsStorageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(mintAmount), secretHash]); + await pxe.addNote(escrowContract.address, token.address, pendingShieldsStorageSlot, note, receipt.txHash); expect( (await token.methods.redeem_shield(escrowContract.address, mintAmount, secret).send().wait()).status, @@ -112,8 +112,8 @@ describe('e2e_escrow_contract', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); - const preimage = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(owner, token.address, pendingShieldsStorageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(mintAmount), secretHash]); + await pxe.addNote(owner, token.address, pendingShieldsStorageSlot, note, receipt.txHash); expect((await token.methods.redeem_shield(owner, mintAmount, secret).send().wait()).status).toEqual(TxStatus.MINED); diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 0484130ff93d..a5e43cedb0b0 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -120,9 +120,9 @@ describe('e2e_lending_contract', () => { await Promise.all([a, b].map(waitForSuccess)); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(mintAmount), secretHash]); + const note = new Note([new Fr(mintAmount), secretHash]); const txHash = await b.getTxHash(); - await wallet.addNote(accounts[0].address, asset.address, storageSlot, preimage, txHash); + await wallet.addNote(accounts[0].address, asset.address, storageSlot, note, txHash); await waitForSuccess(asset.methods.redeem_shield(lendingAccount.address, mintAmount, secret).send()); } diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index 37e02e718e1f..b50512897ac0 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -75,8 +75,8 @@ describe('e2e_multiple_accounts_1_enc_key', () => { expect(receipt.status).toEqual(TxStatus.MINED); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(initialBalance), secretHash]); - await pxe.addNote(accounts[0], token.address, storageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(initialBalance), secretHash]); + await pxe.addNote(accounts[0], token.address, storageSlot, note, receipt.txHash); expect((await token.methods.redeem_shield(accounts[0], initialBalance, secret).send().wait()).status).toEqual( TxStatus.MINED, diff --git a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts index 766a423261fd..a4f94ba61bc3 100644 --- a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts +++ b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts @@ -76,8 +76,8 @@ describe('e2e_sandbox_example', () => { // Add the newly created "pending shield" note to PXE const pendingShieldsStorageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new Note([new Fr(initialSupply), aliceSecretHash]); - await pxe.addNote(alice, contract.address, pendingShieldsStorageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(initialSupply), aliceSecretHash]); + await pxe.addNote(alice, contract.address, pendingShieldsStorageSlot, note, receipt.txHash); // Make the tokens spendable by redeeming them using the secret (converts the "pending shield note" created above // to a "token note") diff --git a/yarn-project/end-to-end/src/e2e_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_token_contract.test.ts index a5439d835cc8..a043e5545d00 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract.test.ts @@ -31,8 +31,8 @@ describe('e2e_token_contract', () => { const addPendingShieldNoteToPXE = async (accountIndex: number, amount: bigint, secretHash: Fr, txHash: TxHash) => { const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new Note([new Fr(amount), secretHash]); - await wallets[accountIndex].addNote(accounts[0].address, asset.address, storageSlot, preimage, txHash); + const note = new Note([new Fr(amount), secretHash]); + await wallets[accountIndex].addNote(accounts[0].address, asset.address, storageSlot, note, txHash); }; beforeAll(async () => { diff --git a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts index 717723f5f11e..06398b5cd497 100644 --- a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts +++ b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts @@ -48,8 +48,8 @@ describe('guides/dapp/testing', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(recipientAddress, token.address, storageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(mintAmount), secretHash]); + await pxe.addNote(recipientAddress, token.address, storageSlot, note, receipt.txHash); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); expect(await token.methods.balance_of_private(recipientAddress).view()).toEqual(20n); @@ -87,8 +87,8 @@ describe('guides/dapp/testing', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. - const preimage = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(recipientAddress, token.address, storageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(mintAmount), secretHash]); + await pxe.addNote(recipientAddress, token.address, storageSlot, note, receipt.txHash); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); expect(await token.methods.balance_of_private(recipientAddress).view()).toEqual(20n); @@ -119,8 +119,8 @@ describe('guides/dapp/testing', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(recipientAddress, token.address, storageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(mintAmount), secretHash]); + await pxe.addNote(recipientAddress, token.address, storageSlot, note, receipt.txHash); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); expect(await token.methods.balance_of_private(recipientAddress).view()).toEqual(20n); @@ -172,8 +172,8 @@ describe('guides/dapp/testing', () => { const receipt = await token.methods.mint_private(100n, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(ownerAddress, token.address, storageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(mintAmount), secretHash]); + await pxe.addNote(ownerAddress, token.address, storageSlot, note, receipt.txHash); await token.methods.redeem_shield(ownerAddress, 100n, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index 7622bbae3aa1..a5b3bc6b40c1 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -71,8 +71,8 @@ describe('guides/writing_an_account_contract', () => { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(address, token.address, storageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(mintAmount), secretHash]); + await pxe.addNote(address, token.address, storageSlot, note, receipt.txHash); await token.methods.redeem_shield({ address }, mintAmount, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/sample-dapp/index.mjs b/yarn-project/end-to-end/src/sample-dapp/index.mjs index c2e7b5a67967..7318dd22a8c5 100644 --- a/yarn-project/end-to-end/src/sample-dapp/index.mjs +++ b/yarn-project/end-to-end/src/sample-dapp/index.mjs @@ -44,8 +44,8 @@ async function mintPrivateFunds(pxe) { const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(owner.getAddress(), token.address, storageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(mintAmount), secretHash]); + await pxe.addNote(owner.getAddress(), token.address, storageSlot, note, receipt.txHash); await token.methods.redeem_shield(owner.getAddress(), mintAmount, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/sample-dapp/index.test.mjs b/yarn-project/end-to-end/src/sample-dapp/index.test.mjs index 144e1ad75023..ff54db4b24cb 100644 --- a/yarn-project/end-to-end/src/sample-dapp/index.test.mjs +++ b/yarn-project/end-to-end/src/sample-dapp/index.test.mjs @@ -18,8 +18,8 @@ describe('token', () => { const receipt = await token.methods.mint_private(initialBalance, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(initialBalance), secretHash]); - await pxe.addNote(owner.getAddress(), token.address, storageSlot, preimage, receipt.txHash); + const note = new Note([new Fr(initialBalance), secretHash]); + await pxe.addNote(owner.getAddress(), token.address, storageSlot, note, receipt.txHash); await token.methods.redeem_shield({ address: owner.getAddress() }, initialBalance, secret).send().wait(); }, 120_000); diff --git a/yarn-project/end-to-end/src/shared/browser.ts b/yarn-project/end-to-end/src/shared/browser.ts index f2b00a45f70f..3287c03f61ad 100644 --- a/yarn-project/end-to-end/src/shared/browser.ts +++ b/yarn-project/end-to-end/src/shared/browser.ts @@ -202,8 +202,8 @@ export const browserTestSuite = (setup: () => Server, pageLogger: AztecJs.DebugL const mintPrivateReceipt = await token.methods.mint_private(initialBalance, secretHash).send().wait(); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(initialBalance), secretHash]); - await pxe.addNote(ownerAddress, token.address, storageSlot, preimage, mintPrivateReceipt.txHash); + const note = new Note([new Fr(initialBalance), secretHash]); + await pxe.addNote(ownerAddress, token.address, storageSlot, note, mintPrivateReceipt.txHash); await token.methods.redeem_shield(ownerAddress, initialBalance, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 2e07540575ad..8da780de8b45 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -411,8 +411,8 @@ export class CrossChainTestHarness { async addPendingShieldNoteToPXE(shieldAmount: bigint, secretHash: Fr, txHash: TxHash) { this.logger('Adding note to PXE'); const storageSlot = new Fr(5); - const preimage = new Note([new Fr(shieldAmount), secretHash]); - await this.pxeService.addNote(this.ownerAddress, this.l2Token.address, storageSlot, preimage, txHash); + const note = new Note([new Fr(shieldAmount), secretHash]); + await this.pxeService.addNote(this.ownerAddress, this.l2Token.address, storageSlot, note, txHash); } async redeemShieldPrivatelyOnL2(shieldAmount: bigint, secret: Fr) { From 75dbb5e1e6edf0f69563e9f220991af4bcd54535 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 07:25:00 +0000 Subject: [PATCH 19/41] WIP --- .../acir-simulator/src/acvm/oracle/oracle.ts | 16 ++-- .../src/acvm/oracle/typed_oracle.ts | 4 +- .../src/client/client_execution_context.ts | 17 ++-- .../src/client/execution_result.ts | 10 +-- .../src/client/pick_notes.test.ts | 13 ++-- .../acir-simulator/src/client/pick_notes.ts | 13 ++-- .../src/client/private_execution.test.ts | 78 +++++++++---------- .../acir-simulator/src/client/simulator.ts | 16 ++-- .../client/unconstrained_execution.test.ts | 10 +-- .../src/kernel_prover/kernel_prover.test.ts | 20 ++--- .../pxe/src/kernel_prover/kernel_prover.ts | 4 +- .../src/note_processor/note_processor.test.ts | 7 +- .../pxe/src/note_processor/note_processor.ts | 2 +- .../pxe/src/pxe_service/pxe_service.ts | 10 +-- .../pxe/src/simulator_oracle/index.ts | 2 +- .../types/src/logs/l1_note_payload/note.ts | 4 + 16 files changed, 117 insertions(+), 109 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts index caf9d602d516..2720c1b027b0 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts @@ -64,7 +64,7 @@ export class Oracle { [offset]: ACVMField[], [returnSize]: ACVMField[], ): Promise { - const notes = await this.typedOracle.getNotes( + const noteDatas = await this.typedOracle.getNotes( fromACVMField(storageSlot), +numSelects, selectBy.map(s => +s), @@ -75,26 +75,26 @@ export class Oracle { +offset, ); - const preimageLength = notes?.[0]?.preimage.length ?? 0; - if (!notes.every(({ preimage }) => preimageLength === preimage.length)) { - throw new Error('Preimages for a particular note type should all be the same length.'); + const noteLength = noteDatas?.[0]?.note.items.length ?? 0; + if (!noteDatas.every(({ note }) => noteLength === note.items.length)) { + throw new Error('Notes should all be the same length.'); } - const contractAddress = notes[0]?.contractAddress ?? Fr.ZERO; + const contractAddress = noteDatas[0]?.contractAddress ?? Fr.ZERO; // Values indicates whether the note is settled or transient. const noteTypes = { isSettled: new Fr(0), isTransient: new Fr(1), }; - const flattenData = notes.flatMap(({ nonce, preimage, index }) => [ + const flattenData = noteDatas.flatMap(({ nonce, note, index }) => [ nonce, index === undefined ? noteTypes.isTransient : noteTypes.isSettled, - ...preimage, + ...note.items, ]); const returnFieldSize = +returnSize; - const returnData = [notes.length, contractAddress, ...flattenData].map(v => toACVMField(v)); + const returnData = [noteDatas.length, contractAddress, ...flattenData].map(v => toACVMField(v)); if (returnData.length > returnFieldSize) { throw new Error(`Return data size too big. Maximum ${returnFieldSize} fields. Got ${flattenData.length}.`); } diff --git a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts index a07f03e6ef22..b3e22d8161d6 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts @@ -3,7 +3,7 @@ import { FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; -import { CompleteAddress, PublicKey, UnencryptedL2Log } from '@aztec/types'; +import { CompleteAddress, Note, PublicKey, UnencryptedL2Log } from '@aztec/types'; /** * Information about a note needed during execution. @@ -16,7 +16,7 @@ export interface NoteData { /** The nonce of the note. */ nonce: Fr; /** The preimage of the note */ - preimage: Fr[]; + note: Note; /** The inner note hash of the note. */ innerNoteHash: Fr; /** The corresponding nullifier of the note. Undefined for pending notes. */ diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 73dd1a4e4fa2..1f1d6775d14f 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -28,7 +28,7 @@ import { SideEffectCounter } from '../common/index.js'; import { PackedArgsCache } from '../common/packed_args_cache.js'; import { DBOracle } from './db_oracle.js'; import { ExecutionNoteCache } from './execution_note_cache.js'; -import { ExecutionResult, NewNoteData } from './execution_result.js'; +import { ExecutionResult, NoteAndSlot } from './execution_result.js'; import { pickNotes } from './pick_notes.js'; import { executePrivateFunction } from './private_execution.js'; import { ViewDataOracle } from './view_data_oracle.js'; @@ -44,7 +44,7 @@ export class ClientExecutionContext extends ViewDataOracle { * This information is only for references (currently used for tests), and is not used for any sort of constrains. * Users can also use this to get a clearer idea of what's happened during a simulation. */ - private newNotes: NewNoteData[] = []; + private newNotes: NoteAndSlot[] = []; /** * Notes from previous transactions that are returned to the oracle call `getNotes` during this execution. * The mapping maps from the unique siloed note hash to the index for notes created in private executions. @@ -135,7 +135,7 @@ export class ClientExecutionContext extends ViewDataOracle { * Get the data for the newly created notes. * @param innerNoteHashes - Inner note hashes for the notes. */ - public getNewNotes(): NewNoteData[] { + public getNewNotes(): NoteAndSlot[] { return this.newNotes; } @@ -227,7 +227,7 @@ export class ClientExecutionContext extends ViewDataOracle { this.log( `Returning ${notes.length} notes for ${this.contractAddress} at ${storageSlot}: ${notes - .map(n => `${n.nonce.toString()}:[${n.preimage.map(i => i.toString()).join(',')}]`) + .map(n => `${n.nonce.toString()}:[${n.note.items.map(i => i.toString()).join(',')}]`) .join(', ')}`, ); @@ -251,22 +251,23 @@ export class ClientExecutionContext extends ViewDataOracle { * It can be used in subsequent calls (or transactions when chaining txs is possible). * @param contractAddress - The contract address. * @param storageSlot - The storage slot. - * @param preimage - The preimage of the new note. + * @param noteItems - The items to be included in a Note. * @param innerNoteHash - The inner note hash of the new note. * @returns */ - public notifyCreatedNote(storageSlot: Fr, preimage: Fr[], innerNoteHash: Fr) { + public notifyCreatedNote(storageSlot: Fr, noteItems: Fr[], innerNoteHash: Fr) { + const note = new Note(noteItems); this.noteCache.addNewNote({ contractAddress: this.contractAddress, storageSlot, nonce: Fr.ZERO, // Nonce cannot be known during private execution. - preimage, + note, siloedNullifier: undefined, // Siloed nullifier cannot be known for newly created note. innerNoteHash, }); this.newNotes.push({ storageSlot, - preimage, + note, }); } diff --git a/yarn-project/acir-simulator/src/client/execution_result.ts b/yarn-project/acir-simulator/src/client/execution_result.ts index bf2b738953ea..8dc812ee963d 100644 --- a/yarn-project/acir-simulator/src/client/execution_result.ts +++ b/yarn-project/acir-simulator/src/client/execution_result.ts @@ -1,16 +1,16 @@ import { PrivateCallStackItem, PublicCallRequest, ReadRequestMembershipWitness } from '@aztec/circuits.js'; import { DecodedReturn } from '@aztec/foundation/abi'; import { Fr } from '@aztec/foundation/fields'; -import { FunctionL2Logs } from '@aztec/types'; +import { FunctionL2Logs, Note } from '@aztec/types'; import { ACVMField } from '../acvm/index.js'; /** * The contents of a new note. */ -export interface NewNoteData { - /** The preimage of the note. */ - preimage: Fr[]; +export interface NoteAndSlot { + /** The note. */ + note: Note; /** The storage slot of the note. */ storageSlot: Fr; } @@ -33,7 +33,7 @@ export interface ExecutionResult { readRequestPartialWitnesses: ReadRequestMembershipWitness[]; // Needed when we enable chained txs. The new notes can be cached and used in a later transaction. /** The notes created in the executed function. */ - newNotes: NewNoteData[]; + newNotes: NoteAndSlot[]; /** The decoded return values of the executed function. */ returnValues: DecodedReturn; /** The nested executions. */ diff --git a/yarn-project/acir-simulator/src/client/pick_notes.test.ts b/yarn-project/acir-simulator/src/client/pick_notes.test.ts index f95d4d628e9a..1d9a5ffeb22f 100644 --- a/yarn-project/acir-simulator/src/client/pick_notes.test.ts +++ b/yarn-project/acir-simulator/src/client/pick_notes.test.ts @@ -1,26 +1,27 @@ import { Fr } from '@aztec/foundation/fields'; +import { Note } from '@aztec/types'; import { SortOrder, pickNotes } from './pick_notes.js'; describe('getNotes', () => { - const expectNotesFields = (notes: { preimage: Fr[] }[], ...expected: [number, bigint[]][]) => { + const expectNotesFields = (notes: { note: Note }[], ...expected: [number, bigint[]][]) => { expect(notes.length).toBe(expected[0][1].length); expected.forEach(([fieldIndex, fields]) => { for (let i = 0; i < notes.length; ++i) { - expect(notes[i].preimage[fieldIndex].value).toBe(fields[i]); + expect(notes[i].note.items[fieldIndex].value).toBe(fields[i]); } }); }; - const expectNotes = (notes: { preimage: Fr[] }[], expected: bigint[][]) => { + const expectNotes = (notes: { note: Note }[], expected: bigint[][]) => { expect(notes.length).toBe(expected.length); notes.forEach((note, i) => { - expect(note.preimage.map(p => p.value)).toEqual(expected[i]); + expect(note.note.items.map(p => p.value)).toEqual(expected[i]); }); }; - const createNote = (preimage: bigint[]) => ({ - preimage: preimage.map(f => new Fr(f)), + const createNote = (items: bigint[]) => ({ + note: new Note(items.map(f => new Fr(f))), }); it('should get sorted notes', () => { diff --git a/yarn-project/acir-simulator/src/client/pick_notes.ts b/yarn-project/acir-simulator/src/client/pick_notes.ts index 8f9fbddbff5e..cd95fa93eaaf 100644 --- a/yarn-project/acir-simulator/src/client/pick_notes.ts +++ b/yarn-project/acir-simulator/src/client/pick_notes.ts @@ -1,4 +1,5 @@ import { Fr } from '@aztec/foundation/fields'; +import { Note } from '@aztec/types'; /** * Configuration for selecting values. @@ -70,11 +71,11 @@ interface BasicNoteData { /** * Preimage of a note. */ - preimage: Fr[]; + note: Note; } -const selectNotes = (notes: T[], selects: Select[]): T[] => - notes.filter(note => selects.every(({ index, value }) => note.preimage[index]?.equals(value))); +const selectNotes = (noteDatas: T[], selects: Select[]): T[] => + noteDatas.filter(noteData => selects.every(({ index, value }) => noteData.note.items[index]?.equals(value))); const sortNotes = (a: Fr[], b: Fr[], sorts: Sort[], level = 0): number => { if (sorts[level] === undefined) return 0; @@ -94,10 +95,10 @@ const sortNotes = (a: Fr[], b: Fr[], sorts: Sort[], level = 0): number => { * Pick from a note array a number of notes that meet the criteria. */ export function pickNotes( - notes: T[], + noteDatas: T[], { selects = [], sorts = [], limit = 0, offset = 0 }: GetOptions, ): T[] { - return selectNotes(notes, selects) - .sort((a, b) => sortNotes(a.preimage, b.preimage, sorts)) + return selectNotes(noteDatas, selects) + .sort((a, b) => sortNotes(a.note.items, b.note.items, sorts)) .slice(offset, limit ? offset + limit : undefined); } diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index df61888a4e60..47825b308917 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -27,7 +27,6 @@ import { makeContractDeploymentData } from '@aztec/circuits.js/factories'; import { FunctionArtifact, FunctionSelector, encodeArguments } from '@aztec/foundation/abi'; import { asyncMap } from '@aztec/foundation/async-map'; import { AztecAddress } from '@aztec/foundation/aztec-address'; -import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; @@ -41,7 +40,7 @@ import { TestContractArtifact, TokenContractArtifact, } from '@aztec/noir-contracts/artifacts'; -import { PackedArguments, TxExecutionRequest } from '@aztec/types'; +import { Note, PackedArguments, TxExecutionRequest } from '@aztec/types'; import { jest } from '@jest/globals'; import { MockProxy, mock } from 'jest-mock-extended'; @@ -145,7 +144,6 @@ describe('Private Execution test suite', () => { return trees[name]; }; - const hash = (data: Buffer[]) => pedersenHashInputs(circuitsWasm, data); const hashFields = (data: Fr[]) => Fr.fromBuffer( pedersenHashInputs( @@ -206,13 +204,13 @@ describe('Private Execution test suite', () => { // `hash(firstNullifier, noteHashIndex)` const noteHashIndex = Math.floor(Math.random()); // mock index in TX's final newNoteHashes array const nonce = computeCommitmentNonce(circuitsWasm, mockFirstNullifier, noteHashIndex); - const preimage = [new Fr(amount), owner.toField(), Fr.random()]; - const innerNoteHash = Fr.fromBuffer(hash(preimage.map(p => p.toBuffer()))); + const note = new Note([new Fr(amount), owner.toField(), Fr.random()]); + const innerNoteHash = hashFields(note.items); return { contractAddress, storageSlot, nonce, - preimage, + note, innerNoteHash, siloedNullifier: new Fr(0), index: currentNoteIndex++, @@ -233,20 +231,20 @@ describe('Private Execution test suite', () => { it('should have an artifact for computing note hash and nullifier', async () => { const storageSlot = Fr.random(); - const note = buildNote(60n, owner, storageSlot); + const noteWithContext = buildNote(60n, owner, storageSlot); // Should be the same as how we compute the values for the ValueNote in the Aztec.nr library. - const valueNoteHash = hashFields(note.preimage); + const valueNoteHash = hashFields(noteWithContext.note.items); const innerNoteHash = hashFields([storageSlot, valueNoteHash]); const siloedNoteHash = siloCommitment(circuitsWasm, contractAddress, innerNoteHash); - const uniqueSiloedNoteHash = computeUniqueCommitment(circuitsWasm, note.nonce, siloedNoteHash); + const uniqueSiloedNoteHash = computeUniqueCommitment(circuitsWasm, noteWithContext.nonce, siloedNoteHash); const innerNullifier = hashFields([uniqueSiloedNoteHash, ownerPk.low, ownerPk.high]); const result = await acirSimulator.computeNoteHashAndNullifier( contractAddress, - note.nonce, + noteWithContext.nonce, storageSlot, - note.preimage, + noteWithContext.note, ); expect(result).toEqual({ @@ -271,7 +269,7 @@ describe('Private Execution test suite', () => { const [commitment] = newCommitments; expect(commitment).toEqual( - await acirSimulator.computeInnerNoteHash(contractAddress, newNote.storageSlot, newNote.preimage), + await acirSimulator.computeInnerNoteHash(contractAddress, newNote.storageSlot, newNote.note), ); }); @@ -289,7 +287,7 @@ describe('Private Execution test suite', () => { const [commitment] = newCommitments; expect(commitment).toEqual( - await acirSimulator.computeInnerNoteHash(contractAddress, newNote.storageSlot, newNote.preimage), + await acirSimulator.computeInnerNoteHash(contractAddress, newNote.storageSlot, newNote.note), ); }); @@ -303,8 +301,8 @@ describe('Private Execution test suite', () => { const notes = [buildNote(60n, owner, storageSlot), buildNote(80n, owner, storageSlot)]; oracle.getNotes.mockResolvedValue(notes); - const consumedNotes = await asyncMap(notes, ({ nonce, preimage }) => - acirSimulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, preimage), + const consumedNotes = await asyncMap(notes, ({ nonce, note }) => + acirSimulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note), ); await insertLeaves(consumedNotes.map(n => n.siloedNoteHash)); @@ -325,14 +323,14 @@ describe('Private Execution test suite', () => { const [changeNoteCommitment, recipientNoteCommitment] = newCommitments; expect(recipientNoteCommitment).toEqual( - await acirSimulator.computeInnerNoteHash(contractAddress, recipientStorageSlot, recipientNote.preimage), + await acirSimulator.computeInnerNoteHash(contractAddress, recipientStorageSlot, recipientNote.note), ); expect(changeNoteCommitment).toEqual( - await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, changeNote.preimage), + await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, changeNote.note), ); - expect(recipientNote.preimage[0]).toEqual(new Fr(amountToTransfer)); - expect(changeNote.preimage[0]).toEqual(new Fr(40n)); + expect(recipientNote.note.items[0]).toEqual(new Fr(amountToTransfer)); + expect(changeNote.note.items[0]).toEqual(new Fr(40n)); const readRequests = result.callStackItem.publicInputs.readRequests.filter(field => !field.equals(Fr.ZERO)); expect(readRequests).toHaveLength(consumedNotes.length); @@ -349,8 +347,8 @@ describe('Private Execution test suite', () => { const notes = [buildNote(balance, owner, storageSlot)]; oracle.getNotes.mockResolvedValue(notes); - const consumedNotes = await asyncMap(notes, ({ nonce, preimage }) => - acirSimulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, preimage), + const consumedNotes = await asyncMap(notes, ({ nonce, note }) => + acirSimulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note), ); await insertLeaves(consumedNotes.map(n => n.siloedNoteHash)); @@ -362,8 +360,8 @@ describe('Private Execution test suite', () => { expect(result.newNotes).toHaveLength(2); const [changeNote, recipientNote] = result.newNotes; - expect(recipientNote.preimage[0]).toEqual(new Fr(amountToTransfer)); - expect(changeNote.preimage[0]).toEqual(new Fr(balance - amountToTransfer)); + expect(recipientNote.note.items[0]).toEqual(new Fr(amountToTransfer)); + expect(changeNote.note.items[0]).toEqual(new Fr(balance - amountToTransfer)); }); }); @@ -509,17 +507,17 @@ describe('Private Execution test suite', () => { const wasm = await CircuitsWasm.get(); const secret = new Fr(1n); const secretHash = computeSecretMessageHash(wasm, secret); - const preimage = [toBufferBE(amount, 32), secretHash.toBuffer()]; - const noteHash = Fr.fromBuffer(hash(preimage)); + const note = new Note([new Fr(amount), secretHash]); + const noteHash = hashFields(note.items); const storageSlot = new Fr(5); - const innerNoteHash = Fr.fromBuffer(hash([storageSlot.toBuffer(), noteHash.toBuffer()])); + const innerNoteHash = hashFields([storageSlot, noteHash]); const siloedNoteHash = siloCommitment(wasm, contractAddress, innerNoteHash); oracle.getNotes.mockResolvedValue([ { contractAddress, storageSlot, nonce: Fr.ZERO, - preimage: preimage.map(p => Fr.fromBuffer(p)), + note, innerNoteHash: new Fr(EMPTY_NULLIFIED_COMMITMENT), siloedNullifier: Fr.random(), index: 1n, @@ -629,17 +627,17 @@ describe('Private Execution test suite', () => { }); expect(result.newNotes).toHaveLength(1); - const note = result.newNotes[0]; - expect(note.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm)); + const noteAndSlot = result.newNotes[0]; + expect(noteAndSlot.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm)); - expect(note.preimage[0]).toEqual(new Fr(amountToTransfer)); + expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); const newCommitments = result.callStackItem.publicInputs.newCommitments.filter(field => !field.equals(Fr.ZERO)); expect(newCommitments).toHaveLength(1); const commitment = newCommitments[0]; const storageSlot = computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm); - const innerNoteHash = await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, note.preimage); + const innerNoteHash = await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, noteAndSlot.note); expect(commitment).toEqual(innerNoteHash); // read request should match innerNoteHash for pending notes (there is no nonce, so can't compute "unique" hash) @@ -700,10 +698,10 @@ describe('Private Execution test suite', () => { const getNotesAfterNullify = result.nestedExecutions[2]; expect(execInsert.newNotes).toHaveLength(1); - const note = execInsert.newNotes[0]; - expect(note.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm)); + const noteAndSlot = execInsert.newNotes[0]; + expect(noteAndSlot.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm)); - expect(note.preimage[0]).toEqual(new Fr(amountToTransfer)); + expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); const newCommitments = execInsert.callStackItem.publicInputs.newCommitments.filter( field => !field.equals(Fr.ZERO), @@ -712,7 +710,7 @@ describe('Private Execution test suite', () => { const commitment = newCommitments[0]; const storageSlot = computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm); - const innerNoteHash = await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, note.preimage); + const innerNoteHash = await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, noteAndSlot.note); expect(commitment).toEqual(innerNoteHash); // read request should match innerNoteHash for pending notes (there is no nonce, so can't compute "unique" hash) @@ -748,17 +746,19 @@ describe('Private Execution test suite', () => { }); expect(result.newNotes).toHaveLength(1); - const note = result.newNotes[0]; - expect(note.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm)); + const noteAndSlot = result.newNotes[0]; + expect(noteAndSlot.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm)); - expect(note.preimage[0]).toEqual(new Fr(amountToTransfer)); + expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); const newCommitments = result.callStackItem.publicInputs.newCommitments.filter(field => !field.equals(Fr.ZERO)); expect(newCommitments).toHaveLength(1); const commitment = newCommitments[0]; const storageSlot = computeSlotForMapping(new Fr(1n), owner.toField(), circuitsWasm); - expect(commitment).toEqual(await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, note.preimage)); + expect(commitment).toEqual( + await acirSimulator.computeInnerNoteHash(contractAddress, storageSlot, noteAndSlot.note), + ); // read requests should be empty const readRequest = result.callStackItem.publicInputs.readRequests[0].value; diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 91e8a2aad097..54463ddb5dde 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -5,7 +5,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; -import { AztecNode, FunctionCall, TxExecutionRequest } from '@aztec/types'; +import { AztecNode, FunctionCall, Note, TxExecutionRequest } from '@aztec/types'; import { WasmBlackBoxFunctionSolver, createBlackBoxSolver } from '@noir-lang/acvm_js'; @@ -155,7 +155,7 @@ export class AcirSimulator { * @param note - The note. * @returns The nullifier. */ - public async computeNoteHashAndNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { + public async computeNoteHashAndNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Note) { let artifact: FunctionArtifactWithDebugMetadata | undefined = undefined; // Brute force @@ -177,12 +177,12 @@ export class AcirSimulator { } const preimageLen = (artifact.parameters[3].type as ArrayType).length; - const extendedPreimage = note.concat(Array(preimageLen - note.length).fill(Fr.ZERO)); + const extendedNoteItems = note.items.concat(Array(preimageLen - note.length).fill(Fr.ZERO)); const execRequest: FunctionCall = { to: AztecAddress.ZERO, functionData: FunctionData.empty(), - args: encodeArguments(artifact, [contractAddress, nonce, storageSlot, extendedPreimage]), + args: encodeArguments(artifact, [contractAddress, nonce, storageSlot, extendedNoteItems]), }; const [innerNoteHash, siloedNoteHash, uniqueSiloedNoteHash, innerNullifier] = (await this.runUnconstrained( @@ -206,7 +206,7 @@ export class AcirSimulator { * @param note - The note. * @returns The note hash. */ - public async computeInnerNoteHash(contractAddress: AztecAddress, storageSlot: Fr, note: Fr[]) { + public async computeInnerNoteHash(contractAddress: AztecAddress, storageSlot: Fr, note: Note) { const { innerNoteHash } = await this.computeNoteHashAndNullifier(contractAddress, Fr.ZERO, storageSlot, note); return innerNoteHash; } @@ -219,7 +219,7 @@ export class AcirSimulator { * @param note - The note. * @returns The note hash. */ - public async computeUniqueSiloedNoteHash(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { + public async computeUniqueSiloedNoteHash(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Note) { const { uniqueSiloedNoteHash } = await this.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note); return uniqueSiloedNoteHash; } @@ -232,7 +232,7 @@ export class AcirSimulator { * @param note - The note. * @returns The note hash. */ - public async computeSiloedNoteHash(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { + public async computeSiloedNoteHash(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Note) { const { siloedNoteHash } = await this.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note); return siloedNoteHash; } @@ -245,7 +245,7 @@ export class AcirSimulator { * @param note - The note. * @returns The note hash. */ - public async computeInnerNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Fr[]) { + public async computeInnerNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Note) { const { innerNullifier } = await this.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note); return innerNullifier; } diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts index 34a4a9ced6e8..8cfdf278a2b2 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts @@ -3,7 +3,7 @@ import { FunctionSelector, encodeArguments } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { StatefulTestContractArtifact } from '@aztec/noir-contracts/artifacts'; -import { FunctionCall } from '@aztec/types'; +import { FunctionCall, Note } from '@aztec/types'; import { mock } from 'jest-mock-extended'; @@ -25,7 +25,7 @@ describe('Unconstrained Execution test suite', () => { let owner: AztecAddress; const buildNote = (amount: bigint, owner: AztecAddress) => { - return [new Fr(amount), owner, Fr.random()]; + return new Note([new Fr(amount), owner.toField(), Fr.random()]); }; beforeEach(async () => { @@ -42,16 +42,16 @@ describe('Unconstrained Execution test suite', () => { const contractAddress = AztecAddress.random(); const artifact = StatefulTestContractArtifact.functions.find(f => f.name === 'summed_values')!; - const preimages = [...Array(5).fill(buildNote(1n, owner)), ...Array(2).fill(buildNote(2n, owner))]; + const notes: Note[] = [...Array(5).fill(buildNote(1n, owner)), ...Array(2).fill(buildNote(2n, owner))]; oracle.getHistoricBlockData.mockResolvedValue(HistoricBlockData.empty()); oracle.getNotes.mockResolvedValue( - preimages.map((preimage, index) => ({ + notes.map((note, index) => ({ contractAddress, storageSlot: Fr.random(), nonce: Fr.random(), isSome: new Fr(1), - preimage, + note, innerNoteHash: Fr.random(), siloedNullifier: Fr.random(), index: BigInt(index), 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 e44ea01cc785..7f1497b09f75 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 { ExecutionResult, NewNoteData } from '@aztec/acir-simulator'; +import { ExecutionResult, NoteAndSlot } from '@aztec/acir-simulator'; import { KernelCircuitPublicInputs, MAX_NEW_COMMITMENTS_PER_CALL, @@ -19,7 +19,7 @@ import { makeTxRequest } from '@aztec/circuits.js/factories'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { Tuple } from '@aztec/foundation/serialize'; -import { FunctionL2Logs } from '@aztec/types'; +import { FunctionL2Logs, Note } from '@aztec/types'; import { mock } from 'jest-mock-extended'; @@ -34,23 +34,23 @@ describe('Kernel Prover', () => { let prover: KernelProver; let dependencies: { [name: string]: string[] } = {}; - const notes: NewNoteData[] = Array(10) + const notesAndSlots: NoteAndSlot[] = Array(10) .fill(null) .map(() => ({ - preimage: [Fr.random(), Fr.random(), Fr.random()], + note: new Note([Fr.random(), Fr.random(), Fr.random()]), storageSlot: Fr.random(), owner: { x: Fr.random(), y: Fr.random() }, })); const createFakeSiloedCommitment = (commitment: Fr) => new Fr(commitment.value + 1n); - const generateFakeCommitment = (note: NewNoteData) => note.preimage[0]; - const generateFakeSiloedCommitment = (note: NewNoteData) => createFakeSiloedCommitment(generateFakeCommitment(note)); + const generateFakeCommitment = (noteAndSlot: NoteAndSlot) => noteAndSlot.note.items[0]; + const generateFakeSiloedCommitment = (note: NoteAndSlot) => createFakeSiloedCommitment(generateFakeCommitment(note)); const createExecutionResult = (fnName: string, newNoteIndices: number[] = []): ExecutionResult => { const publicInputs = PrivateCircuitPublicInputs.empty(); publicInputs.newCommitments = makeTuple( MAX_NEW_COMMITMENTS_PER_CALL, - i => (i < newNoteIndices.length ? generateFakeCommitment(notes[newNoteIndices[i]]) : Fr.ZERO), + i => (i < newNoteIndices.length ? generateFakeCommitment(notesAndSlots[newNoteIndices[i]]) : Fr.ZERO), 0, ); return { @@ -58,7 +58,7 @@ describe('Kernel Prover', () => { callStackItem: new PrivateCallStackItem(AztecAddress.ZERO, fnName as any, publicInputs, false), nestedExecutions: (dependencies[fnName] || []).map(name => createExecutionResult(name)), vk: VerificationKey.makeFake().toBuffer(), - newNotes: newNoteIndices.map(idx => notes[idx]), + newNotes: newNoteIndices.map(idx => notesAndSlots[idx]), // TODO(dbanks12): should test kernel prover with non-transient reads. // This will be necessary once kernel actually checks (attempts to match) transient reads. readRequestPartialWitnesses: Array.from({ length: MAX_READ_REQUESTS_PER_CALL }, () => @@ -76,7 +76,7 @@ describe('Kernel Prover', () => { const createProofOutput = (newNoteIndices: number[]) => { const publicInputs = KernelCircuitPublicInputs.empty(); - const commitments = newNoteIndices.map(idx => generateFakeSiloedCommitment(notes[idx])); + const commitments = newNoteIndices.map(idx => generateFakeSiloedCommitment(notesAndSlots[idx])); // TODO(AD) FIXME(AD) This cast is bad. Why is this not the correct length when this is called? publicInputs.end.newCommitments = commitments as Tuple; return { @@ -103,7 +103,7 @@ describe('Kernel Prover', () => { const expectOutputNotes = (outputNotes: OutputNoteData[], expectedNoteIndices: number[]) => { expect(outputNotes.length).toBe(expectedNoteIndices.length); outputNotes.forEach((n, i) => { - expect(n.data).toEqual(notes[expectedNoteIndices[i]]); + expect(n.data).toEqual(notesAndSlots[expectedNoteIndices[i]]); }); }; diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 2cb54b410718..a5b7b36fb0c3 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -1,4 +1,4 @@ -import { ExecutionResult, NewNoteData } from '@aztec/acir-simulator'; +import { ExecutionResult, NoteAndSlot } from '@aztec/acir-simulator'; import { AztecAddress, CONTRACT_TREE_HEIGHT, @@ -42,7 +42,7 @@ export interface OutputNoteData { /** * The encrypted note data for an output note. */ - data: NewNoteData; + data: NoteAndSlot; /** * The unique value representing the note. */ 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 55a4cf937f0b..f40468a05dae 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -14,6 +14,7 @@ import { L2Block, L2BlockContext, L2BlockL2Logs, + Note, TxL2Logs, } from '@aztec/types'; @@ -39,11 +40,11 @@ describe('Note Processor', () => { const numCommitmentsPerBlock = TXS_PER_BLOCK * MAX_NEW_COMMITMENTS_PER_TX; const firstBlockDataStartIndex = (firstBlockNum - 1) * numCommitmentsPerBlock; - const computeMockNoteHash = (preimage: Fr[]) => + const computeMockNoteHash = (note: Note) => Fr.fromBuffer( pedersenHashInputs( wasm, - preimage.map(p => p.toBuffer()), + note.items.map(i => i.toBuffer()), ), ); @@ -106,7 +107,7 @@ describe('Note Processor', () => { } = createEncryptedLogsAndOwnedL1NotePayloads(isTargetBlock ? ownedData : [], isTargetBlock ? ownedNotes : []); encryptedLogsArr.push(encryptedLogs); ownedL1NotePayloads.push(...payloads); - block.newCommitments = newNotes.map(n => computeMockNoteHash(n.note.items)); + block.newCommitments = newNotes.map(n => computeMockNoteHash(n.note)); const randomBlockContext = new L2BlockContext(block); blockContexts.push(randomBlockContext); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index f43545126ae8..40b2220641c7 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -218,7 +218,7 @@ export class NoteProcessor { const expectedNonce = computeCommitmentNonce(wasm, firstNullifier, commitmentIndex); ({ innerNoteHash, siloedNoteHash, uniqueSiloedNoteHash, innerNullifier } = - await this.simulator.computeNoteHashAndNullifier(contractAddress, expectedNonce, storageSlot, note.items)); + await this.simulator.computeNoteHashAndNullifier(contractAddress, expectedNonce, storageSlot, note)); if (commitment.equals(uniqueSiloedNoteHash)) { nonce = expectedNonce; break; diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index d18ff7c00115..0adffa13d185 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -202,7 +202,7 @@ export class PXEService implements PXE { account: AztecAddress, contractAddress: AztecAddress, storageSlot: Fr, - preimage: Note, + note: Note, txHash: TxHash, nonce?: Fr, ) { @@ -212,14 +212,14 @@ export class PXEService implements PXE { } if (!nonce) { - [nonce] = await this.getNoteNonces(contractAddress, storageSlot, preimage, txHash); + [nonce] = await this.getNoteNonces(contractAddress, storageSlot, note, txHash); } if (!nonce) { throw new Error(`Cannot find the note in tx: ${txHash}.`); } const { innerNoteHash, siloedNoteHash, uniqueSiloedNoteHash, innerNullifier } = - await this.simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, preimage.items); + await this.simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) // This can always be `uniqueSiloedNoteHash` once notes added from public also include nonces. @@ -238,7 +238,7 @@ export class PXEService implements PXE { await this.db.addExtendedNote( new ExtendedNote( - preimage, + note, contractAddress, txHash, nonce, @@ -276,7 +276,7 @@ export class PXEService implements PXE { contractAddress, nonce, storageSlot, - note.items, + note, ); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) // Remove this once notes added from public also include nonces. diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 8efe31577c4c..a2ee24f8fb51 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -50,7 +50,7 @@ export class SimulatorOracle implements DBOracle { contractAddress, storageSlot, nonce, - preimage: note.items, + note, innerNoteHash, siloedNullifier, // PXE can use this index to get full MembershipWitness diff --git a/yarn-project/types/src/logs/l1_note_payload/note.ts b/yarn-project/types/src/logs/l1_note_payload/note.ts index 9bc9e066efd1..6fdda129ec8d 100644 --- a/yarn-project/types/src/logs/l1_note_payload/note.ts +++ b/yarn-project/types/src/logs/l1_note_payload/note.ts @@ -51,4 +51,8 @@ export class Note extends Vector { const hex = str.replace(/^0x/, ''); return Note.fromBuffer(Buffer.from(hex, 'hex')); } + + get length() { + return this.items.length; + } } From 445309f38c682ae72aaa87859d1967d7fdae8be2 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 08:06:51 +0000 Subject: [PATCH 20/41] fixes --- yarn-project/end-to-end/src/guides/up_quick_start.sh | 2 +- yarn-project/end-to-end/src/shared/cli.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/end-to-end/src/guides/up_quick_start.sh b/yarn-project/end-to-end/src/guides/up_quick_start.sh index 4f4d1926bc57..61d119616840 100755 --- a/yarn-project/end-to-end/src/guides/up_quick_start.sh +++ b/yarn-project/end-to-end/src/guides/up_quick_start.sh @@ -34,7 +34,7 @@ MINT_PRIVATE_TX_HASH=$(echo "$MINT_PRIVATE_OUTPUT" | grep "Transaction hash:" | aztec-cli add-note \ $ALICE $CONTRACT 5 $MINT_PRIVATE_TX_HASH \ - --preimage 1000 $SECRET_HASH + --note 1000 $SECRET_HASH aztec-cli send redeem_shield \ --args $ALICE 1000 $SECRET \ diff --git a/yarn-project/end-to-end/src/shared/cli.ts b/yarn-project/end-to-end/src/shared/cli.ts index 529cb8130b2b..bcc500edc9ff 100644 --- a/yarn-project/end-to-end/src/shared/cli.ts +++ b/yarn-project/end-to-end/src/shared/cli.ts @@ -142,7 +142,7 @@ export const cliTestSuite = ( const txHashes = findMultipleInLogs(/Transaction Hash: ([0-9a-f]{64})/i); const mintPrivateTxHash = txHashes[txHashes.length - 1][1]; await run( - `add-note ${ownerAddress} ${contractAddress} 5 ${mintPrivateTxHash} --preimage ${INITIAL_BALANCE} ${secretHash}`, + `add-note ${ownerAddress} ${contractAddress} 5 ${mintPrivateTxHash} --note ${INITIAL_BALANCE} ${secretHash}`, ); debug('Redeem tokens.'); From 7424dcdc28e9963cee2ebca96a32a6293a8825da Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 08:41:40 +0000 Subject: [PATCH 21/41] naming fixes --- .../acir-simulator/src/acvm/oracle/oracle.ts | 4 ++-- .../src/acvm/oracle/typed_oracle.ts | 8 ++++---- .../src/client/client_execution_context.ts | 20 ++++++------------- .../acir-simulator/src/client/db_oracle.ts | 2 +- .../acir-simulator/src/client/pick_notes.ts | 10 +++++----- .../acir-simulator/src/client/simulator.ts | 4 ++-- .../src/client/view_data_oracle.ts | 13 +++--------- .../pxe/src/kernel_prover/kernel_prover.ts | 4 ++-- .../src/note_processor/note_processor.test.ts | 4 ++-- .../pxe/src/note_processor/note_processor.ts | 2 +- yarn-project/types/src/interfaces/pxe.ts | 2 +- 11 files changed, 29 insertions(+), 44 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts index 2720c1b027b0..08944796c0cc 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts @@ -148,14 +148,14 @@ export class Oracle { [storageSlot]: ACVMField[], [publicKeyX]: ACVMField[], [publicKeyY]: ACVMField[], - preimage: ACVMField[], + log: ACVMField[], ): ACVMField { const publicKey = new Point(fromACVMField(publicKeyX), fromACVMField(publicKeyY)); this.typedOracle.emitEncryptedLog( AztecAddress.fromString(contractAddress), Fr.fromString(storageSlot), publicKey, - preimage.map(fromACVMField), + log.map(fromACVMField), ); return toACVMField(0); } diff --git a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts index b3e22d8161d6..a864471a722f 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts @@ -9,14 +9,14 @@ import { CompleteAddress, Note, PublicKey, UnencryptedL2Log } from '@aztec/types * Information about a note needed during execution. */ export interface NoteData { + /** The note. */ + note: Note; /** The contract address of the note. */ contractAddress: AztecAddress; /** The storage slot of the note. */ storageSlot: Fr; /** The nonce of the note. */ nonce: Fr; - /** The preimage of the note */ - note: Note; /** The inner note hash of the note. */ innerNoteHash: Fr; /** The corresponding nullifier of the note. Undefined for pending notes. */ @@ -93,7 +93,7 @@ export abstract class TypedOracle { throw new Error('Not available.'); } - notifyCreatedNote(_storageSlot: Fr, _preimage: Fr[], _innerNoteHash: Fr): void { + notifyCreatedNote(_storageSlot: Fr, _note: Fr[], _innerNoteHash: Fr): void { throw new Error('Not available.'); } @@ -121,7 +121,7 @@ export abstract class TypedOracle { throw new Error('Not available.'); } - emitEncryptedLog(_contractAddress: AztecAddress, _storageSlot: Fr, _publicKey: PublicKey, _preimage: Fr[]): void { + emitEncryptedLog(_contractAddress: AztecAddress, _storageSlot: Fr, _publicKey: PublicKey, _log: Fr[]): void { throw new Error('Not available.'); } diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 1f1d6775d14f..5236304a716c 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -176,16 +176,13 @@ export class ClientExecutionContext extends ViewDataOracle { } /** - * Gets some notes for a contract address and storage slot. - * Returns a flattened array containing real-note-count and note preimages. + * Gets some notes for a storage slot. * * @remarks - * - * Check for pending notes with matching address/slot. + * Check for pending notes with matching slot. * Real notes coming from DB will have a leafIndex which * represents their index in the note hash tree. * - * @param contractAddress - The contract address. * @param storageSlot - The storage slot. * @param numSelects - The number of valid selects in selectBy and selectValues. * @param selectBy - An array of indices of the fields to selects. @@ -194,12 +191,7 @@ export class ClientExecutionContext extends ViewDataOracle { * @param sortOrder - The order of the corresponding index in sortBy. (1: DESC, 2: ASC, 0: Do nothing) * @param limit - The number of notes to retrieve per query. * @param offset - The starting index for pagination. - * @param returnSize - The return size. - * @returns Flattened array of ACVMFields (format expected by Noir/ACVM) containing: - * count - number of real (non-padding) notes retrieved, - * contractAddress - the contract address, - * preimages - the real note preimages retrieved, and - * paddedZeros - zeros to ensure an array with length returnSize expected by Noir circuit + * @returns Array of note data. */ public async getNotes( storageSlot: Fr, @@ -286,10 +278,10 @@ export class ClientExecutionContext extends ViewDataOracle { * @param contractAddress - The contract address of the note. * @param storageSlot - The storage slot the note is at. * @param publicKey - The public key of the account that can decrypt the log. - * @param preimage - The preimage of the note. + * @param log - The log contents. */ - public emitEncryptedLog(contractAddress: AztecAddress, storageSlot: Fr, publicKey: Point, preimage: Fr[]) { - const note = new Note(preimage); + public emitEncryptedLog(contractAddress: AztecAddress, storageSlot: Fr, publicKey: Point, log: Fr[]) { + const note = new Note(log); const l1NotePayload = new L1NotePayload(note, contractAddress, storageSlot); const encryptedNote = l1NotePayload.toEncryptedBuffer(publicKey, this.curve); this.encryptedLogs.push(encryptedNote); diff --git a/yarn-project/acir-simulator/src/client/db_oracle.ts b/yarn-project/acir-simulator/src/client/db_oracle.ts index da9233c5453a..729c181385d0 100644 --- a/yarn-project/acir-simulator/src/client/db_oracle.ts +++ b/yarn-project/acir-simulator/src/client/db_oracle.ts @@ -50,7 +50,7 @@ export interface DBOracle extends CommitmentsDB { /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. * The query result is paginated using 'limit' and 'offset' values. - * Returns an object containing an array of note data, including preimage, nonce, and index for each note. + * Returns an object containing an array of note data. * * @param contractAddress - The AztecAddress instance representing the contract address. * @param storageSlot - The Fr instance representing the storage slot of the notes. diff --git a/yarn-project/acir-simulator/src/client/pick_notes.ts b/yarn-project/acir-simulator/src/client/pick_notes.ts index cd95fa93eaaf..ca4bbaf1576b 100644 --- a/yarn-project/acir-simulator/src/client/pick_notes.ts +++ b/yarn-project/acir-simulator/src/client/pick_notes.ts @@ -65,16 +65,16 @@ interface GetOptions { } /** - * Basic data needed from a note to perform sort. + * Data needed from to perform sort. */ -interface BasicNoteData { +interface ContainsNote { /** - * Preimage of a note. + * The note. */ note: Note; } -const selectNotes = (noteDatas: T[], selects: Select[]): T[] => +const selectNotes = (noteDatas: T[], selects: Select[]): T[] => noteDatas.filter(noteData => selects.every(({ index, value }) => noteData.note.items[index]?.equals(value))); const sortNotes = (a: Fr[], b: Fr[], sorts: Sort[], level = 0): number => { @@ -94,7 +94,7 @@ const sortNotes = (a: Fr[], b: Fr[], sorts: Sort[], level = 0): number => { /** * Pick from a note array a number of notes that meet the criteria. */ -export function pickNotes( +export function pickNotes( noteDatas: T[], { selects = [], sorts = [], limit = 0, offset = 0 }: GetOptions, ): T[] { diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 54463ddb5dde..a412e7b3e1d2 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -176,8 +176,8 @@ export class AcirSimulator { ); } - const preimageLen = (artifact.parameters[3].type as ArrayType).length; - const extendedNoteItems = note.items.concat(Array(preimageLen - note.length).fill(Fr.ZERO)); + const noteItemsLength = (artifact.parameters[3].type as ArrayType).length; + const extendedNoteItems = note.items.concat(Array(noteItemsLength - note.length).fill(Fr.ZERO)); const execRequest: FunctionCall = { to: AztecAddress.ZERO, diff --git a/yarn-project/acir-simulator/src/client/view_data_oracle.ts b/yarn-project/acir-simulator/src/client/view_data_oracle.ts index 55e1aff0206c..53a47c04ff0a 100644 --- a/yarn-project/acir-simulator/src/client/view_data_oracle.ts +++ b/yarn-project/acir-simulator/src/client/view_data_oracle.ts @@ -57,16 +57,13 @@ export class ViewDataOracle extends TypedOracle { } /** - * Gets some notes for a contract address and storage slot. - * Returns a flattened array containing real-note-count and note preimages. + * Gets some notes for a storage slot. * * @remarks - * - * Check for pending notes with matching address/slot. + * Check for pending notes with matching slot. * Real notes coming from DB will have a leafIndex which * represents their index in the note hash tree. * - * @param contractAddress - The contract address. * @param storageSlot - The storage slot. * @param numSelects - The number of valid selects in selectBy and selectValues. * @param selectBy - An array of indices of the fields to selects. @@ -75,11 +72,7 @@ export class ViewDataOracle extends TypedOracle { * @param sortOrder - The order of the corresponding index in sortBy. (1: DESC, 2: ASC, 0: Do nothing) * @param limit - The number of notes to retrieve per query. * @param offset - The starting index for pagination. - * @returns Flattened array of ACVMFields (format expected by Noir/ACVM) containing: - * count - number of real (non-padding) notes retrieved, - * contractAddress - the contract address, - * preimages - the real note preimages retrieved, and - * paddedZeros - zeros to ensure an array with length returnSize expected by Noir circuit + * @returns Array of note data. */ public async getNotes( storageSlot: Fr, diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index a5b7b36fb0c3..96e2d49e47c7 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -231,11 +231,11 @@ export class KernelProver { /** * Retrieves the new output notes for a given execution result. - * The function maps over the new note preimages and associates them with their corresponding + * The function maps over the new notes and associates them with their corresponding * commitments in the public inputs of the execution result. It also includes the contract address * from the call context of the public inputs. * - * @param executionResult - The execution result object containing note preimages and public inputs. + * @param executionResult - The execution result object containing notes and public inputs. * @returns An array of OutputNoteData objects, each representing an output note with its associated data. */ private async getNewNotes(executionResult: ExecutionResult): Promise { 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 f40468a05dae..d9582d82cd62 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -202,10 +202,10 @@ describe('Note Processor', () => { await noteProcessor.process(blockContexts, encryptedLogsArr); }); - it('should be able to recover two notes with the same preimage', async () => { + it('should be able to recover two note payloads with containing the same note', async () => { const note = L1NotePayload.random(); const note2 = L1NotePayload.random(); - // All notes expect one have the same contract address, storage slot, and preimage. + // All note payloads except one have the same contract address, storage slot, and the actual note. const notes = [note, note, note, note2, note]; const { blockContexts, encryptedLogsArr, ownedL1NotePayloads } = mockData([[0, 2], [], [0, 1, 3]], 0, 0, notes); await noteProcessor.process(blockContexts, encryptedLogsArr); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 40b2220641c7..1cea76bc7a3f 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -187,7 +187,7 @@ export class NoteProcessor { * commitment for the current tx matches this value. * Compute the nullifier for a given transaction auxiliary data. * The nullifier is calculated using the private key of the account, - * contract address, and note preimage associated with the l1NotePayload. + * contract address, and the note associated with the l1NotePayload. * This method assists in identifying spent commitments in the private state. * @param commitments - Commitments in the tx. One of them should be the note's commitment. * @param firstNullifier - First nullifier in the tx. diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index 4489811e88c5..d0c698bf1a14 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -174,7 +174,7 @@ export interface PXE { * @param storageSlot - The storage slot of the note. * @param note - The note to add. * @param txHash - The tx hash of the tx containing the note. - * @param nonce - The nonce of the note. If undefined, will look for the first index that matches the preimage. + * @param nonce - The nonce of the note. If undefined, will look for the first index that matches the note. */ addNote( account: AztecAddress, From 1f0d5f467d68b0c91b2124bac72f50f4065a1381 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 10:24:13 +0000 Subject: [PATCH 22/41] WIP --- yarn-project/pxe/src/database/database.ts | 22 +++--- .../pxe/src/database/memory_db.test.ts | 14 ++-- yarn-project/pxe/src/database/memory_db.ts | 25 +++--- .../pxe/src/database/note_dao.test.ts | 23 ++++++ yarn-project/pxe/src/database/note_dao.ts | 77 +++++++++++++++++++ .../pxe/src/pxe_service/pxe_service.ts | 4 +- .../pxe/src/simulator_oracle/index.ts | 2 +- yarn-project/types/src/mocks.ts | 17 +--- yarn-project/types/src/notes/extended_note.ts | 63 +++------------ 9 files changed, 149 insertions(+), 98 deletions(-) create mode 100644 yarn-project/pxe/src/database/note_dao.test.ts create mode 100644 yarn-project/pxe/src/database/note_dao.ts diff --git a/yarn-project/pxe/src/database/database.ts b/yarn-project/pxe/src/database/database.ts index b94d1c7016f6..3280c1748e47 100644 --- a/yarn-project/pxe/src/database/database.ts +++ b/yarn-project/pxe/src/database/database.ts @@ -1,7 +1,9 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { ContractDatabase, ExtendedNote, MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; +import { ContractDatabase, MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; + +import { NoteDao } from './note_dao.js'; /** * A database interface that provides methods for retrieving, adding, and removing transactional data related to Aztec @@ -27,22 +29,22 @@ export interface Database extends ContractDatabase { * @param filter - The filter to apply to the notes. * @returns The requested notes. */ - getExtendedNotes(filter: NoteFilter): Promise; + getNotes(filter: NoteFilter): Promise; /** - * Adds ExtendedNote to DB. - * @param extendedNote - The note to add. + * Adds a note to DB. + * @param note - The note to add. */ - addExtendedNote(extendedNote: ExtendedNote): Promise; + addNote(note: NoteDao): Promise; /** - * Adds an array of ExtendedNotes. - * This function is used to insert multiple extended notes to the database at once, + * Adds an array of notes to DB. + * This function is used to insert multiple notes to the database at once, * which can improve performance when dealing with large numbers of transactions. * - * @param extendedNotes - An array of ExtendedNote instances. + * @param notes - An array of notes. */ - addExtendedNotes(extendedNotes: ExtendedNote[]): Promise; + addNotes(notes: NoteDao[]): Promise; /** * Remove nullified notes associated with the given account and nullifiers. @@ -51,7 +53,7 @@ export interface Database extends ContractDatabase { * @param account - A PublicKey instance representing the account for which the records are being removed. * @returns Removed notes. */ - removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise; + removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise; /** * Retrieve the stored Merkle tree roots from the database. diff --git a/yarn-project/pxe/src/database/memory_db.test.ts b/yarn-project/pxe/src/database/memory_db.test.ts index a368b7dd4d64..a8cb6cc4c202 100644 --- a/yarn-project/pxe/src/database/memory_db.test.ts +++ b/yarn-project/pxe/src/database/memory_db.test.ts @@ -10,7 +10,7 @@ describe('Memory DB', () => { db = new MemoryDB(); }); - describe('ExtendedNote', () => { + describe('NoteDao', () => { const contractAddress = AztecAddress.random(); const storageSlot = Fr.random(); @@ -29,11 +29,11 @@ describe('Memory DB', () => { it('should add and get notes', async () => { const notes = createNotes(3, false); for (let i = 0; i < notes.length; ++i) { - await db.addExtendedNote(notes[i]); + await db.addNote(notes[i]); } for (let i = 0; i < notes.length; ++i) { - const result = await db.getExtendedNotes({ + const result = await db.getNotes({ contractAddress: notes[i].contractAddress, storageSlot: notes[i].storageSlot, }); @@ -43,10 +43,10 @@ describe('Memory DB', () => { it('should batch add notes', async () => { const notes = createNotes(3, false); - await db.addExtendedNotes(notes); + await db.addNote(notes); for (let i = 0; i < notes.length; ++i) { - const result = await db.getExtendedNotes({ + const result = await db.getNotes({ contractAddress: notes[i].contractAddress, storageSlot: notes[i].storageSlot, }); @@ -56,9 +56,9 @@ describe('Memory DB', () => { it('should get all notes with the same contract storage slot', async () => { const notes = createNotes(3); - await db.addExtendedNotes(notes); + await db.addNote(notes); - const result = await db.getExtendedNotes({ contractAddress, storageSlot }); + const result = await db.getNotes({ contractAddress, storageSlot }); expect(result.length).toBe(notes.length); expect(result).toEqual(expect.objectContaining(notes)); }); diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 20bcd22621af..86b5076dbdbe 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -2,10 +2,11 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { ExtendedNote, MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; +import { MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; import { MemoryContractDatabase } from '../contract_database/index.js'; import { Database } from './database.js'; +import { NoteDao } from './note_dao.js'; /** * The MemoryDB class provides an in-memory implementation of a database to manage transactions and auxiliary data. @@ -14,7 +15,7 @@ import { Database } from './database.js'; * As an in-memory database, the stored data will not persist beyond the life of the application instance. */ export class MemoryDB extends MemoryContractDatabase implements Database { - private extendedNotesTable: ExtendedNote[] = []; + private notesTable: NoteDao[] = []; private treeRoots: Record | undefined; private globalVariablesHash: Fr | undefined; private addresses: CompleteAddress[] = []; @@ -43,17 +44,17 @@ export class MemoryDB extends MemoryContractDatabase implements Database { return Promise.resolve(this.authWitnesses[messageHash.toString()]); } - public addExtendedNote(extendedNote: ExtendedNote) { - this.extendedNotesTable.push(extendedNote); + public addNote(note: NoteDao) { + this.notesTable.push(note); return Promise.resolve(); } - public addExtendedNotes(extendedNotes: ExtendedNote[]) { - this.extendedNotesTable.push(...extendedNotes); + public addNotes(notes: NoteDao[]) { + this.notesTable.push(...notes); return Promise.resolve(); } - public async getExtendedNotes(filter: NoteFilter): Promise { + public async getNotes(filter: NoteFilter): Promise { let ownerPublicKey: PublicKey | undefined; if (filter.owner !== undefined) { const ownerCompleteAddress = await this.getCompleteAddress(filter.owner); @@ -63,7 +64,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { ownerPublicKey = ownerCompleteAddress.publicKey; } - return this.extendedNotesTable.filter( + return this.notesTable.filter( note => (filter.contractAddress == undefined || note.contractAddress.equals(filter.contractAddress)) && (filter.txHash == undefined || note.txHash.equals(filter.txHash)) && @@ -74,8 +75,8 @@ export class MemoryDB extends MemoryContractDatabase implements Database { public removeNullifiedNotes(nullifiers: Fr[], account: PublicKey) { const nullifierSet = new Set(nullifiers.map(nullifier => nullifier.toString())); - const [remaining, removed] = this.extendedNotesTable.reduce( - (acc: [ExtendedNote[], ExtendedNote[]], note) => { + const [remaining, removed] = this.notesTable.reduce( + (acc: [NoteDao[], NoteDao[]], note) => { const nullifier = note.siloedNullifier.toString(); if (note.publicKey.equals(account) && nullifierSet.has(nullifier)) { acc[1].push(note); @@ -87,7 +88,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { [[], []], ); - this.extendedNotesTable = remaining; + this.notesTable = remaining; return Promise.resolve(removed); } @@ -155,7 +156,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { } public estimateSize() { - const notesSize = this.extendedNotesTable.reduce((sum, note) => sum + note.getSize(note), 0); + const notesSize = this.notesTable.reduce((sum, note) => sum + note.getSize(note), 0); const treeRootsSize = this.treeRoots ? Object.entries(this.treeRoots).length * Fr.SIZE_IN_BYTES : 0; const authWits = Object.entries(this.authWitnesses); const authWitsSize = authWits.reduce((sum, [key, value]) => sum + key.length + value.length * Fr.SIZE_IN_BYTES, 0); diff --git a/yarn-project/pxe/src/database/note_dao.test.ts b/yarn-project/pxe/src/database/note_dao.test.ts new file mode 100644 index 000000000000..7550abe5486e --- /dev/null +++ b/yarn-project/pxe/src/database/note_dao.test.ts @@ -0,0 +1,23 @@ +import { Fr, Point } from '@aztec/circuits.js'; +import { randomExtendedNote } from '@aztec/types'; + +import { NoteDao } from './note_dao.js'; + +const randomNoteDao = () => { + const extendedNote = randomExtendedNote(); + const nonce = Fr.random(); + const innerNoteHash = Fr.random(); + const siloedNullifier = Fr.random(); + const index = BigInt(0); + const publicKey = Point.random(); + + return new NoteDao(extendedNote, nonce, innerNoteHash, siloedNullifier, index, publicKey); +}; + +describe('Note DAO', () => { + it('convert to and from buffer', () => { + const note = randomNoteDao(); + const buf = note.toBuffer(); + expect(NoteDao.fromBuffer(buf)).toEqual(note); + }); +}); diff --git a/yarn-project/pxe/src/database/note_dao.ts b/yarn-project/pxe/src/database/note_dao.ts new file mode 100644 index 000000000000..8f8d9204cf4c --- /dev/null +++ b/yarn-project/pxe/src/database/note_dao.ts @@ -0,0 +1,77 @@ +import { Fr, Point, PublicKey } from '@aztec/circuits.js'; +import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; +import { BufferReader, ExtendedNote } from '@aztec/types'; + +/** + * A note with contextual data. + */ +export class NoteDao { + constructor( + /** The extended note. */ + public extendedNote: ExtendedNote, + /** The nonce of the note. */ + public nonce: Fr, + /** + * Inner note hash of the note. This is customizable by the app circuit. + * We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash. + */ + public innerNoteHash: Fr, + /** The nullifier of the note (siloed by contract address). */ + public siloedNullifier: Fr, + /** The location of the relevant note in the note hash tree. */ + public index: bigint, + /** The public key that was used to encrypt the data. */ + public publicKey: PublicKey, + ) {} + + toBuffer(): Buffer { + return Buffer.concat([ + this.extendedNote.toBuffer(), + this.nonce.toBuffer(), + this.innerNoteHash.toBuffer(), + this.siloedNullifier.toBuffer(), + toBufferBE(this.index, 32), + this.publicKey.toBuffer(), + ]); + } + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + + const extendedNote = ExtendedNote.fromBuffer(reader); + const nonce = Fr.fromBuffer(reader); + const innerNoteHash = Fr.fromBuffer(reader); + const siloedNullifier = Fr.fromBuffer(reader); + const index = toBigIntBE(reader.readBytes(32)); + const publicKey = Point.fromBuffer(reader); + + return new this( + extendedNote, + nonce, + innerNoteHash, + siloedNullifier, + index, + publicKey, + ); + } + + toString() { + return '0x' + this.toBuffer().toString('hex'); + } + + static fromString(str: string) { + const hex = str.replace(/^0x/, ''); + return NoteDao.fromBuffer(Buffer.from(hex, 'hex')); + } + + /** + * Returns the size in bytes of the extended note. + * @returns - Its size in bytes. + */ + public getSize() { + // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer + const indexSize = Math.ceil(Math.log2(Number(this.index))); + return ( + this.extendedNote.note.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize + Point.SIZE_IN_BYTES + ); + } +} diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 0adffa13d185..a2f24d82d94f 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -195,7 +195,7 @@ export class PXEService implements PXE { } public async getNotes(filter: NoteFilter): Promise { - return await this.db.getExtendedNotes(filter); + return await this.db.getNotes(filter); } public async addNote( @@ -236,7 +236,7 @@ export class PXEService implements PXE { throw new Error('The note has been destroyed.'); } - await this.db.addExtendedNote( + await this.db.addNote( new ExtendedNote( note, contractAddress, diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index a2ee24f8fb51..f4f8f2573596 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -45,7 +45,7 @@ export class SimulatorOracle implements DBOracle { } async getNotes(contractAddress: AztecAddress, storageSlot: Fr) { - const noteDaos = await this.db.getExtendedNotes({ contractAddress, storageSlot }); + const noteDaos = await this.db.getNotes({ contractAddress, storageSlot }); return noteDaos.map(({ contractAddress, storageSlot, nonce, note, innerNoteHash, siloedNullifier, index }) => ({ contractAddress, storageSlot, diff --git a/yarn-project/types/src/mocks.ts b/yarn-project/types/src/mocks.ts index 1a0dcf73b8ab..5257375c5ad8 100644 --- a/yarn-project/types/src/mocks.ts +++ b/yarn-project/types/src/mocks.ts @@ -5,8 +5,7 @@ import { Fr, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - Point, - Proof, + Proof } from '@aztec/circuits.js'; import { makePrivateKernelPublicInputsFinal, makePublicCallRequest } from '@aztec/circuits.js/factories'; import { ContractArtifact } from '@aztec/foundation/abi'; @@ -56,24 +55,16 @@ export const randomDeployedContract = async (): Promise => ({ export const randomExtendedNote = ({ note = Note.random(), + owner = AztecAddress.random(), contractAddress = AztecAddress.random(), txHash = randomTxHash(), - nonce = Fr.random(), storageSlot = Fr.random(), - innerNoteHash = Fr.random(), - siloedNullifier = Fr.random(), - index = Fr.random().value, - publicKey = Point.random(), }: Partial = {}) => { return new ExtendedNote( note, + owner, contractAddress, - txHash, - nonce, storageSlot, - innerNoteHash, - siloedNullifier, - index, - publicKey, + txHash, ); }; diff --git a/yarn-project/types/src/notes/extended_note.ts b/yarn-project/types/src/notes/extended_note.ts index 2ee8cc5ec7a1..1b39068802ec 100644 --- a/yarn-project/types/src/notes/extended_note.ts +++ b/yarn-project/types/src/notes/extended_note.ts @@ -1,5 +1,4 @@ -import { AztecAddress, Fr, Point, PublicKey } from '@aztec/circuits.js'; -import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; +import { AztecAddress, Fr } from '@aztec/circuits.js'; import { BufferReader, Note, TxHash } from '@aztec/types'; /** @@ -9,64 +8,35 @@ export class ExtendedNote { constructor( /** The note as emitted from the Noir contract. */ public note: Note, + /** The owner whose public key was used to encrypt the note. */ + public owner: AztecAddress, /** The contract address this note is created in. */ public contractAddress: AztecAddress, - /** The hash of the tx the note was created in. */ - public txHash: TxHash, - /** The nonce of the note. */ - public nonce: Fr, /** The specific storage location of the note on the contract. */ public storageSlot: Fr, - /** - * Inner note hash of the note. This is customizable by the app circuit. - * We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash. - */ - public innerNoteHash: Fr, - /** The nullifier of the note (siloed by contract address). */ - public siloedNullifier: Fr, - /** The location of the relevant note in the note hash tree. */ - public index: bigint, - /** The public key that was used to encrypt the data. */ - public publicKey: PublicKey, + /** The hash of the tx the note was created in. */ + public txHash: TxHash, ) {} toBuffer(): Buffer { return Buffer.concat([ this.note.toBuffer(), + this.owner.toBuffer(), this.contractAddress.toBuffer(), - this.txHash.buffer, - this.nonce.toBuffer(), this.storageSlot.toBuffer(), - this.innerNoteHash.toBuffer(), - this.siloedNullifier.toBuffer(), - toBufferBE(this.index, 32), - this.publicKey.toBuffer(), + this.txHash.buffer, ]); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); const note = Note.fromBuffer(reader); + const owner = AztecAddress.fromBuffer(reader); const contractAddress = AztecAddress.fromBuffer(reader); - const txHash = new TxHash(reader.readBytes(TxHash.SIZE)); - const nonce = Fr.fromBuffer(reader); const storageSlot = Fr.fromBuffer(reader); - const innerNoteHash = Fr.fromBuffer(reader); - const siloedNullifier = Fr.fromBuffer(reader); - const index = toBigIntBE(reader.readBytes(32)); - const publicKey = Point.fromBuffer(reader); + const txHash = new TxHash(reader.readBytes(TxHash.SIZE)); - return new this( - note, - contractAddress, - txHash, - nonce, - storageSlot, - innerNoteHash, - siloedNullifier, - index, - publicKey, - ); + return new this(note, owner, contractAddress, storageSlot, txHash); } toString() { @@ -77,17 +47,4 @@ export class ExtendedNote { const hex = str.replace(/^0x/, ''); return ExtendedNote.fromBuffer(Buffer.from(hex, 'hex')); } - - /** - * Returns the size in bytes of the extended note. - * @param extendedNote - The extended note. - * @returns - Its size in bytes. - */ - public getSize(extendedNote: ExtendedNote) { - // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer - const indexSize = Math.ceil(Math.log2(Number(extendedNote.index))); - return ( - extendedNote.note.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize + Point.SIZE_IN_BYTES - ); - } } From c1100bec6e5ddcae0836a1b7b1bfcd77d4fb7600 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 12:53:57 +0000 Subject: [PATCH 23/41] WIP --- .../aztec-sandbox/src/examples/token.ts | 4 +- .../aztec.js/src/wallet/base_wallet.ts | 18 ++--- .../blank-react/src/artifacts/Blank.json | 10 +-- .../boxes/blank/src/artifacts/Blank.json | 10 +-- .../boxes/token/src/artifacts/Token.json | 74 +++++++++---------- .../token/src/tests/token.contract.test.ts | 4 +- yarn-project/cli/src/index.ts | 5 +- .../end-to-end/src/e2e_2_pxes.test.ts | 5 +- .../src/e2e_escrow_contract.test.ts | 8 +- .../src/e2e_lending_contract.test.ts | 5 +- .../e2e_multiple_accounts_1_enc_key.test.ts | 5 +- .../src/e2e_sandbox_example.test.ts | 7 +- .../end-to-end/src/e2e_token_contract.test.ts | 4 +- .../src/guides/dapp_testing.test.ts | 13 +++- .../writing_an_account_contract.test.ts | 5 +- yarn-project/end-to-end/src/shared/browser.ts | 10 ++- .../src/shared/cross_chain_test_harness.ts | 4 +- .../src/types/private_kernel_init_types.ts | 55 ++------------ .../src/types/private_kernel_inner_types.ts | 55 ++------------ .../types/private_kernel_ordering_types.ts | 39 ++-------- yarn-project/pxe/src/database/database.ts | 4 +- .../pxe/src/database/memory_db.test.ts | 23 ++---- yarn-project/pxe/src/database/memory_db.ts | 32 +++----- .../pxe/src/database/note_dao.test.ts | 11 ++- yarn-project/pxe/src/database/note_dao.ts | 22 ++---- .../src/note_processor/note_processor.test.ts | 36 ++++----- .../pxe/src/note_processor/note_processor.ts | 72 +++++++++--------- .../pxe/src/pxe_service/pxe_service.ts | 61 +++++---------- .../pxe/src/simulator_oracle/index.ts | 8 +- .../pxe/src/synchronizer/synchronizer.test.ts | 2 +- .../pxe/src/synchronizer/synchronizer.ts | 26 +++---- yarn-project/types/src/interfaces/pxe.ts | 28 ++----- yarn-project/types/src/mocks.ts | 10 +-- 33 files changed, 248 insertions(+), 427 deletions(-) diff --git a/yarn-project/aztec-sandbox/src/examples/token.ts b/yarn-project/aztec-sandbox/src/examples/token.ts index 4cb22e6a7fdf..2d35a5011b7c 100644 --- a/yarn-project/aztec-sandbox/src/examples/token.ts +++ b/yarn-project/aztec-sandbox/src/examples/token.ts @@ -9,6 +9,7 @@ import { } from '@aztec/aztec.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { TokenContract } from '@aztec/noir-contracts/types'; +import { ExtendedNote } from '@aztec/types'; const logger = createDebugLogger('aztec:http-rpc-client'); @@ -57,7 +58,8 @@ async function main() { // Add the newly created "pending shield" note to PXE const pendingShieldsStorageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. const note = new Note([new Fr(ALICE_MINT_BALANCE), aliceSecretHash]); - await pxe.addNote(alice.address, token.address, pendingShieldsStorageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, alice.address, token.address, pendingShieldsStorageSlot, receipt.txHash); + await pxe.addNote(extendedNote); // Make the tokens spendable by redeeming them using the secret (converts the "pending shield note" created above // to a "token note") diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index 58548fc2b2f8..6003bdb24968 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -10,7 +10,6 @@ import { L2Tx, LogFilter, NodeInfo, - Note, NoteFilter, PXE, SyncStatus, @@ -77,18 +76,11 @@ export abstract class BaseWallet implements Wallet { getPublicStorageAt(contract: AztecAddress, storageSlot: Fr): Promise { return this.pxe.getPublicStorageAt(contract, storageSlot); } - addNote( - account: AztecAddress, - contract: AztecAddress, - storageSlot: Fr, - preimage: Note, - txHash: TxHash, - nonce?: Fr, - ): Promise { - return this.pxe.addNote(account, contract, storageSlot, preimage, txHash, nonce); - } - getNoteNonces(contract: AztecAddress, storageSlot: Fr, preimage: Note, txHash: TxHash): Promise { - return this.pxe.getNoteNonces(contract, storageSlot, preimage, txHash); + addNote(note: ExtendedNote): Promise { + return this.pxe.addNote(note); + } + getNoteNonces(note: ExtendedNote): Promise { + return this.pxe.getNoteNonces(note); } viewTx(functionName: string, args: any[], to: AztecAddress, from?: AztecAddress | undefined): Promise { return this.pxe.viewTx(functionName, args, to, from); diff --git a/yarn-project/boxes/blank-react/src/artifacts/Blank.json b/yarn-project/boxes/blank-react/src/artifacts/Blank.json index b626f0d25939..42966767d89d 100644 --- a/yarn-project/boxes/blank-react/src/artifacts/Blank.json +++ b/yarn-project/boxes/blank-react/src/artifacts/Blank.json @@ -37,23 +37,23 @@ "fileMap": { "1": { "source": "contract Blank {\n use dep::aztec::{\n abi,\n oracle::{\n get_public_key::get_public_key,\n },\n };\n\n #[aztec(private)]\n fn constructor() {}\n\n #[aztec(private)]\n fn getPublicKey(\n address: Field,\n ) -> [Field; 2]{\n let pub_key = get_public_key(address);\n \n [pub_key.x, pub_key.y]\n }\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/blank-react/src/contracts/src/main.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/blank-react/src/contracts/src/main.nr" }, "34": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\nuse crate::hash::pedersen_hash;\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n note_hash_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.note_hash_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { note_hash_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n pedersen_hash([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n pedersen_hash(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n pedersen_hash(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" }, "35": { "source": "use crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\nuse crate::hash::pedersen_hash;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n pedersen_hash([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" }, "38": { "source": "use dep::std::hash::{pedersen_hash_with_separator, sha256};\nuse crate::constants_gen::{\n GENERATOR_INDEX__SIGNATURE_PAYLOAD,\n GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET,\n};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n // TODO(#1205) This is probably not the right index to use\n pedersen_hash([secret], GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET)\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n pedersen_hash_with_separator(inputs, hash_index)\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" }, "58": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: Field) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" } } } diff --git a/yarn-project/boxes/blank/src/artifacts/Blank.json b/yarn-project/boxes/blank/src/artifacts/Blank.json index 9be43a48e317..8dcb2487d354 100644 --- a/yarn-project/boxes/blank/src/artifacts/Blank.json +++ b/yarn-project/boxes/blank/src/artifacts/Blank.json @@ -37,23 +37,23 @@ "fileMap": { "1": { "source": "contract Blank {\n use dep::aztec::{\n abi,\n oracle::{\n get_public_key::get_public_key,\n },\n };\n\n #[aztec(private)]\n fn constructor() {}\n\n #[aztec(private)]\n fn getPublicKey(\n address: Field,\n ) -> [Field; 2]{\n let pub_key = get_public_key(address);\n \n [pub_key.x, pub_key.y]\n }\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/blank/src/contracts/src/main.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/blank/src/contracts/src/main.nr" }, "34": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\nuse crate::hash::pedersen_hash;\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n note_hash_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.note_hash_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { note_hash_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n pedersen_hash([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n pedersen_hash(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n pedersen_hash(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" }, "35": { "source": "use crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\nuse crate::hash::pedersen_hash;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n pedersen_hash([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" }, "38": { "source": "use dep::std::hash::{pedersen_hash_with_separator, sha256};\nuse crate::constants_gen::{\n GENERATOR_INDEX__SIGNATURE_PAYLOAD,\n GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET,\n};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n // TODO(#1205) This is probably not the right index to use\n pedersen_hash([secret], GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET)\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n pedersen_hash_with_separator(inputs, hash_index)\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" }, "58": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: Field) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" } } } diff --git a/yarn-project/boxes/token/src/artifacts/Token.json b/yarn-project/boxes/token/src/artifacts/Token.json index 1117f77a9d7b..a9b925326513 100644 --- a/yarn-project/boxes/token/src/artifacts/Token.json +++ b/yarn-project/boxes/token/src/artifacts/Token.json @@ -3185,7 +3185,7 @@ "fileMap": { "1": { "source": "// docs:start:token_all\n// docs:start:imports\nmod types;\n\n// Minimal token implementation that supports `AuthWit` accounts.\n// The auth message follows a similar pattern to the cross-chain message and includes a designated caller.\n// The designated caller is ALWAYS used here, and not based on a flag as cross-chain.\n// message hash = H([caller, contract, selector, ...args])\n// To be read as `caller` calls function at `contract` defined by `selector` with `args`\n// Including a nonce in the message hash ensures that the message can only be used once.\n\ncontract Token {\n // Libs\n use dep::std::option::Option;\n\n use dep::safe_math::SafeU120;\n\n use dep::aztec::{\n note::{\n note_getter_options::NoteGetterOptions,\n note_header::NoteHeader,\n utils as note_utils,\n },\n context::{PrivateContext, PublicContext, Context},\n hash::{compute_secret_hash},\n state_vars::{map::Map, public_state::PublicState, set::Set},\n types::type_serialization::{\n field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN},\n bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN},\n aztec_address_serialization::{AztecAddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN},\n },\n types::address::{AztecAddress},\n selector::compute_selector,\n };\n\n // docs:start:import_authwit\n use dep::authwit::{\n auth::{\n assert_current_call_valid_authwit, \n assert_current_call_valid_authwit_public, \n },\n };\n // docs:end:import_authwit\n\n use crate::types::{\n transparent_note::{TransparentNote, TransparentNoteMethods, TRANSPARENT_NOTE_LEN},\n token_note::{TokenNote, TokenNoteMethods, TOKEN_NOTE_LEN},\n balances_map::{BalancesMap},\n safe_u120_serialization::{SafeU120SerializationMethods, SAFE_U120_SERIALIZED_LEN}\n };\n // docs:end::imports\n\n // docs:start:storage_struct\n struct Storage {\n // docs:start:storage_admin\n admin: PublicState,\n // docs:end:storage_admin\n // docs:start:storage_minters\n minters: Map>,\n // docs:end:storage_minters\n // docs:start:storage_balances\n balances: BalancesMap,\n // docs:end:storage_balances\n total_supply: PublicState,\n // docs:start:storage_pending_shields\n pending_shields: Set,\n // docs:end:storage_pending_shields\n public_balances: Map>,\n }\n // docs:end:storage_struct\n\n // docs:start:storage_init\n impl Storage {\n fn init(context: Context) -> pub Self {\n Storage {\n // docs:start:storage_admin_init\n admin: PublicState::new(\n context,\n 1,\n AztecAddressSerializationMethods,\n ),\n // docs:end:storage_admin_init\n // docs:start:storage_minters_init\n minters: Map::new(\n context,\n 2,\n |context, slot| {\n PublicState::new(\n context,\n slot,\n BoolSerializationMethods,\n )\n },\n ),\n // docs:end:storage_minters_init\n balances: BalancesMap::new(context, 3),\n total_supply: PublicState::new(\n context,\n 4,\n SafeU120SerializationMethods,\n ),\n // docs:start:storage_pending_shields_init\n pending_shields: Set::new(context, 5, TransparentNoteMethods),\n // docs:end:storage_pending_shields_init\n public_balances: Map::new(\n context,\n 6,\n |context, slot| {\n PublicState::new(\n context,\n slot,\n SafeU120SerializationMethods,\n )\n },\n ),\n }\n }\n }\n // docs:end:storage_init\n\n // docs:start:constructor\n #[aztec(private)]\n fn constructor(admin: AztecAddress) {\n let selector = compute_selector(\"_initialize((Field))\");\n context.call_public_function(context.this_address(), selector, [admin.address]);\n }\n // docs:end:constructor\n\n // docs:start:set_admin\n #[aztec(public)]\n fn set_admin(\n new_admin: AztecAddress,\n ) {\n assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), \"caller is not admin\");\n // docs:start:write_admin\n storage.admin.write(new_admin);\n // docs:end:write_admin\n }\n // docs:end:set_admin\n\n // docs:start:set_minter\n #[aztec(public)]\n fn set_minter(\n minter: AztecAddress,\n approve: bool,\n ) {\n // docs:start:read_admin\n assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), \"caller is not admin\");\n // docs:end:read_admin\n // docs:start:write_minter\n storage.minters.at(minter.address).write(approve);\n // docs:end:write_minter\n }\n // docs:end:set_minter\n\n // docs:start:mint_public\n #[aztec(public)]\n fn mint_public(\n to: AztecAddress,\n amount: Field,\n ) -> Field {\n // docs:start:read_minter\n assert(storage.minters.at(context.msg_sender()).read(), \"caller is not minter\");\n // docs:end:read_minter\n let amount = SafeU120::new(amount);\n let new_balance = storage.public_balances.at(to.address).read().add(amount);\n let supply = storage.total_supply.read().add(amount);\n\n storage.public_balances.at(to.address).write(new_balance);\n storage.total_supply.write(supply);\n 1\n }\n // docs:end:mint_public\n\n // docs:start:mint_private\n #[aztec(public)]\n fn mint_private(\n amount: Field,\n secret_hash: Field,\n ) -> Field {\n assert(storage.minters.at(context.msg_sender()).read(), \"caller is not minter\");\n let pending_shields = storage.pending_shields;\n let mut note = TransparentNote::new(amount, secret_hash);\n let supply = storage.total_supply.read().add(SafeU120::new(amount));\n\n storage.total_supply.write(supply);\n // docs:start:insert_from_public\n pending_shields.insert_from_public(&mut note);\n // docs:end:insert_from_public\n 1\n }\n // docs:end:mint_private\n\n // docs:start:shield\n #[aztec(public)]\n fn shield(\n from: AztecAddress,\n amount: Field,\n secret_hash: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n // The redeem is only spendable once, so we need to ensure that you cannot insert multiple shields from the same message.\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n\n let pending_shields = storage.pending_shields;\n let mut note = TransparentNote::new(amount.value as Field, secret_hash);\n\n storage.public_balances.at(from.address).write(from_balance);\n pending_shields.insert_from_public(&mut note);\n 1\n }\n // docs:end:shield\n\n // docs:start:transfer_public\n #[aztec(public)]\n fn transfer_public(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n storage.public_balances.at(from.address).write(from_balance);\n\n let to_balance = storage.public_balances.at(to.address).read().add(amount);\n storage.public_balances.at(to.address).write(to_balance);\n\n 1\n }\n // docs:end:transfer_public\n\n // docs:start:burn_public\n #[aztec(public)]\n fn burn_public(\n from: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n storage.public_balances.at(from.address).write(from_balance);\n\n let new_supply = storage.total_supply.read().sub(amount);\n storage.total_supply.write(new_supply);\n\n 1\n }\n // docs:end:burn_public\n\n // docs:start:redeem_shield\n #[aztec(private)]\n fn redeem_shield(\n to: AztecAddress,\n amount: Field,\n secret: Field,\n ) -> Field {\n let pending_shields = storage.pending_shields;\n let secret_hash = compute_secret_hash(secret);\n let options = NoteGetterOptions::new().select(0, amount).select(1, secret_hash).set_limit(1);\n let notes = pending_shields.get_notes(options);\n let note = notes[0].unwrap_unchecked();\n pending_shields.remove(note);\n\n storage.balances.at(to).add(SafeU120::new(amount));\n\n 1\n }\n // docs:end:redeem_shield\n\n // docs:start:unshield\n #[aztec(private)]\n fn unshield(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n storage.balances.at(from).sub(SafeU120::new(amount));\n\n let selector = compute_selector(\"_increase_public_balance((Field),Field)\");\n let _void = context.call_public_function(context.this_address(), selector, [to.address, amount]);\n\n 1\n }\n // docs:end:unshield\n\n // docs:start:transfer\n #[aztec(private)]\n fn transfer(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n storage.balances.at(from).sub(amount);\n storage.balances.at(to).add(amount);\n\n 1\n }\n // docs:end:transfer\n\n // docs:start:burn\n #[aztec(private)]\n fn burn(\n from: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n storage.balances.at(from).sub(SafeU120::new(amount));\n\n let selector = compute_selector(\"_reduce_total_supply(Field)\");\n let _void = context.call_public_function(context.this_address(), selector, [amount]);\n\n 1\n }\n // docs:end:burn\n\n // docs:start:initialize\n #[aztec(public)]\n internal fn _initialize(\n new_admin: AztecAddress,\n ) {\n storage.admin.write(new_admin);\n storage.minters.at(new_admin.address).write(true);\n }\n // docs:end:initialize\n\n /// Internal ///\n\n // docs:start:increase_public_balance\n #[aztec(public)]\n internal fn _increase_public_balance(\n to: AztecAddress,\n amount: Field,\n ) {\n let new_balance = storage.public_balances.at(to.address).read().add(SafeU120::new(amount));\n storage.public_balances.at(to.address).write(new_balance);\n }\n // docs:end:increase_public_balance\n\n // docs:start:reduce_total_supply\n #[aztec(public)]\n internal fn _reduce_total_supply(\n amount: Field,\n ) {\n // Only to be called from burn.\n let new_supply = storage.total_supply.read().sub(SafeU120::new(amount));\n storage.total_supply.write(new_supply);\n }\n // docs:end:reduce_total_supply\n\n /// Unconstrained ///\n\n // docs:start:admin\n unconstrained fn admin() -> Field {\n storage.admin.read().address\n }\n // docs:end:admin\n\n // docs:start:is_minter\n unconstrained fn is_minter(\n minter: AztecAddress,\n ) -> bool {\n storage.minters.at(minter.address).read()\n }\n // docs:end:is_minter\n\n // docs:start:total_supply\n unconstrained fn total_supply() -> u120 {\n storage.total_supply.read().value\n }\n // docs:end:total_supply\n\n // docs:start:balance_of_private\n unconstrained fn balance_of_private(\n owner: AztecAddress,\n ) -> u120 {\n storage.balances.at(owner).balance_of().value\n }\n // docs:end:balance_of_private\n\n // docs:start:balance_of_public\n unconstrained fn balance_of_public(\n owner: AztecAddress,\n ) -> u120 {\n storage.public_balances.at(owner.address).read().value\n }\n // docs:end:balance_of_public\n\n // Below this point is the stuff of nightmares.\n // This should ideally not be required. What do we do if vastly different types of preimages?\n\n // docs:start:compute_note_hash_and_nullifier\n // Computes note hash and nullifier.\n // Note 1: Needs to be defined by every contract producing logs.\n // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes.\n unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; TOKEN_NOTE_LEN]) -> [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n if (storage_slot == 5) {\n note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, preimage)\n } else {\n note_utils::compute_note_hash_and_nullifier(TokenNoteMethods, note_header, preimage)\n }\n }\n // docs:end:compute_note_hash_and_nullifier\n}\n// docs:end:token_all\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/main.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/main.nr" }, "18": { "source": "struct GrumpkinScalar {\n low: Field,\n high: Field,\n}\n\nimpl GrumpkinScalar {\n pub fn new(low: Field, high: Field) -> Self {\n // TODO: check that the low and high value fit within the grumpkin modulus\n GrumpkinScalar { low, high }\n }\n}\n\nglobal GRUMPKIN_SCALAR_SERIALIZED_LEN: Field = 2;\n\npub fn deserialize_grumpkin_scalar(fields: [Field; GRUMPKIN_SCALAR_SERIALIZED_LEN]) -> GrumpkinScalar {\n GrumpkinScalar { low: fields[0], high: fields[1] }\n}\n\npub fn serialize_grumpkin_scalar(scalar: GrumpkinScalar) -> [Field; GRUMPKIN_SCALAR_SERIALIZED_LEN] {\n [scalar.low, scalar.high]\n}\n", @@ -3205,147 +3205,147 @@ }, "37": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\nuse crate::hash::pedersen_hash;\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n note_hash_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.note_hash_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { note_hash_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n pedersen_hash([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n pedersen_hash(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n pedersen_hash(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" }, "38": { "source": "use crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\nuse crate::hash::pedersen_hash;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n pedersen_hash([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" }, "40": { "source": "use crate::constants_gen::{\n EMPTY_NULLIFIED_COMMITMENT,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n};\n\nuse crate::abi;\n\nuse crate::abi::{\n hash_args,\n CallContext,\n ContractDeploymentData,\n HistoricBlockData,\n FunctionData,\n PrivateCircuitPublicInputs,\n PublicCircuitPublicInputs,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// l1 to l2 messaging\nuse crate::messaging::process_l1_to_l2_message;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem;\n\nuse crate::types::{\n vec::BoundedVec,\n point::Point,\n};\n\nuse crate::utils::arr_copy_slice;\n\nuse crate::oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n};\n\nuse dep::std::option::Option;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: abi::PrivateContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n pending_read_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n nullified_commitments: BoundedVec,\n\n private_call_stack : BoundedVec,\n public_call_stack : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n block_data: HistoricBlockData,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: abi::PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(0),\n pending_read_requests: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n nullified_commitments: BoundedVec::new(0),\n\n block_data: inputs.block_data,\n\n private_call_stack: BoundedVec::new(0),\n public_call_stack: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> Field {\n self.inputs.call_context.function_selector\n }\n\n pub fn finish(self) -> abi::PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = abi::PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n pending_read_requests: self.pending_read_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n nullified_commitments: self.nullified_commitments.storage,\n private_call_stack: self.private_call_stack.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.block_data,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n self.read_requests.push(read_request);\n }\n\n pub fn push_pending_read_request(&mut self, pending_read_request: Field) {\n self.pending_read_requests.push(pending_read_request);\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n // We never push a zero nullified_commitment as zero is used to indicate the end\n // of a field array in private kernel. This routine transparently replaces a\n // zero value into the special placeholder: EMPTY_NULLIFIED_COMMITMENT.\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n let mut non_zero_nullified = nullified_commitment;\n if (non_zero_nullified == 0) {\n non_zero_nullified = EMPTY_NULLIFIED_COMMITMENT;\n }\n self.nullified_commitments.push(non_zero_nullified);\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) \n // docs:end:context_message_portal\n {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n msg_key: Field,\n content: Field,\n secret: Field\n ) \n // docs:end:context_consume_l1_to_l2_message\n {\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, self.this_address(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PrivateCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n function_selector: fields[8], // practically same as fields[1]\n is_delegate_call : fields[9] as bool,\n is_static_call : fields[10] as bool,\n is_contract_deployment: fields[11] as bool,\n },\n // TODO handle the offsets as a variable incremented during extraction?\n args_hash: fields[12],\n return_values: arr_copy_slice(fields, [0; RETURN_VALUES_LENGTH], 13),\n read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 17),\n pending_read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 49),\n new_commitments: arr_copy_slice(fields, [0; MAX_NEW_COMMITMENTS_PER_CALL], 81),\n new_nullifiers: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 97),\n nullified_commitments: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 113),\n private_call_stack: arr_copy_slice(fields, [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], 129),\n public_call_stack: arr_copy_slice(fields, [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], 133),\n new_l2_to_l1_msgs: arr_copy_slice(fields, [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], 137),\n encrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 139),\n unencrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 141),\n encrypted_log_preimages_length: fields[143],\n unencrypted_log_preimages_length: fields[144],\n block_data: HistoricBlockData {\n // Must match order in `private_circuit_public_inputs.hpp`\n note_hash_tree_root : fields[145],\n nullifier_tree_root : fields[146],\n contract_tree_root : fields[147],\n l1_to_l2_messages_tree_root : fields[148],\n blocks_tree_root : fields[149],\n public_data_tree_root: fields[150],\n global_variables_hash: fields[151],\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: Point::new(fields[152], fields[153]),\n constructor_vk_hash : fields[154],\n function_tree_root : fields[155],\n contract_address_salt : fields[156],\n portal_contract_address : fields[157],\n },\n chain_id: fields[158],\n version: fields[159],\n },\n is_execution_request: fields[160] as bool,\n };\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.private_call_stack.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PublicCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n function_selector: fields[8], // practically same as fields[1]\n is_delegate_call : fields[9] as bool,\n is_static_call : fields[10] as bool,\n is_contract_deployment: fields[11] as bool,\n },\n args_hash: fields[12],\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [0; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [0; MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_data: HistoricBlockData::empty(),\n prover_address: 0,\n },\n is_execution_request: true,\n };\n\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.public_call_stack.push(item.hash());\n }\n}\n\nuse crate::abi::{\n ContractStorageRead,\n ContractStorageUpdateRequest\n};\n\nstruct PublicContext {\n inputs: abi::PublicContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_read: BoundedVec,\n public_call_stack: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicContext {\n pub fn new(inputs: abi::PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = ContractStorageRead::empty();\n let empty_storage_update = ContractStorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_read: BoundedVec::new(empty_storage_read),\n public_call_stack: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_data: inputs.block_data,\n prover_address: 0,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n pub fn selector(self) -> Field {\n self.inputs.call_context.function_selector\n }\n\n pub fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n pub fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n pub fn finish(self) -> abi::PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = abi::PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_read: self.contract_storage_read.storage,\n return_values: self.return_values.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.inputs.block_data,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n }\n\n pub fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, this, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_public_function(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = abi::hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n pub fn call_public_function_no_args(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context {\n private: Option::some(context),\n public: Option::none()\n }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context {\n public: Option::some(context),\n private: Option::none()\n }\n }\n\n pub fn none() -> Context {\n Context {\n public: Option::none(),\n private: Option::none()\n }\n }\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/context.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/context.nr" }, "41": { "source": "use dep::std::hash::{pedersen_hash_with_separator, sha256};\nuse crate::constants_gen::{\n GENERATOR_INDEX__SIGNATURE_PAYLOAD,\n GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET,\n};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n // TODO(#1205) This is probably not the right index to use\n pedersen_hash([secret], GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET)\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n pedersen_hash_with_separator(inputs, hash_index)\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" }, "42": { "source": "use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse crate::types::point::Point;\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n log: [Field; N],\n) {\n let _ = oracle::logs::emit_encrypted_log(contract_address, storage_slot, encryption_pub_key, log);\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(\n context: &mut PublicContext,\n log: T,\n) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(\n context: &mut PrivateContext,\n log: T,\n) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/log.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/log.nr" }, "47": { "source": "use crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\nuse crate::constants_gen::EMPTY_NULLIFIED_COMMITMENT;\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n broadcast: bool,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialize = note_interface.serialize;\n let preimage = serialize(*note);\n assert(notify_created_note(storage_slot, preimage, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n let broadcast = note_interface.broadcast;\n broadcast(context, storage_slot, *note);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(\n context: &mut PrivateContext,\n note: Note,\n note_interface: NoteInterface,\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = EMPTY_NULLIFIED_COMMITMENT;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // `nullified_commitment` is used to inform the kernel which pending commitment\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(nullifier, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr" }, "48": { "source": "use dep::std::option::Option;\nuse crate::constants_gen::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n};\nuse crate::oracle;\nuse crate::types::vec::BoundedVec;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: Note,\n) {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n let contract_address = context.this_address();\n assert(header.contract_address == contract_address);\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(\n fields: [Field; N],\n selects: BoundedVec, N>,\n) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n assert(fields[select.field_index] == select.value, \"Mismatch return note field.\");\n }\n}\n\nfn check_notes_order(fields_0: [Field; N], fields_1: [Field; N], sorts: BoundedVec, N>) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let note = get_note_internal(storage_slot, note_interface);\n\n check_note_header(*context, storage_slot, note_interface, note);\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let opt_notes = get_notes_internal(storage_slot, note_interface, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let serialize = note_interface.serialize;\n let fields = serialize(note);\n check_note_header(*context, storage_slot, note_interface, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n };\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n 0,\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n placeholder_note,\n placeholder_fields,\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteViewerOptions,\n) -> [Option; MAX_NOTES_PER_PAGE] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>,\n) -> (u8, [u8; N], [Field; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n num_selects += 1;\n };\n };\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n };\n\n (num_selects, select_by, select_values, sort_by, sort_order)\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_getter.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_getter.nr" }, "50": { "source": "use crate::hash::pedersen_hash;\nuse crate::constants_gen::{GENERATOR_INDEX__UNIQUE_COMMITMENT, GENERATOR_INDEX__SILOED_COMMITMENT};\n\npub fn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([storage_slot, note_hash], 0)\n}\n\npub fn compute_siloed_hash(contract_address: Field, inner_note_hash: Field) -> Field {\n let inputs = [contract_address, inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)\n}\n\npub fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_hash.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_hash.nr" }, "54": { "source": "use crate::note::{\n note_hash::{compute_inner_hash, compute_siloed_hash, compute_unique_hash},\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\npub fn compute_inner_note_hash(\n note_interface: NoteInterface,\n note: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n\n compute_inner_hash(header.storage_slot, note_hash)\n}\n\npub fn compute_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let inner_note_hash = compute_inner_note_hash(note_interface, note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\npub fn compute_unique_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let siloed_note_hash = compute_siloed_note_hash(note_interface, note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_note_hash_for_read_or_nullify(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note_interface, note_with_header)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note_interface, note_with_header)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note_interface, note_with_header)\n }\n\n}\n\npub fn compute_note_hash_and_nullifier(\n note_interface: NoteInterface,\n note_header: NoteHeader,\n preimage: [Field; S],\n) -> [Field; 4] {\n let deserialize = note_interface.deserialize;\n let set_header = note_interface.set_header;\n let mut note = deserialize(arr_copy_slice(preimage, [0; N], 0));\n set_header(&mut note, note_header);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n let inner_note_hash = compute_inner_hash(note_header.storage_slot, note_hash);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let compute_nullifier = note_interface.compute_nullifier;\n let inner_nullifier = compute_nullifier(note);\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/note/utils.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/utils.nr" }, "56": { "source": "#[oracle(packArguments)]\nfn pack_arguments_oracle(_args: [Field; N]) -> Field {}\n\n// TODO: explain what this does.\nunconstrained pub fn pack_arguments(args: [Field; N]) -> Field {\n pack_arguments_oracle(args)\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/arguments.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/arguments.nr" }, "57": { "source": "use crate::constants_gen::CALL_PRIVATE_FUNCTION_RETURN_SIZE;\n\n#[oracle(callPrivateFunction)]\nfn call_private_function_oracle(\n _contract_address: Field,\n _function_selector: Field,\n _args_hash: Field\n) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {}\n\nunconstrained pub fn call_private_function_internal(\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {\n call_private_function_oracle(\n contract_address,\n function_selector,\n args_hash,\n )\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr" }, "61": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: Field) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" }, "62": { "source": "use crate::oracle::get_public_key::get_public_key;\nuse crate::types::point::Point;\n\n#[oracle(getSecretKey)]\nfn get_secret_key_oracle(\n _owner: Point,\n) -> [Field; dep::std::grumpkin_scalar::GRUMPKIN_SCALAR_SERIALIZED_LEN] {\n}\n\nunconstrained fn get_secret_key_internal(owner_public_key: Point) -> dep::std::grumpkin_scalar::GrumpkinScalar {\n dep::std::grumpkin_scalar::deserialize_grumpkin_scalar(get_secret_key_oracle(owner_public_key))\n}\n\npub fn get_secret_key(owner: Field) -> dep::std::grumpkin_scalar::GrumpkinScalar {\n let owner_public_key = get_public_key(owner);\n let secret = get_secret_key_internal(owner_public_key);\n\n // Constrain the owner - Nullifier secret key is currently just the encryption private key so we can constrain\n // the owner by deriving the public key from the secret key and checking the result.\n let computed_public_key = dep::std::grumpkin_scalar_mul::grumpkin_fixed_base(secret);\n assert(owner_public_key.x == computed_public_key[0]);\n assert(owner_public_key.y == computed_public_key[1]);\n\n secret\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key.nr" }, "63": { "source": "\n\n#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/rand.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/rand.nr" }, "64": { "source": "\n// contract_address + \n// args_hash +\n// crate::abi::FUNCTION_DATA_SIZE +\n// crate::abi::CALL_CONTEXT_SIZE +\n// = 2 + 4 + 7\nglobal ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE: Field = 13;\n\n#[oracle(enqueuePublicFunctionCall)]\nfn enqueue_public_function_call_oracle(\n _contract_address: Field, \n _function_selector: Field, \n _args_hash: Field,\n) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {}\n\nunconstrained pub fn enqueue_public_function_call_internal(\n contract_address: Field, \n function_selector: Field,\n args_hash: Field\n) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {\n enqueue_public_function_call_oracle(\n contract_address, \n function_selector, \n args_hash,\n )\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr" }, "65": { "source": "use crate::constants_gen::RETURN_VALUES_LENGTH;\n\n#[oracle(callPublicFunction)]\nfn call_public_function_oracle(\n _contract_address: Field, \n _function_selector: Field, \n _args_hash: Field\n) -> [Field; RETURN_VALUES_LENGTH] {}\n\nunconstrained pub fn call_public_function_internal(\n contract_address: Field, \n function_selector: Field,\n args_hash: Field\n) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_oracle(\n contract_address, \n function_selector, \n args_hash,\n )\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/public_call.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/public_call.nr" }, "66": { "source": "use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _preimage: [Field; N],\n _inner_note_hash: Field,\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n preimage: [Field; N],\n inner_note_hash: Field,\n) -> Field {\n notify_created_note_oracle(storage_slot, preimage, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(\n _nullifier: Field,\n _inner_note_hash: Field,\n) -> Field {}\n\nunconstrained pub fn notify_nullified_note(\n nullifier: Field,\n inner_note_hash: Field,\n) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _return_size: u32,\n _placeholder_fields: [Field; S],\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n mut placeholder_fields: [Field; S],\n)-> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(storage_slot, num_selects, select_by, select_values, sort_by, sort_order, limit, offset, return_size, placeholder_fields)\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n) -> [Option; S] {\n let fields = get_notes_oracle_wrapper(storage_slot, num_selects, select_by, select_values, sort_by, sort_order, limit, offset, placeholder_fields);\n let num_notes = fields[0] as u32;\n let contract_address = fields[1];\n let deserialize = note_interface.deserialize;\n let set_header = note_interface.set_header;\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let preimage = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = deserialize(preimage);\n set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n };\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(\n _inner_nullifier: Field,\n) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/notes.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/notes.nr" }, "67": { "source": "\n#[oracle(storageRead)]\nfn storage_read_oracle(\n _storage_slot: Field,\n _number_of_elements: Field,\n) -> [Field; N] {}\n\nunconstrained fn storage_read_oracle_wrapper(_storage_slot: Field)-> [Field; N] {\n storage_read_oracle(_storage_slot, N)\n}\n\npub fn storage_read(\n storage_slot: Field,\n deserialize: fn ([Field; N]) -> T,\n) -> T {\n let fields = storage_read_oracle_wrapper(storage_slot);\n deserialize(fields)\n}\n\n#[oracle(storageWrite)]\nfn storage_write_oracle(\n _storage_slot: Field,\n _values: [Field; N],\n) -> [Field; N] {}\n\n// TODO: Remove return value.\nunconstrained pub fn storage_write(\n storage_slot: Field,\n fields: [Field; N]\n) {\n let _hash = storage_write_oracle(storage_slot, fields);\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/storage.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/storage.nr" }, "68": { "source": "use crate::types::point::Point;\nuse crate::constants_gen::NUM_FIELDS_PER_SHA256;\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: Field,\n _storage_slot: Field,\n _encryption_pub_key: Point,\n _preimage: [Field; N],\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n preimage: [Field; N],\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n encryption_pub_key,\n preimage,\n ), 0]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(_contract_address: Field, _event_selector: Field, _message: T) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(contract_address: Field, event_selector: Field, message: T) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/logs.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/logs.nr" }, "69": { "source": "use crate::abi::FunctionData;\nuse crate::abi::PrivateCircuitPublicInputs;\nuse crate::constants_gen::GENERATOR_INDEX__CALL_STACK_ITEM;\nuse crate::hash::pedersen_hash;\n\nstruct PrivateCallStackItem {\n contract_address: Field,\n function_data: FunctionData,\n public_inputs: PrivateCircuitPublicInputs,\n is_execution_request: bool,\n}\n\nimpl PrivateCallStackItem {\n pub fn hash(self) -> Field {\n pedersen_hash([\n self.contract_address,\n self.function_data.hash(),\n self.public_inputs.hash(),\n ], GENERATOR_INDEX__CALL_STACK_ITEM)\n }\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/private_call_stack_item.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/private_call_stack_item.nr" }, "70": { "source": "use crate::{\n abi,\n hash::pedersen_hash,\n abi::{\n PublicCircuitPublicInputs,\n FunctionData,\n },\n};\nuse crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n GENERATOR_INDEX__CALL_STACK_ITEM,\n};\n\n// oracles\nuse crate::oracle::{\n enqueue_public_function_call::enqueue_public_function_call_internal,\n};\n\nstruct PublicCallStackItem {\n contract_address: Field,\n function_data: FunctionData,\n public_inputs: PublicCircuitPublicInputs,\n is_execution_request: bool,\n}\n\nimpl PublicCallStackItem {\n pub fn hash(self) -> Field {\n pedersen_hash([\n self.contract_address,\n self.function_data.hash(),\n self.public_inputs.hash(),\n ], GENERATOR_INDEX__CALL_STACK_ITEM)\n }\n}\n\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/public_call_stack_item.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/public_call_stack_item.nr" }, "74": { "source": "use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse crate::hash::pedersen_hash;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n ) -> Map {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map {\n context,\n storage_slot,\n state_var_constructor,\n }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: Field) -> V {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key],0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/map.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/map.nr" }, "75": { "source": "use crate::context::{Context};\nuse crate::oracle::storage::storage_read;\nuse crate::oracle::storage::storage_write;\nuse crate::types::type_serialization::TypeSerializationInterface;\nuse dep::std::option::Option;\n\n// docs:start:public_state_struct\nstruct PublicState {\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n}\n// docs:end:public_state_struct\n\nimpl PublicState {\n // docs:start:public_state_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicState {\n context,\n storage_slot,\n serialization_methods,\n }\n }\n // docs:end:public_state_struct_new\n\n // docs:start:public_state_struct_read\n pub fn read(self) -> T {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n storage_read(self.storage_slot, self.serialization_methods.deserialize)\n }\n // docs:end:public_state_struct_read\n\n // docs:start:public_state_struct_write\n pub fn write(self, value: T) {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n let serialize = self.serialization_methods.serialize;\n let fields = serialize(value);\n storage_write(self.storage_slot, fields);\n }\n // docs:end:public_state_struct_write\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr" }, "76": { "source": "use dep::std::option::Option;\nuse crate::abi::PublicContextInputs;\nuse crate::constants_gen::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL};\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, create_note_hash_from_public, destroy_note},\n note_getter::{get_notes, view_notes},\n note_getter_options::NoteGetterOptions,\n note_header::NoteHeader,\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n};\n\n// docs:start:struct\nstruct Set {\n context: Context,\n storage_slot: Field,\n note_interface: NoteInterface,\n}\n// docs:end:struct\n\nimpl Set {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n note_interface: NoteInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Set {\n context,\n storage_slot,\n note_interface,\n }\n }\n // docs:end:new\n\n // docs:start:insert\n pub fn insert(self,\n note: &mut Note,\n broadcast: bool,\n ) {\n create_note(\n self.context.private.unwrap(),\n self.storage_slot,\n note,\n self.note_interface,\n broadcast,\n );\n }\n // docs:end:insert\n\n // docs:start:insert_from_public\n pub fn insert_from_public(self, note: &mut Note) {\n create_note_hash_from_public(\n self.context.public.unwrap(),\n self.storage_slot,\n note,\n self.note_interface,\n );\n }\n // docs:end:insert_from_public\n \n // DEPRECATED\n fn assert_contains_and_remove(_self: Self, _note: &mut Note, _nonce: Field) {\n assert(false, \"`assert_contains_and_remove` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note.\");\n }\n\n // DEPRECATED\n fn assert_contains_and_remove_publicly_created(_self: Self, _note: &mut Note) {\n assert(false, \"`assert_contains_and_remove_publicly_created` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note.\");\n }\n\n // docs:start:remove\n pub fn remove(self, note: Note) {\n let context = self.context.private.unwrap();\n let note_hash = compute_note_hash_for_read_or_nullify(self.note_interface, note);\n let has_been_read = context.read_requests.any(|r| r == note_hash);\n assert(has_been_read, \"Can only remove a note that has been read from the set.\");\n\n destroy_note(\n context,\n note,\n self.note_interface,\n );\n }\n // docs:end:remove\n\n // docs:start:get_notes\n pub fn get_notes(\n self,\n options: NoteGetterOptions,\n ) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let storage_slot = self.storage_slot;\n let opt_notes = get_notes(\n self.context.private.unwrap(),\n storage_slot,\n self.note_interface,\n options,\n );\n opt_notes\n }\n // docs:end:get_notes\n\n // docs:start:view_notes\n unconstrained pub fn view_notes(\n self,\n options: NoteViewerOptions,\n ) -> [Option; MAX_NOTES_PER_PAGE] {\n view_notes(self.storage_slot, self.note_interface, options)\n }\n // docs:end:view_notes\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/set.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/set.nr" }, "79": { "source": "struct AztecAddress {\n address: Field\n}\n\nimpl AztecAddress {\n pub fn new(address: Field) -> Self {\n Self {\n address\n }\n }\n\n pub fn eq(self: Self, other: Self) -> bool {\n self.address == other.address\n }\n\n pub fn serialize(self: Self) -> [Field; 1] {\n [self.address]\n }\n\n pub fn deserialize(fields: [Field; 1]) -> Self {\n Self {\n address: fields[0]\n }\n }\n}\n\nstruct EthereumAddress {\n address: Field\n}\n\nimpl EthereumAddress {\n pub fn new(address: Field) -> Self {\n // Check that it actually will fit. Spending a lot of constraints here :grimacing:\n let bytes = address.to_be_bytes(32);\n for i in 0..12 {\n assert(bytes[i] == 0, \"Value too large for an ethereum address\");\n }\n Self {\n address\n }\n }\n\n\n pub fn serialize(self: Self) -> [Field; 1] {\n [self.address]\n }\n\n pub fn deserialize(fields: [Field; 1]) -> Self {\n Self {\n address: fields[0]\n }\n }\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/types/address.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/address.nr" }, "81": { "source": "\nstruct BoundedVec {\n storage: [T; MaxLen],\n len: Field,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0 }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64);\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn push_array(&mut self, array: [T; Len]) {\n let newLen = self.len + array.len();\n assert(newLen as u64 <= MaxLen as u64);\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = newLen;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n\n let elem = self.storage[self.len - 1];\n self.len -= 1;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}\n\n#[test]\nfn test_vec_push_pop() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n assert(vec.len == 0);\n vec.push(2);\n assert(vec.len == 1);\n vec.push(4);\n assert(vec.len == 2);\n vec.push(6);\n assert(vec.len == 3);\n let x = vec.pop();\n assert(x == 6);\n assert(vec.len == 2);\n assert(vec.get(0) == 2);\n assert(vec.get(1) == 4);\n}\n\n#[test]\nfn test_vec_push_array() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4]);\n assert(vec.len == 2);\n assert(vec.get(0) == 2);\n assert(vec.get(1) == 4);\n}\n\n#[test(should_fail)]\nfn test_vec_get_out_of_bound() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4]);\n let _x = vec.get(2);\n}\n\n#[test(should_fail)]\nfn test_vec_get_not_declared() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2]);\n let _x = vec.get(1);\n}\n\n#[test(should_fail)]\nfn test_vec_get_uninitialized() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n let _x = vec.get(0);\n}\n\n#[test(should_fail)]\nfn test_vec_push_overflow() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push(1);\n vec.push(2);\n}\n\n#[test]\nfn test_vec_any() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4, 6]);\n assert(vec.any(|v| v == 2) == true);\n assert(vec.any(|v| v == 4) == true);\n assert(vec.any(|v| v == 6) == true);\n assert(vec.any(|v| v == 3) == false);\n}\n\n#[test]\nfn test_vec_any_not_default() {\n let default_value = 1;\n let mut vec: BoundedVec = BoundedVec::new(default_value);\n vec.push_array([2, 4]);\n assert(vec.any(|v| v == default_value) == false);\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/types/vec.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/vec.nr" }, "83": { "source": "use crate::types::type_serialization::TypeSerializationInterface;\n\nglobal BOOL_SERIALIZED_LEN: Field = 1;\n\nfn deserializeBool(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool {\n fields[0] as bool\n}\n\nfn serializeBool(value: bool) -> [Field; BOOL_SERIALIZED_LEN] {\n [value as Field]\n}\n\nglobal BoolSerializationMethods = TypeSerializationInterface {\n deserialize: deserializeBool,\n serialize: serializeBool,\n};", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization.nr" }, "86": { "source": "use crate::types::type_serialization::TypeSerializationInterface;\nuse crate::types::address::AztecAddress;\n\nglobal AZTEC_ADDRESS_SERIALIZED_LEN: Field = 1;\n\nfn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> AztecAddress {\n AztecAddress::new(fields[0])\n}\n\nfn serialize(value: AztecAddress) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [value.address]\n}\n\nglobal AztecAddressSerializationMethods = TypeSerializationInterface {\n deserialize,\n serialize,\n};", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization.nr" }, "87": { "source": "pub fn arr_copy_slice(\n src: [T; N],\n mut dst: [T; M],\n offset: Field,\n) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n\npub fn field_from_bytes(bytes: [u8; N], big_endian: bool) -> Field {\n assert(bytes.len() as u32 < 32, \"field_from_bytes: N must be less than 32\");\n let mut as_field = 0;\n let mut offset = 1;\n for i in 0..N {\n let mut index = i;\n if big_endian {\n index = N - i - 1;\n }\n as_field += (bytes[index] as Field) * offset;\n offset *= 256;\n }\n\n as_field\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/utils.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/utils.nr" }, "90": { "source": "use dep::aztec::{\n context::{PrivateContext, PublicContext, Context},\n constants_gen::{EMPTY_NULLIFIED_COMMITMENT, GENERATOR_INDEX__SIGNATURE_PAYLOAD},\n types::address::AztecAddress,\n abi::hash_args,\n hash::pedersen_hash,\n};\n\nglobal IS_VALID_SELECTOR = 0xe86ab4ff;\nglobal IS_VALID_PUBLIC_SELECTOR = 0xf3661153;\n\n// @todo #2676 Should use different generator than the payload to limit probability of collisions.\n\n// docs:start:assert_valid_authwit\n// Assert that `on_behalf_of` have authorized `message_hash` with a valid authentication witness\npub fn assert_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress, message_hash: Field) {\n let result = context.call_private_function(on_behalf_of.address, IS_VALID_SELECTOR, [message_hash])[0];\n context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT);\n assert(result == IS_VALID_SELECTOR, \"Message not authorized by account\");\n}\n// docs:end:assert_valid_authwit\n\n// docs:start:assert_current_call_valid_authwit\n// Assert that `on_behalf_of` have authorized the current call with a valid authentication witness\npub fn assert_current_call_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress) {\n // message_hash = H(caller, contract_this, selector, args_hash)\n let message_hash = pedersen_hash(\n [context.msg_sender(), context.this_address(), context.selector(), context.args_hash],\n GENERATOR_INDEX__SIGNATURE_PAYLOAD\n );\n assert_valid_authwit(context, on_behalf_of, message_hash);\n}\n// docs:end:assert_current_call_valid_authwit\n\n// docs:start:assert_valid_authwit_public\n// Assert that `on_behalf_of` have authorized `message_hash` in a public context\npub fn assert_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress, message_hash: Field) {\n let result = context.call_public_function(on_behalf_of.address, IS_VALID_PUBLIC_SELECTOR, [message_hash])[0];\n context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT);\n assert(result == IS_VALID_SELECTOR, \"Message not authorized by account\");\n}\n// docs:end:assert_valid_authwit_public\n\n// docs:start:assert_current_call_valid_authwit_public\n// Assert that `on_behalf_of` have authorized the current call in a public context\npub fn assert_current_call_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress) {\n // message_hash = H(caller, contract_this, selector, args_hash)\n let message_hash = pedersen_hash(\n [context.msg_sender(), context.this_address(), context.selector(), context.args_hash],\n GENERATOR_INDEX__SIGNATURE_PAYLOAD\n );\n assert_valid_authwit_public(context, on_behalf_of, message_hash);\n}\n// docs:end:assert_current_call_valid_authwit_public\n\n// docs:start:compute_authwit_message_hash\n// Compute the message hash to be used by an authentication witness \npub fn compute_authwit_message_hash(\n caller: AztecAddress, \n target: AztecAddress, \n selector: Field, \n args: [Field; N]\n) -> Field {\n let args_hash = hash_args(args);\n pedersen_hash([caller.address, target.address, selector, args_hash], GENERATOR_INDEX__SIGNATURE_PAYLOAD)\n}\n// docs:end:compute_authwit_message_hash", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/authwit/src/auth.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/authwit/src/auth.nr" }, "92": { "source": "struct SafeU120 {\n value: u120,\n}\n\nimpl SafeU120 {\n pub fn min() -> Self {\n Self {\n value: 0\n }\n }\n\n pub fn max() -> Self {\n Self {\n value: 0xffffffffffffffffffffffffffffff\n }\n }\n\n pub fn new(\n value: Field,\n ) -> Self {\n // Check that it actually will fit. Spending a lot of constraints here :grimacing:\n let bytes = value.to_be_bytes(32);\n for i in 0..17 {\n assert(bytes[i] == 0, \"Value too large for SafeU120\");\n }\n Self {\n value: value as u120\n }\n }\n\n pub fn is_zero(\n self: Self,\n ) -> bool {\n self.value == 0\n }\n\n pub fn eq(\n self: Self,\n other: Self\n ) -> bool {\n self.value == other.value\n }\n\n pub fn lt(self: Self, other: Self) -> bool {\n self.value < other.value\n }\n\n pub fn le(self: Self, other: Self) -> bool {\n self.value <= other.value\n }\n\n pub fn gt(self: Self, other: Self) -> bool {\n self.value > other.value\n }\n\n pub fn ge(self: Self, other: Self) -> bool {\n self.value >= other.value\n }\n\n pub fn sub(\n self: Self,\n b: Self,\n ) -> Self {\n assert(self.value >= b.value, \"Underflow\");\n Self {\n value: self.value - b.value\n }\n }\n\n pub fn add(\n self: Self,\n b: Self,\n ) -> Self {\n let c: u120 = self.value + b.value;\n assert(c >= self.value, \"Overflow\");\n Self {\n value: c\n }\n }\n\n pub fn mul(\n self: Self,\n b: Self,\n ) -> Self {\n let c: u120 = self.value * b.value;\n if !b.is_zero() {\n assert(c / b.value == self.value, \"Overflow\");\n }\n Self {\n value: c\n }\n }\n\n pub fn div(\n self: Self,\n b: Self,\n ) -> Self {\n assert(!b.is_zero(), \"Divide by zero\");\n Self {\n value: self.value / b.value\n }\n }\n\n pub fn mul_div(\n self: Self,\n b: Self,\n divisor: Self\n ) -> Self {\n self.mul(b).div(divisor)\n }\n\n pub fn mul_div_up(\n self: Self,\n b: Self,\n divisor: Self\n ) -> Self {\n let c = self.mul(b);\n assert(!divisor.is_zero(), \"Divide by zero\");\n let adder = ((self.value * b.value % divisor.value) as u120 > 0) as u120;\n c.div(divisor).add(Self {value: adder})\n }\n\n // todo: implement mul_div with 240 bit intermediate values.\n}\n\n#[test]\nfn test_init() {\n let a = SafeU120::new(1);\n assert(a.value == 1);\n}\n\n#[test]\nfn test_init_max() {\n let a = SafeU120::max();\n assert(a.value == 0xffffffffffffffffffffffffffffff);\n}\n\n#[test]\nfn test_init_min() {\n let a = SafeU120::min();\n assert(a.value == 0);\n}\n\n#[test]\nfn test_is_zero() {\n let a = SafeU120::min();\n assert(a.value == 0);\n assert(a.is_zero() == true);\n}\n\n#[test]\nfn test_eq() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(1);\n assert(a.eq(b));\n}\n\n#[test]\nfn test_lt() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n assert(a.lt(b));\n assert(b.lt(a) == false);\n}\n\n\n#[test]\nfn test_le() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(2);\n let c = SafeU120::new(5);\n assert(a.le(b));\n assert(a.le(c));\n assert(c.le(a) == false);\n}\n\n#[test]\nfn test_gt() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n assert(b.gt(a));\n assert(a.gt(b) == false);\n}\n\n\n#[test]\nfn test_ge() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(2);\n let c = SafeU120::new(5);\n assert(a.ge(b));\n assert(a.ge(c) == false);\n assert(c.ge(a));\n}\n\n#[test(should_fail)]\nfn test_init_too_large() {\n let b = SafeU120::max().value as Field + 1; // max + 1\n let _a = SafeU120::new(b);\n}\n\n#[test]\nfn test_add() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n let c = SafeU120::add(a, b);\n assert(c.value == 3);\n}\n\n#[test(should_fail)]\nfn test_add_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(1);\n let _c = SafeU120::add(a, b);\n}\n\n#[test]\nfn test_sub() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(1);\n let c = SafeU120::sub(a, b);\n assert(c.value == 1);\n}\n\n#[test(should_fail)]\nfn test_sub_underflow() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n let _c = SafeU120::sub(a, b);\n}\n\n#[test]\nfn test_mul() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(3);\n let c = SafeU120::mul(a, b);\n assert(c.value == 6);\n}\n\n#[test(should_fail)]\nfn test_mul_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let _c = SafeU120::mul(a, b);\n}\n\n#[test]\nfn test_div() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::div(a, b);\n assert(c.value == 2);\n}\n\n#[test(should_fail)]\nfn test_div_by_zero() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(0);\n let _c = SafeU120::div(a, b);\n}\n\n#[test]\nfn test_mul_div() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(2);\n let d = SafeU120::mul_div(a, b, c);\n assert(d.value == 9);\n}\n\n#[test(should_fail)]\nfn test_mul_div_zero_divisor() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(0);\n let _d = SafeU120::mul_div(a, b, c);\n}\n\n#[test(should_fail)]\nfn test_mul_div_ghost_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let c = SafeU120::new(4);\n let _d = SafeU120::mul_div(a, b, c);\n}\n\n#[test]\nfn test_mul_div_up_rounding() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(5);\n let d = SafeU120::mul_div_up(a, b, c);\n assert(d.value == 4);\n}\n\n#[test]\nfn test_mul_div_up_non_rounding() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(2);\n let d = SafeU120::mul_div_up(a, b, c);\n assert(d.value == 9);\n}\n\n\n#[test(should_fail)]\nfn test_mul_div_up_ghost_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let c = SafeU120::new(9);\n let _d = SafeU120::mul_div_up(a, b, c);\n}\n\n// It should not be possible for us to overflow `mul_div_up` through the adder, since that require the divisor to be 1\n// since we otherwise would not be at the max value. If divisor is 1, adder is 0.\n#[test(should_fail)]\nfn test_mul_div_up_zero_divisor() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(0);\n let _d = SafeU120::mul_div_up(a, b, c);\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/safe-math/src/safe_u120.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/safe-math/src/safe_u120.nr" }, "98": { "source": "// docs:start:token_types_all\nuse dep::aztec::{\n note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_siloed_note_hash,\n },\n hash::{compute_secret_hash, pedersen_hash},\n context::PrivateContext,\n};\n\nglobal TRANSPARENT_NOTE_LEN: Field = 2;\n\n// Transparent note represents a note that is created in the clear (public execution),\n// but can only be spent by those that know the preimage of the \"secret_hash\"\nstruct TransparentNote {\n amount: Field,\n secret_hash: Field,\n // the secret is just here for ease of use and won't be (de)serialized\n secret: Field,\n // header is just here to satisfy the NoteInterface\n header: NoteHeader,\n}\n\nimpl TransparentNote {\n\n // CONSTRUCTORS\n\n pub fn new(amount: Field, secret_hash: Field) -> Self {\n TransparentNote {\n amount: amount,\n secret_hash: secret_hash,\n secret: 0,\n header: NoteHeader::empty(),\n }\n }\n\n // new oracle call primitive\n // get me the secret corresponding to this hash\n pub fn new_from_secret(amount: Field, secret: Field) -> Self {\n TransparentNote {\n amount: amount,\n secret_hash: compute_secret_hash(secret),\n secret: secret,\n header: NoteHeader::empty(),\n }\n }\n\n\n // STANDARD NOTE_INTERFACE FUNCTIONS\n\n pub fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] {\n [self.amount, self.secret_hash]\n }\n\n pub fn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> Self {\n TransparentNote {\n amount: preimage[0],\n secret_hash: preimage[1],\n secret: 0,\n header: NoteHeader::empty(),\n }\n }\n\n pub fn compute_note_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n self.amount,\n self.secret_hash,\n ],0)\n }\n\n pub fn compute_nullifier(self) -> Field {\n // TODO(#1386): should use `compute_note_hash_for_read_or_nullify` once public functions inject nonce!\n let siloed_note_hash = compute_siloed_note_hash(TransparentNoteMethods, self);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([self.secret, siloed_note_hash], 0)\n }\n\n pub fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n\n // CUSTOM FUNCTIONS FOR THIS NOTE TYPE\n\n pub fn knows_secret(self, secret: Field) {\n let hash = compute_secret_hash(secret);\n assert(self.secret_hash == hash);\n }\n}\n\nfn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> TransparentNote {\n TransparentNote::deserialize(preimage)\n}\n\nfn serialize(note: TransparentNote) -> [Field; TRANSPARENT_NOTE_LEN] {\n note.serialize()\n}\n\nfn compute_note_hash(note: TransparentNote) -> Field {\n note.compute_note_hash()\n}\n\nfn compute_nullifier(note: TransparentNote) -> Field {\n note.compute_nullifier()\n}\n\nfn get_header(note: TransparentNote) -> NoteHeader {\n note.header\n}\n\nfn set_header(note: &mut TransparentNote, header: NoteHeader) {\n note.set_header(header)\n}\n\nfn broadcast(context: &mut PrivateContext, slot: Field, note: TransparentNote) {\n assert(false, \"TransparentNote does not support broadcast\");\n}\n\nglobal TransparentNoteMethods = NoteInterface {\n deserialize,\n serialize,\n compute_note_hash,\n compute_nullifier,\n get_header,\n set_header,\n broadcast,\n};\n// docs:end:token_types_all", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/transparent_note.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/transparent_note.nr" }, "99": { "source": "use dep::std::option::Option;\nuse dep::safe_math::SafeU120;\nuse dep::aztec::{\n context::Context,\n constants_gen::MAX_READ_REQUESTS_PER_CALL,\n state_vars::set::Set,\n types::address::AztecAddress,\n};\nuse dep::aztec::note::{\n note_getter::view_notes,\n note_getter_options::{NoteGetterOptions, SortOrder},\n note_viewer_options::NoteViewerOptions\n};\nuse dep::aztec::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_note_hash_for_read_or_nullify,\n};\nuse dep::aztec::oracle::{\n rand::rand,\n get_secret_key::get_secret_key,\n get_public_key::get_public_key,\n};\n\nuse crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN, TokenNoteMethods};\n\n// A set implementing standard manipulation of balances.\n// Does not require spending key, but only knowledge.\n// Spending key requirement should be enforced by the contract using this.\nstruct BalanceSet {\n context: Context,\n owner: AztecAddress,\n set: Set\n}\n\nimpl BalanceSet {\n pub fn new(context: Context, owner: AztecAddress, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n let set = Set {\n context,\n storage_slot,\n note_interface: TokenNoteMethods,\n };\n Self {\n context,\n owner,\n set,\n }\n }\n\n unconstrained pub fn balance_of(self: Self) -> SafeU120 {\n self.balance_of_with_offset(0)\n }\n\n unconstrained pub fn balance_of_with_offset(self: Self, offset: u32) -> SafeU120 {\n // Same as SafeU120::new(0), but fewer constraints because no check. \n let mut balance = SafeU120::min();\n // docs:start:view_notes\n let options = NoteViewerOptions::new().set_offset(offset);\n let opt_notes = self.set.view_notes(options);\n // docs:end:view_notes\n let len = opt_notes.len();\n for i in 0..len {\n if opt_notes[i].is_some() {\n balance = balance.add(opt_notes[i].unwrap_unchecked().amount);\n }\n }\n if (opt_notes[len - 1].is_some()) {\n balance = balance.add(self.balance_of_with_offset(offset + opt_notes.len() as u32));\n }\n\n balance\n }\n\n pub fn add(self: Self, addend: SafeU120) {\n let mut addend_note = TokenNote::new(addend, self.owner);\n\n // docs:start:insert\n self.set.insert(&mut addend_note, true);\n // docs:end:insert\n }\n\n pub fn sub(self: Self, subtrahend: SafeU120) {\n // docs:start:get_notes\n let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend);\n let maybe_notes = self.set.get_notes(options);\n // docs:end:get_notes\n\n let mut minuend: SafeU120 = SafeU120::min();\n for i in 0..maybe_notes.len() {\n if maybe_notes[i].is_some() {\n let note = maybe_notes[i].unwrap_unchecked();\n\n // Removes the note from the owner's set of notes.\n // This will call the the `compute_nullifer` function of the `token_note`\n // which require knowledge of the secret key (currently the users encryption key).\n // The contract logic must ensure that the spending key is used as well.\n // docs:start:remove\n self.set.remove(note);\n // docs:end:remove\n\n minuend = minuend.add(note.amount);\n }\n }\n\n // This is to provide a nicer error msg,\n // without it minuend-subtrahend would still catch it, but more generic error then.\n // without the == true, it includes 'minuend.ge(subtrahend)' as part of the error.\n assert(minuend.ge(subtrahend) == true, \"Balance too low\");\n\n self.add(minuend.sub(subtrahend));\n }\n}\n\npub fn filter_notes_min_sum(notes: [Option; MAX_READ_REQUESTS_PER_CALL], min_sum: SafeU120) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let mut selected = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let mut sum = SafeU120::min();\n for i in 0..notes.len() {\n if notes[i].is_some() & sum.lt(min_sum) {\n let note = notes[i].unwrap_unchecked();\n selected[i] = Option::some(note);\n sum = sum.add(note.amount);\n }\n }\n selected\n}", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balance_set.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balance_set.nr" }, "100": { "source": "use dep::aztec::context::{PrivateContext, PublicContext, Context};\nuse dep::aztec::types::address::AztecAddress;\nuse dep::std::option::Option;\nuse crate::types::balance_set::BalanceSet;\nuse dep::aztec::hash::pedersen_hash;\n\nstruct BalancesMap {\n context: Context,\n storage_slot: Field,\n}\n\nimpl BalancesMap {\n pub fn new(\n context: Context,\n storage_slot: Field,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self {\n context,\n storage_slot,\n }\n }\n\n pub fn at(self, owner: AztecAddress) -> BalanceSet {\n let derived_storage_slot = pedersen_hash([self.storage_slot, owner.address],0);\n BalanceSet::new(self.context, owner, derived_storage_slot)\n }\n}\n", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balances_map.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balances_map.nr" }, "101": { "source": "use dep::aztec::{\n note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_note_hash_for_read_or_nullify,\n },\n hash::pedersen_hash,\n context::PrivateContext,\n constants_gen::MAX_READ_REQUESTS_PER_CALL,\n state_vars::set::Set,\n log::emit_encrypted_log,\n};\nuse dep::aztec::types::address::AztecAddress;\nuse dep::aztec::oracle::{\n rand::rand,\n get_secret_key::get_secret_key,\n get_public_key::get_public_key,\n};\n\nuse dep::safe_math::SafeU120;\nuse dep::std::option::Option;\n\nglobal TOKEN_NOTE_LEN: Field = 3; // 3 plus a header.\n\nstruct TokenNote {\n // the amount of tokens in the note\n amount: SafeU120,\n // the provider of secrets for the nullifier. The owner (recipient) to ensure that the note \n // can be privately spent. When nullifier secret and encryption private key is same \n // we can simply use the owner for this one.\n owner: AztecAddress,\n // randomness of the note to hide contents.\n randomness: Field,\n // the note header (contract_address, nonce, storage_slot)\n // included in the note such that it becomes part of encrypted logs for later use.\n header: NoteHeader,\n}\n\nimpl TokenNote {\n pub fn new(amount: SafeU120, owner: AztecAddress) -> Self {\n Self {\n amount,\n owner,\n randomness: rand(),\n header: NoteHeader::empty(),\n }\n }\n\n pub fn serialize(self) -> [Field; TOKEN_NOTE_LEN] {\n [self.amount.value as Field, self.owner.address, self.randomness]\n }\n\n pub fn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> Self {\n Self {\n amount: SafeU120::new(preimage[0]),\n owner: AztecAddress::new(preimage[1]),\n randomness: preimage[2],\n header: NoteHeader::empty(),\n }\n }\n\n pub fn compute_note_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n self.amount.value as Field, \n self.owner.address as Field,\n self.randomness,\n ],0)\n }\n\n // docs:start:nullifier\n pub fn compute_nullifier(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(TokenNoteMethods, self);\n let secret = get_secret_key(self.owner.address);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n // docs:end:nullifier\n\n pub fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n // Broadcasts the note as an encrypted log on L1.\n pub fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n // We only bother inserting the note if non-empty to save funds on gas.\n if !self.amount.is_zero() {\n let encryption_pub_key = get_public_key(self.owner.address);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n encryption_pub_key,\n self.serialize(),\n );\n }\n }\n}\n\nfn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> TokenNote {\n TokenNote::deserialize(preimage)\n}\n\nfn serialize(note: TokenNote) -> [Field; TOKEN_NOTE_LEN] {\n note.serialize()\n}\n\nfn compute_note_hash(note: TokenNote) -> Field {\n note.compute_note_hash()\n}\n\nfn compute_nullifier(note: TokenNote) -> Field {\n note.compute_nullifier()\n}\n\nfn get_header(note: TokenNote) -> NoteHeader {\n note.header\n}\n\nfn set_header(note: &mut TokenNote, header: NoteHeader) {\n note.set_header(header)\n}\n\n// Broadcasts the note as an encrypted log on L1.\nfn broadcast(context: &mut PrivateContext, slot: Field, note: TokenNote) {\n note.broadcast(context, slot);\n}\n\nglobal TokenNoteMethods = NoteInterface {\n deserialize,\n serialize,\n compute_note_hash,\n compute_nullifier,\n get_header,\n set_header,\n broadcast,\n};", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/token_note.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/token_note.nr" }, "102": { "source": "use dep::aztec::types::type_serialization::TypeSerializationInterface;\nuse dep::safe_math::SafeU120;\n\nglobal SAFE_U120_SERIALIZED_LEN: Field = 1;\n\n// This is safe when reading from storage IF only correct safeu120 was written to storage\nfn deserializeU120(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 {\n SafeU120{value: fields[0] as u120}\n}\n\nfn serializeU120(value: SafeU120) -> [Field; SAFE_U120_SERIALIZED_LEN] {\n [value.value as Field]\n}\n\nglobal SafeU120SerializationMethods = TypeSerializationInterface {\n deserialize: deserializeU120,\n serialize: serializeU120,\n};", - "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/safe_u120_serialization.nr" + "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/safe_u120_serialization.nr" } } } diff --git a/yarn-project/boxes/token/src/tests/token.contract.test.ts b/yarn-project/boxes/token/src/tests/token.contract.test.ts index eda449643d3d..0f8b57e7ae54 100644 --- a/yarn-project/boxes/token/src/tests/token.contract.test.ts +++ b/yarn-project/boxes/token/src/tests/token.contract.test.ts @@ -15,6 +15,7 @@ import { } from '@aztec/aztec.js'; import { CompleteAddress } from '@aztec/circuits.js'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; +import { ExtendedNote } from '@aztec/types'; import { afterEach, beforeAll, expect, jest } from '@jest/globals'; // assumes sandbox is running locally, which this script does not trigger @@ -43,7 +44,8 @@ describe('e2e_token_contract', () => { const addPendingShieldNoteToPXE = async (accountIndex: number, amount: bigint, secretHash: Fr, txHash: TxHash) => { const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. const note = new Note([new Fr(amount), secretHash]); - await wallets[accountIndex].addNote(accounts[0].address, asset.address, storageSlot, note, txHash); + const extendedNote = new ExtendedNote(note, accounts[0].address, asset.address, storageSlot, txHash); + await wallets[accountIndex].addNote(extendedNote); }; beforeAll(async () => { diff --git a/yarn-project/cli/src/index.ts b/yarn-project/cli/src/index.ts index 0a7b22e79e3d..2dd5ae417391 100644 --- a/yarn-project/cli/src/index.ts +++ b/yarn-project/cli/src/index.ts @@ -21,7 +21,7 @@ import { DebugLogger, LogFn } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; import { fileURLToPath } from '@aztec/foundation/url'; import { compileContract, generateNoirInterface, generateTypescriptInterface } from '@aztec/noir-compiler/cli'; -import { CompleteAddress, ContractData, LogFilter } from '@aztec/types'; +import { CompleteAddress, ContractData, ExtendedNote, LogFilter } from '@aztec/types'; import { createSecp256k1PeerId } from '@libp2p/peer-id-factory'; import { Command, Option } from 'commander'; @@ -589,8 +589,9 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { .addOption(pxeOption) .action(async (address, contractAddress, storageSlot, txHash, options) => { const note = new Note(parseFields(options.note)); + const extendedNote = new ExtendedNote(note, address, contractAddress, storageSlot, txHash); const client = await createCompatibleClient(options.rpcUrl, debugLogger); - await client.addNote(address, contractAddress, storageSlot, note, txHash); + await client.addNote(extendedNote); }); // Helper for users to decode hex strings into structs if needed. diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index a4493366d670..8039eeb8fc3e 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -4,7 +4,7 @@ import { retryUntil } from '@aztec/foundation/retry'; import { toBigInt } from '@aztec/foundation/serialize'; import { ChildContract, TokenContract } from '@aztec/noir-contracts/types'; import { EthAddress, Fr, PXEService } from '@aztec/pxe'; -import { AztecNode, CompleteAddress, PXE, TxStatus } from '@aztec/types'; +import { AztecNode, CompleteAddress, ExtendedNote, PXE, TxStatus } from '@aztec/types'; import { jest } from '@jest/globals'; @@ -98,7 +98,8 @@ describe('e2e_2_pxes', () => { const storageSlot = new Fr(5); const note = new Note([new Fr(balance), secretHash]); - await pxe.addNote(recipient, contract.address, storageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, recipient, contract.address, storageSlot, receipt.txHash); + await pxe.addNote(extendedNote); expect((await contract.methods.redeem_shield(recipient, balance, secret).send().wait()).status).toEqual( TxStatus.MINED, diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index 4a80cfa1830c..968a8a4b7757 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -10,7 +10,7 @@ import { CompleteAddress, Fr, GrumpkinPrivateKey, GrumpkinScalar, getContractDep import { DebugLogger } from '@aztec/foundation/log'; import { EscrowContractArtifact } from '@aztec/noir-contracts/artifacts'; import { EscrowContract, TokenContract } from '@aztec/noir-contracts/types'; -import { PXE, PublicKey, TxStatus } from '@aztec/types'; +import { ExtendedNote, PXE, PublicKey, TxStatus } from '@aztec/types'; import { setup } from './fixtures/utils.js'; @@ -67,7 +67,8 @@ describe('e2e_escrow_contract', () => { expect(receipt.status).toEqual(TxStatus.MINED); const note = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(escrowContract.address, token.address, pendingShieldsStorageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, owner, token.address, pendingShieldsStorageSlot, receipt.txHash); + await pxe.addNote(extendedNote); expect( (await token.methods.redeem_shield(escrowContract.address, mintAmount, secret).send().wait()).status, @@ -113,7 +114,8 @@ describe('e2e_escrow_contract', () => { expect(receipt.status).toEqual(TxStatus.MINED); const note = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(owner, token.address, pendingShieldsStorageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, owner, token.address, pendingShieldsStorageSlot, receipt.txHash); + await pxe.addNote(extendedNote); expect((await token.methods.redeem_shield(owner, mintAmount, secret).send().wait()).status).toEqual(TxStatus.MINED); diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index a5e43cedb0b0..9fe151d549a7 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -9,7 +9,7 @@ import { import { CompleteAddress } from '@aztec/circuits.js'; import { DebugLogger } from '@aztec/foundation/log'; import { LendingContract, PriceFeedContract, TokenContract } from '@aztec/noir-contracts/types'; -import { Note, TxStatus } from '@aztec/types'; +import { ExtendedNote, Note, TxStatus } from '@aztec/types'; import { jest } from '@jest/globals'; @@ -122,7 +122,8 @@ describe('e2e_lending_contract', () => { const storageSlot = new Fr(5); const note = new Note([new Fr(mintAmount), secretHash]); const txHash = await b.getTxHash(); - await wallet.addNote(accounts[0].address, asset.address, storageSlot, note, txHash); + const extendedNote = new ExtendedNote(note, accounts[0].address, asset.address, storageSlot, txHash); + await wallet.addNote(extendedNote); await waitForSuccess(asset.methods.redeem_shield(lendingAccount.address, mintAmount, secret).send()); } diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index b50512897ac0..1222245d6ea4 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -10,7 +10,7 @@ import { import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { DebugLogger } from '@aztec/foundation/log'; import { TokenContract } from '@aztec/noir-contracts/types'; -import { AztecNode, CompleteAddress, PXE, TxStatus } from '@aztec/types'; +import { AztecNode, CompleteAddress, ExtendedNote, PXE, TxStatus } from '@aztec/types'; import { expectsNumOfEncryptedLogsInTheLastBlockToBe, setup } from './fixtures/utils.js'; @@ -76,7 +76,8 @@ describe('e2e_multiple_accounts_1_enc_key', () => { const storageSlot = new Fr(5); const note = new Note([new Fr(initialBalance), secretHash]); - await pxe.addNote(accounts[0], token.address, storageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, accounts[0], token.address, storageSlot, receipt.txHash); + await pxe.addNote(extendedNote); expect((await token.methods.redeem_shield(accounts[0], initialBalance, secret).send().wait()).status).toEqual( TxStatus.MINED, diff --git a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts index a4f94ba61bc3..0d1cb02d933a 100644 --- a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts +++ b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts @@ -12,6 +12,7 @@ import { } from '@aztec/aztec.js'; import { GrumpkinScalar } from '@aztec/circuits.js'; import { TokenContract } from '@aztec/noir-contracts/types'; +import { ExtendedNote } from '@aztec/types'; import { format } from 'util'; @@ -77,7 +78,7 @@ describe('e2e_sandbox_example', () => { // Add the newly created "pending shield" note to PXE const pendingShieldsStorageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. const note = new Note([new Fr(initialSupply), aliceSecretHash]); - await pxe.addNote(alice, contract.address, pendingShieldsStorageSlot, note, receipt.txHash); + await pxe.addNote(new ExtendedNote(note, alice, contract.address, pendingShieldsStorageSlot, receipt.txHash)); // Make the tokens spendable by redeeming them using the secret (converts the "pending shield note" created above // to a "token note") @@ -143,7 +144,9 @@ describe('e2e_sandbox_example', () => { const mintPrivateReceipt = await tokenContractBob.methods.mint_private(mintQuantity, bobSecretHash).send().wait(); const bobPendingShield = new Note([new Fr(mintQuantity), bobSecretHash]); - await pxe.addNote(bob, contract.address, pendingShieldsStorageSlot, bobPendingShield, mintPrivateReceipt.txHash); + await pxe.addNote( + new ExtendedNote(bobPendingShield, bob, contract.address, pendingShieldsStorageSlot, mintPrivateReceipt.txHash), + ); await tokenContractBob.methods.redeem_shield(bob, mintQuantity, bobSecret).send().wait(); diff --git a/yarn-project/end-to-end/src/e2e_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_token_contract.test.ts index a043e5545d00..4841032d3e6b 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract.test.ts @@ -9,6 +9,7 @@ import { import { CompleteAddress, Fr, FunctionSelector } from '@aztec/circuits.js'; import { DebugLogger } from '@aztec/foundation/log'; import { TokenContract } from '@aztec/noir-contracts/types'; +import { ExtendedNote } from '@aztec/types'; import { jest } from '@jest/globals'; @@ -32,7 +33,8 @@ describe('e2e_token_contract', () => { const addPendingShieldNoteToPXE = async (accountIndex: number, amount: bigint, secretHash: Fr, txHash: TxHash) => { const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. const note = new Note([new Fr(amount), secretHash]); - await wallets[accountIndex].addNote(accounts[0].address, asset.address, storageSlot, note, txHash); + const extendedNote = new ExtendedNote(note, accounts[0].address, asset.address, storageSlot, txHash); + await wallets[accountIndex].addNote(extendedNote); }; beforeAll(async () => { diff --git a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts index 06398b5cd497..c07023f7cb5d 100644 --- a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts +++ b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts @@ -13,6 +13,7 @@ import { } from '@aztec/aztec.js'; import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; import { TestContract, TokenContract } from '@aztec/noir-contracts/types'; +import { ExtendedNote } from '@aztec/types'; const { PXE_URL = 'http://localhost:8080', ETHEREUM_HOST = 'http://localhost:8545' } = process.env; @@ -49,7 +50,8 @@ describe('guides/dapp/testing', () => { const storageSlot = new Fr(5); const note = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(recipientAddress, token.address, storageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, recipientAddress, token.address, storageSlot, receipt.txHash); + await pxe.addNote(extendedNote); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); expect(await token.methods.balance_of_private(recipientAddress).view()).toEqual(20n); @@ -88,7 +90,8 @@ describe('guides/dapp/testing', () => { const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. const note = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(recipientAddress, token.address, storageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, recipientAddress, token.address, storageSlot, receipt.txHash); + await pxe.addNote(extendedNote); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); expect(await token.methods.balance_of_private(recipientAddress).view()).toEqual(20n); @@ -120,7 +123,8 @@ describe('guides/dapp/testing', () => { const storageSlot = new Fr(5); const note = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(recipientAddress, token.address, storageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, recipientAddress, token.address, storageSlot, receipt.txHash); + await pxe.addNote(extendedNote); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); expect(await token.methods.balance_of_private(recipientAddress).view()).toEqual(20n); @@ -173,7 +177,8 @@ describe('guides/dapp/testing', () => { const storageSlot = new Fr(5); const note = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(ownerAddress, token.address, storageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, ownerAddress, token.address, storageSlot, receipt.txHash); + await pxe.addNote(extendedNote); await token.methods.redeem_shield(ownerAddress, 100n, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index a5b3bc6b40c1..e87c7af4970e 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -10,7 +10,7 @@ import { import { GrumpkinPrivateKey, GrumpkinScalar } from '@aztec/circuits.js'; import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { SchnorrHardcodedAccountContractArtifact, TokenContract } from '@aztec/noir-contracts/types'; -import { AuthWitness } from '@aztec/types'; +import { AuthWitness, ExtendedNote } from '@aztec/types'; import { setup } from '../fixtures/utils.js'; @@ -72,7 +72,8 @@ describe('guides/writing_an_account_contract', () => { const storageSlot = new Fr(5); const note = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(address, token.address, storageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, address, token.address, storageSlot, receipt.txHash); + await pxe.addNote(extendedNote); await token.methods.redeem_shield({ address }, mintAmount, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/shared/browser.ts b/yarn-project/end-to-end/src/shared/browser.ts index 3287c03f61ad..d5fa2d1a3c6c 100644 --- a/yarn-project/end-to-end/src/shared/browser.ts +++ b/yarn-project/end-to-end/src/shared/browser.ts @@ -1,6 +1,7 @@ /* eslint-disable no-console */ import * as AztecJs from '@aztec/aztec.js'; import { TokenContractArtifact } from '@aztec/noir-contracts/artifacts'; +import { ExtendedNote } from '@aztec/types'; import { Server } from 'http'; import Koa from 'koa'; @@ -203,7 +204,14 @@ export const browserTestSuite = (setup: () => Server, pageLogger: AztecJs.DebugL const storageSlot = new Fr(5); const note = new Note([new Fr(initialBalance), secretHash]); - await pxe.addNote(ownerAddress, token.address, storageSlot, note, mintPrivateReceipt.txHash); + const extendedNote = new ExtendedNote( + note, + ownerAddress, + token.address, + storageSlot, + mintPrivateReceipt.txHash, + ); + await pxe.addNote(extendedNote); await token.methods.redeem_shield(ownerAddress, initialBalance, secret).send().wait(); diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 8da780de8b45..e24619285114 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -21,6 +21,7 @@ import { TokenPortalBytecode, } from '@aztec/l1-artifacts'; import { TokenBridgeContract, TokenContract } from '@aztec/noir-contracts/types'; +import { ExtendedNote } from '@aztec/types'; import { Account, Chain, HttpTransport, PublicClient, WalletClient, getContract, getFunctionSelector } from 'viem'; @@ -412,7 +413,8 @@ export class CrossChainTestHarness { this.logger('Adding note to PXE'); const storageSlot = new Fr(5); const note = new Note([new Fr(shieldAmount), secretHash]); - await this.pxeService.addNote(this.ownerAddress, this.l2Token.address, storageSlot, note, txHash); + const extendedNote = new ExtendedNote(note, this.ownerAddress, this.l2Token.address, storageSlot, txHash); + await this.pxeService.addNote(extendedNote); } async redeemShieldPrivatelyOnL2(shieldAmount: bigint, secret: Fr) { diff --git a/yarn-project/noir-private-kernel/src/types/private_kernel_init_types.ts b/yarn-project/noir-private-kernel/src/types/private_kernel_init_types.ts index a659bc69b0e9..bfd1dd2a301c 100644 --- a/yarn-project/noir-private-kernel/src/types/private_kernel_init_types.ts +++ b/yarn-project/noir-private-kernel/src/types/private_kernel_init_types.ts @@ -2,7 +2,7 @@ /* eslint-disable */ -export type FixedLengthArray = L extends 0 ? never[]: T[] & { length: L } +export type FixedLengthArray = L extends 0 ? never[] : T[] & { length: L }; export type Field = string; export type u32 = string; @@ -11,18 +11,15 @@ export interface Address { inner: Field; } - export interface Point { x: Field; y: Field; } - export interface EthAddress { inner: Field; } - export interface ContractDeploymentData { deployer_public_key: Point; constructor_vk_hash: Field; @@ -31,7 +28,6 @@ export interface ContractDeploymentData { portal_contract_address: EthAddress; } - export interface TxContext { is_fee_payment_tx: boolean; is_rebate_payment_tx: boolean; @@ -41,12 +37,10 @@ export interface TxContext { version: Field; } - export interface FunctionSelector { inner: u32; } - export interface FunctionData { selector: FunctionSelector; is_internal: boolean; @@ -54,7 +48,6 @@ export interface FunctionData { is_constructor: boolean; } - export interface TxRequest { origin: Address; args_hash: Field; @@ -62,12 +55,6 @@ export interface TxRequest { function_data: FunctionData; } - - - - - - export interface CallContext { msg_sender: Address; storage_contract_address: Address; @@ -78,7 +65,6 @@ export interface CallContext { is_contract_deployment: boolean; } - export interface Block { note_hash_tree_root: Field; nullifier_tree_root: Field; @@ -88,15 +74,12 @@ export interface Block { global_variables_hash: Field; } - export interface HistoricalBlockData { blocks_tree_root: Field; block: Block; private_kernel_vk_tree_root: Field; } - - export interface PrivateCircuitPublicInputs { call_context: CallContext; args_hash: Field; @@ -119,8 +102,6 @@ export interface PrivateCircuitPublicInputs { version: Field; } - - export interface CallStackItem { contract_address: Address; public_inputs: PrivateCircuitPublicInputs; @@ -128,32 +109,24 @@ export interface CallStackItem { function_data: FunctionData; } - export interface PrivateCallStackItem { inner: CallStackItem; } +export interface Proof {} -export interface Proof { -} - - -export interface VerificationKey { -} - +export interface VerificationKey {} export interface FunctionLeafMembershipWitness { leaf_index: Field; sibling_path: FixedLengthArray; } - export interface ContractLeafMembershipWitness { leaf_index: Field; sibling_path: FixedLengthArray; } - export interface ReadRequestMembershipWitness { leaf_index: Field; sibling_path: FixedLengthArray; @@ -161,8 +134,6 @@ export interface ReadRequestMembershipWitness { hint_to_commitment: Field; } - - export interface PrivateCallData { call_stack_item: PrivateCallStackItem; private_call_stack_preimages: FixedLengthArray; @@ -175,18 +146,12 @@ export interface PrivateCallData { acir_hash: Field; } - export interface PrivateKernelInputsInit { tx_request: TxRequest; private_call: PrivateCallData; } - -export interface AggregationObject { -} - - - +export interface AggregationObject {} export interface NewContractData { contract_address: Address; @@ -194,9 +159,6 @@ export interface NewContractData { function_tree_root: Field; } - - - export interface OptionallyRevealedData { call_stack_item_hash: Field; function_data: FunctionData; @@ -208,20 +170,17 @@ export interface OptionallyRevealedData { called_from_public_l2: boolean; } - export interface PublicDataUpdateRequest { leaf_index: Field; old_value: Field; new_value: Field; } - export interface PublicDataRead { leaf_index: Field; value: Field; } - export interface CombinedAccumulatedData { aggregation_object: AggregationObject; read_requests: FixedLengthArray; @@ -242,15 +201,11 @@ export interface CombinedAccumulatedData { public_data_reads: FixedLengthArray; } - - - export interface CombinedConstantData { block_data: HistoricalBlockData; tx_context: TxContext; } - export interface KernelCircuitPublicInputs { end: CombinedAccumulatedData; constants: CombinedConstantData; @@ -261,4 +216,4 @@ export type ReturnType = KernelCircuitPublicInputs; export interface InputType { input: PrivateKernelInputsInit; -} \ No newline at end of file +} diff --git a/yarn-project/noir-private-kernel/src/types/private_kernel_inner_types.ts b/yarn-project/noir-private-kernel/src/types/private_kernel_inner_types.ts index 1d7ffc5909f3..796a33f80f6f 100644 --- a/yarn-project/noir-private-kernel/src/types/private_kernel_inner_types.ts +++ b/yarn-project/noir-private-kernel/src/types/private_kernel_inner_types.ts @@ -2,37 +2,31 @@ /* eslint-disable */ -export type FixedLengthArray = L extends 0 ? never[]: T[] & { length: L } +export type FixedLengthArray = L extends 0 ? never[] : T[] & { length: L }; export type Field = string; export type u32 = string; -export interface AggregationObject { -} - +export interface AggregationObject {} export interface Address { inner: Field; } - export interface EthAddress { inner: Field; } - export interface NewContractData { contract_address: Address; portal_contract_address: EthAddress; function_tree_root: Field; } - export interface FunctionSelector { inner: u32; } - export interface FunctionData { selector: FunctionSelector; is_internal: boolean; @@ -40,8 +34,6 @@ export interface FunctionData { is_constructor: boolean; } - - export interface OptionallyRevealedData { call_stack_item_hash: Field; function_data: FunctionData; @@ -53,20 +45,17 @@ export interface OptionallyRevealedData { called_from_public_l2: boolean; } - export interface PublicDataUpdateRequest { leaf_index: Field; old_value: Field; new_value: Field; } - export interface PublicDataRead { leaf_index: Field; value: Field; } - export interface CombinedAccumulatedData { aggregation_object: AggregationObject; read_requests: FixedLengthArray; @@ -87,7 +76,6 @@ export interface CombinedAccumulatedData { public_data_reads: FixedLengthArray; } - export interface Block { note_hash_tree_root: Field; nullifier_tree_root: Field; @@ -97,21 +85,17 @@ export interface Block { global_variables_hash: Field; } - export interface HistoricalBlockData { blocks_tree_root: Field; block: Block; private_kernel_vk_tree_root: Field; } - export interface Point { x: Field; y: Field; } - - export interface ContractDeploymentData { deployer_public_key: Point; constructor_vk_hash: Field; @@ -120,7 +104,6 @@ export interface ContractDeploymentData { portal_contract_address: EthAddress; } - export interface TxContext { is_fee_payment_tx: boolean; is_rebate_payment_tx: boolean; @@ -130,27 +113,20 @@ export interface TxContext { version: Field; } - export interface CombinedConstantData { block_data: HistoricalBlockData; tx_context: TxContext; } - export interface KernelCircuitPublicInputs { end: CombinedAccumulatedData; constants: CombinedConstantData; is_private: boolean; } +export interface Proof {} -export interface Proof { -} - - -export interface VerificationKey { -} - +export interface VerificationKey {} export interface PreviousKernelData { public_inputs: KernelCircuitPublicInputs; @@ -160,12 +136,6 @@ export interface PreviousKernelData { vk_path: FixedLengthArray; } - - - - - - export interface CallContext { msg_sender: Address; storage_contract_address: Address; @@ -176,9 +146,6 @@ export interface CallContext { is_contract_deployment: boolean; } - - - export interface PrivateCircuitPublicInputs { call_context: CallContext; args_hash: Field; @@ -201,8 +168,6 @@ export interface PrivateCircuitPublicInputs { version: Field; } - - export interface CallStackItem { contract_address: Address; public_inputs: PrivateCircuitPublicInputs; @@ -210,26 +175,20 @@ export interface CallStackItem { function_data: FunctionData; } - export interface PrivateCallStackItem { inner: CallStackItem; } - - - export interface FunctionLeafMembershipWitness { leaf_index: Field; sibling_path: FixedLengthArray; } - export interface ContractLeafMembershipWitness { leaf_index: Field; sibling_path: FixedLengthArray; } - export interface ReadRequestMembershipWitness { leaf_index: Field; sibling_path: FixedLengthArray; @@ -237,8 +196,6 @@ export interface ReadRequestMembershipWitness { hint_to_commitment: Field; } - - export interface PrivateCallData { call_stack_item: PrivateCallStackItem; private_call_stack_preimages: FixedLengthArray; @@ -251,15 +208,13 @@ export interface PrivateCallData { acir_hash: Field; } - export interface PrivateKernelInputsInner { previous_kernel: PreviousKernelData; private_call: PrivateCallData; } - export type ReturnType = KernelCircuitPublicInputs; export interface InputType { input: PrivateKernelInputsInner; -} \ No newline at end of file +} diff --git a/yarn-project/noir-private-kernel/src/types/private_kernel_ordering_types.ts b/yarn-project/noir-private-kernel/src/types/private_kernel_ordering_types.ts index 81ab30ace94c..460b6e89e4c6 100644 --- a/yarn-project/noir-private-kernel/src/types/private_kernel_ordering_types.ts +++ b/yarn-project/noir-private-kernel/src/types/private_kernel_ordering_types.ts @@ -2,37 +2,31 @@ /* eslint-disable */ -export type FixedLengthArray = L extends 0 ? never[]: T[] & { length: L } +export type FixedLengthArray = L extends 0 ? never[] : T[] & { length: L }; export type Field = string; export type u32 = string; -export interface AggregationObject { -} - +export interface AggregationObject {} export interface Address { inner: Field; } - export interface EthAddress { inner: Field; } - export interface NewContractData { contract_address: Address; portal_contract_address: EthAddress; function_tree_root: Field; } - export interface FunctionSelector { inner: u32; } - export interface FunctionData { selector: FunctionSelector; is_internal: boolean; @@ -40,8 +34,6 @@ export interface FunctionData { is_constructor: boolean; } - - export interface OptionallyRevealedData { call_stack_item_hash: Field; function_data: FunctionData; @@ -53,20 +45,17 @@ export interface OptionallyRevealedData { called_from_public_l2: boolean; } - export interface PublicDataUpdateRequest { leaf_index: Field; old_value: Field; new_value: Field; } - export interface PublicDataRead { leaf_index: Field; value: Field; } - export interface CombinedAccumulatedData { aggregation_object: AggregationObject; read_requests: FixedLengthArray; @@ -87,7 +76,6 @@ export interface CombinedAccumulatedData { public_data_reads: FixedLengthArray; } - export interface Block { note_hash_tree_root: Field; nullifier_tree_root: Field; @@ -97,21 +85,17 @@ export interface Block { global_variables_hash: Field; } - export interface HistoricalBlockData { blocks_tree_root: Field; block: Block; private_kernel_vk_tree_root: Field; } - export interface Point { x: Field; y: Field; } - - export interface ContractDeploymentData { deployer_public_key: Point; constructor_vk_hash: Field; @@ -120,7 +104,6 @@ export interface ContractDeploymentData { portal_contract_address: EthAddress; } - export interface TxContext { is_fee_payment_tx: boolean; is_rebate_payment_tx: boolean; @@ -130,27 +113,20 @@ export interface TxContext { version: Field; } - export interface CombinedConstantData { block_data: HistoricalBlockData; tx_context: TxContext; } - export interface KernelCircuitPublicInputs { end: CombinedAccumulatedData; constants: CombinedConstantData; is_private: boolean; } +export interface Proof {} -export interface Proof { -} - - -export interface VerificationKey { -} - +export interface VerificationKey {} export interface PreviousKernelData { public_inputs: KernelCircuitPublicInputs; @@ -160,15 +136,12 @@ export interface PreviousKernelData { vk_path: FixedLengthArray; } - export interface PrivateKernelInputsOrdering { previous_kernel: PreviousKernelData; read_commitment_hints: FixedLengthArray; nullifier_commitment_hints: FixedLengthArray; } - - export interface FinalAccumulatedData { aggregation_object: AggregationObject; new_commitments: FixedLengthArray; @@ -185,8 +158,6 @@ export interface FinalAccumulatedData { optionally_revealed_data: FixedLengthArray; } - - export interface KernelCircuitPublicInputsFinal { end: FinalAccumulatedData; constants: CombinedConstantData; @@ -197,4 +168,4 @@ export type ReturnType = KernelCircuitPublicInputsFinal; export interface InputType { input: PrivateKernelInputsOrdering; -} \ No newline at end of file +} diff --git a/yarn-project/pxe/src/database/database.ts b/yarn-project/pxe/src/database/database.ts index 3280c1748e47..a03cdfa1bc4b 100644 --- a/yarn-project/pxe/src/database/database.ts +++ b/yarn-project/pxe/src/database/database.ts @@ -50,10 +50,10 @@ export interface Database extends ContractDatabase { * Remove nullified notes associated with the given account and nullifiers. * * @param nullifiers - An array of Fr instances representing nullifiers to be matched. - * @param account - A PublicKey instance representing the account for which the records are being removed. + * @param account - An account for which the records are being removed. * @returns Removed notes. */ - removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise; + removeNullifiedNotes(nullifiers: Fr[], account: AztecAddress): Promise; /** * Retrieve the stored Merkle tree roots from the database. diff --git a/yarn-project/pxe/src/database/memory_db.test.ts b/yarn-project/pxe/src/database/memory_db.test.ts index a8cb6cc4c202..1eb0a2c42168 100644 --- a/yarn-project/pxe/src/database/memory_db.test.ts +++ b/yarn-project/pxe/src/database/memory_db.test.ts @@ -1,7 +1,7 @@ import { AztecAddress, Fr } from '@aztec/circuits.js'; -import { ExtendedNote, randomExtendedNote } from '@aztec/types'; import { MemoryDB } from './memory_db.js'; +import { randomNoteDao } from './note_dao.test.js'; describe('Memory DB', () => { let db: MemoryDB; @@ -14,17 +14,10 @@ describe('Memory DB', () => { const contractAddress = AztecAddress.random(); const storageSlot = Fr.random(); - const createNote = (attributes: Partial = {}, sameStorage = true) => - randomExtendedNote({ - ...attributes, - contractAddress: sameStorage ? contractAddress : AztecAddress.random(), - storageSlot: sameStorage ? storageSlot : Fr.random(), - }); - const createNotes = (numberOfNotes: number, sameStorage = true) => Array(numberOfNotes) .fill(0) - .map(() => createNote({}, sameStorage)); + .map(() => randomNoteDao({ storageSlot: sameStorage ? storageSlot : Fr.random() })); it('should add and get notes', async () => { const notes = createNotes(3, false); @@ -34,8 +27,8 @@ describe('Memory DB', () => { for (let i = 0; i < notes.length; ++i) { const result = await db.getNotes({ - contractAddress: notes[i].contractAddress, - storageSlot: notes[i].storageSlot, + contractAddress: notes[i].extendedNote.contractAddress, + storageSlot: notes[i].extendedNote.storageSlot, }); expect(result).toEqual([notes[i]]); } @@ -43,12 +36,12 @@ describe('Memory DB', () => { it('should batch add notes', async () => { const notes = createNotes(3, false); - await db.addNote(notes); + await db.addNotes(notes); for (let i = 0; i < notes.length; ++i) { const result = await db.getNotes({ - contractAddress: notes[i].contractAddress, - storageSlot: notes[i].storageSlot, + contractAddress: notes[i].extendedNote.contractAddress, + storageSlot: notes[i].extendedNote.storageSlot, }); expect(result).toEqual([notes[i]]); } @@ -56,7 +49,7 @@ describe('Memory DB', () => { it('should get all notes with the same contract storage slot', async () => { const notes = createNotes(3); - await db.addNote(notes); + await db.addNotes(notes); const result = await db.getNotes({ contractAddress, storageSlot }); expect(result.length).toBe(notes.length); diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 86b5076dbdbe..743a4ff5c994 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -2,7 +2,7 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; +import { MerkleTreeId, NoteFilter } from '@aztec/types'; import { MemoryContractDatabase } from '../contract_database/index.js'; import { Database } from './database.js'; @@ -54,31 +54,23 @@ export class MemoryDB extends MemoryContractDatabase implements Database { return Promise.resolve(); } - public async getNotes(filter: NoteFilter): Promise { - let ownerPublicKey: PublicKey | undefined; - if (filter.owner !== undefined) { - const ownerCompleteAddress = await this.getCompleteAddress(filter.owner); - if (ownerCompleteAddress === undefined) { - throw new Error(`Owner ${filter.owner.toString()} not found in memory database`); - } - ownerPublicKey = ownerCompleteAddress.publicKey; - } - - return this.notesTable.filter( - note => - (filter.contractAddress == undefined || note.contractAddress.equals(filter.contractAddress)) && - (filter.txHash == undefined || note.txHash.equals(filter.txHash)) && - (filter.storageSlot == undefined || note.storageSlot.equals(filter.storageSlot!)) && - (ownerPublicKey == undefined || note.publicKey.equals(ownerPublicKey!)), + public getNotes(filter: NoteFilter): Promise { + const notes = this.notesTable.filter( + noteDao => + (filter.contractAddress == undefined || noteDao.extendedNote.contractAddress.equals(filter.contractAddress)) && + (filter.txHash == undefined || noteDao.extendedNote.txHash.equals(filter.txHash)) && + (filter.storageSlot == undefined || noteDao.extendedNote.storageSlot.equals(filter.storageSlot!)) && + (filter.owner == undefined || noteDao.extendedNote.owner.equals(filter.owner!)), ); + return Promise.resolve(notes); } - public removeNullifiedNotes(nullifiers: Fr[], account: PublicKey) { + public removeNullifiedNotes(nullifiers: Fr[], account: AztecAddress) { const nullifierSet = new Set(nullifiers.map(nullifier => nullifier.toString())); const [remaining, removed] = this.notesTable.reduce( (acc: [NoteDao[], NoteDao[]], note) => { const nullifier = note.siloedNullifier.toString(); - if (note.publicKey.equals(account) && nullifierSet.has(nullifier)) { + if (note.extendedNote.owner.equals(account) && nullifierSet.has(nullifier)) { acc[1].push(note); } else { acc[0].push(note); @@ -156,7 +148,7 @@ export class MemoryDB extends MemoryContractDatabase implements Database { } public estimateSize() { - const notesSize = this.notesTable.reduce((sum, note) => sum + note.getSize(note), 0); + const notesSize = this.notesTable.reduce((sum, note) => sum + note.getSize(), 0); const treeRootsSize = this.treeRoots ? Object.entries(this.treeRoots).length * Fr.SIZE_IN_BYTES : 0; const authWits = Object.entries(this.authWitnesses); const authWitsSize = authWits.reduce((sum, [key, value]) => sum + key.length + value.length * Fr.SIZE_IN_BYTES, 0); diff --git a/yarn-project/pxe/src/database/note_dao.test.ts b/yarn-project/pxe/src/database/note_dao.test.ts index 7550abe5486e..fe981f814640 100644 --- a/yarn-project/pxe/src/database/note_dao.test.ts +++ b/yarn-project/pxe/src/database/note_dao.test.ts @@ -1,17 +1,16 @@ -import { Fr, Point } from '@aztec/circuits.js'; -import { randomExtendedNote } from '@aztec/types'; +import { Fr } from '@aztec/circuits.js'; +import { ExtendedNote, randomExtendedNote } from '@aztec/types'; import { NoteDao } from './note_dao.js'; -const randomNoteDao = () => { - const extendedNote = randomExtendedNote(); +export const randomNoteDao = (extendedNoteAttributes: Partial = {}) => { + const extendedNote = randomExtendedNote(extendedNoteAttributes); const nonce = Fr.random(); const innerNoteHash = Fr.random(); const siloedNullifier = Fr.random(); const index = BigInt(0); - const publicKey = Point.random(); - return new NoteDao(extendedNote, nonce, innerNoteHash, siloedNullifier, index, publicKey); + return new NoteDao(extendedNote, nonce, innerNoteHash, siloedNullifier, index); }; describe('Note DAO', () => { diff --git a/yarn-project/pxe/src/database/note_dao.ts b/yarn-project/pxe/src/database/note_dao.ts index 8f8d9204cf4c..cb238f610a10 100644 --- a/yarn-project/pxe/src/database/note_dao.ts +++ b/yarn-project/pxe/src/database/note_dao.ts @@ -1,4 +1,4 @@ -import { Fr, Point, PublicKey } from '@aztec/circuits.js'; +import { Fr } from '@aztec/circuits.js'; import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; import { BufferReader, ExtendedNote } from '@aztec/types'; @@ -20,8 +20,6 @@ export class NoteDao { public siloedNullifier: Fr, /** The location of the relevant note in the note hash tree. */ public index: bigint, - /** The public key that was used to encrypt the data. */ - public publicKey: PublicKey, ) {} toBuffer(): Buffer { @@ -31,7 +29,6 @@ export class NoteDao { this.innerNoteHash.toBuffer(), this.siloedNullifier.toBuffer(), toBufferBE(this.index, 32), - this.publicKey.toBuffer(), ]); } static fromBuffer(buffer: Buffer | BufferReader) { @@ -42,16 +39,8 @@ export class NoteDao { const innerNoteHash = Fr.fromBuffer(reader); const siloedNullifier = Fr.fromBuffer(reader); const index = toBigIntBE(reader.readBytes(32)); - const publicKey = Point.fromBuffer(reader); - return new this( - extendedNote, - nonce, - innerNoteHash, - siloedNullifier, - index, - publicKey, - ); + return new this(extendedNote, nonce, innerNoteHash, siloedNullifier, index); } toString() { @@ -64,14 +53,13 @@ export class NoteDao { } /** - * Returns the size in bytes of the extended note. + * Returns the size in bytes of the Note Dao. * @returns - Its size in bytes. */ public getSize() { + // TODO: update // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer const indexSize = Math.ceil(Math.log2(Number(this.index))); - return ( - this.extendedNote.note.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize + Point.SIZE_IN_BYTES - ); + return this.extendedNote.note.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize; } } 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 d9582d82cd62..63e47b5dfd74 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -1,5 +1,5 @@ import { AcirSimulator } from '@aztec/acir-simulator'; -import { CircuitsWasm, Fr, MAX_NEW_COMMITMENTS_PER_TX } from '@aztec/circuits.js'; +import { CircuitsWasm, CompleteAddress, Fr, MAX_NEW_COMMITMENTS_PER_TX } from '@aztec/circuits.js'; import { Grumpkin, pedersenHashInputs } from '@aztec/circuits.js/barretenberg'; import { Point } from '@aztec/foundation/fields'; import { ConstantKeyPair } from '@aztec/key-store'; @@ -22,6 +22,7 @@ import { jest } from '@jest/globals'; import { MockProxy, mock } from 'jest-mock-extended'; import { Database, MemoryDB } from '../database/index.js'; +import { NoteDao } from '../database/note_dao.js'; import { NoteProcessor } from './note_processor.js'; const TXS_PER_BLOCK = 4; @@ -31,9 +32,10 @@ describe('Note Processor', () => { let grumpkin: Grumpkin; let database: Database; let aztecNode: ReturnType>; - let addExtendedNotesSpy: any; + let addNotesSpy: any; let noteProcessor: NoteProcessor; let owner: KeyPair; + let ownerAddress: CompleteAddress; let keyStore: MockProxy; let simulator: MockProxy; const firstBlockNum = 123; @@ -119,24 +121,18 @@ describe('Note Processor', () => { wasm = await CircuitsWasm.get(); grumpkin = new Grumpkin(wasm); owner = ConstantKeyPair.random(grumpkin); + ownerAddress = await CompleteAddress.fromPrivateKeyAndPartialAddress(await owner.getPrivateKey(), Fr.random()); }); beforeEach(() => { database = new MemoryDB(); - addExtendedNotesSpy = jest.spyOn(database, 'addExtendedNotes'); + addNotesSpy = jest.spyOn(database, 'addNotes'); aztecNode = mock(); keyStore = mock(); simulator = mock(); keyStore.getAccountPrivateKey.mockResolvedValue(owner.getPrivateKey()); - noteProcessor = new NoteProcessor( - owner.getPublicKey(), - keyStore, - database, - aztecNode, - INITIAL_L2_BLOCK_NUM, - simulator, - ); + noteProcessor = new NoteProcessor(ownerAddress, keyStore, database, aztecNode, INITIAL_L2_BLOCK_NUM, simulator); simulator.computeNoteHashAndNullifier.mockImplementation((...args) => Promise.resolve({ @@ -149,15 +145,15 @@ describe('Note Processor', () => { }); afterEach(() => { - addExtendedNotesSpy.mockReset(); + addNotesSpy.mockReset(); }); it('should store a note that belongs to us', async () => { const { blockContexts, encryptedLogsArr, ownedL1NotePayloads } = mockData([[2]]); await noteProcessor.process(blockContexts, encryptedLogsArr); - expect(addExtendedNotesSpy).toHaveBeenCalledTimes(1); - expect(addExtendedNotesSpy).toHaveBeenCalledWith([ + expect(addNotesSpy).toHaveBeenCalledTimes(1); + expect(addNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ ...ownedL1NotePayloads[0], index: BigInt(firstBlockDataStartIndex + 2), @@ -177,8 +173,8 @@ describe('Note Processor', () => { ); await noteProcessor.process(blockContexts, encryptedLogsArr); - expect(addExtendedNotesSpy).toHaveBeenCalledTimes(1); - expect(addExtendedNotesSpy).toHaveBeenCalledWith([ + expect(addNotesSpy).toHaveBeenCalledTimes(1); + expect(addNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ ...ownedL1NotePayloads[0], // Index 1 log in the 2nd tx. @@ -202,7 +198,7 @@ describe('Note Processor', () => { await noteProcessor.process(blockContexts, encryptedLogsArr); }); - it('should be able to recover two note payloads with containing the same note', async () => { + it('should be able to recover two note payloads containing the same note', async () => { const note = L1NotePayload.random(); const note2 = L1NotePayload.random(); // All note payloads except one have the same contract address, storage slot, and the actual note. @@ -210,8 +206,8 @@ describe('Note Processor', () => { const { blockContexts, encryptedLogsArr, ownedL1NotePayloads } = mockData([[0, 2], [], [0, 1, 3]], 0, 0, notes); await noteProcessor.process(blockContexts, encryptedLogsArr); - const addedInfos: ExtendedNote[] = addExtendedNotesSpy.mock.calls[0][0]; - expect(addedInfos).toEqual([ + const addedNoteDaos: NoteDao[] = addNotesSpy.mock.calls[0][0]; + expect(addedNoteDaos).toEqual([ expect.objectContaining({ ...ownedL1NotePayloads[0] }), expect.objectContaining({ ...ownedL1NotePayloads[1] }), expect.objectContaining({ ...ownedL1NotePayloads[2] }), @@ -225,7 +221,7 @@ describe('Note Processor', () => { // Check that every note has a different nonce. const nonceSet = new Set(); - addedInfos.forEach(info => nonceSet.add(info.nonce.value)); + addedNoteDaos.forEach(info => nonceSet.add(info.nonce.value)); expect(nonceSet.size).toBe(notes.length); }); }); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 1cea76bc7a3f..69b548614727 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -1,21 +1,19 @@ -import { CircuitsWasm, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX } from '@aztec/circuits.js'; +import { + CircuitsWasm, + CompleteAddress, + MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, +} from '@aztec/circuits.js'; import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/abis'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; -import { - AztecNode, - ExtendedNote, - KeyStore, - L1NotePayload, - L2BlockContext, - L2BlockL2Logs, - PublicKey, -} from '@aztec/types'; +import { AztecNode, ExtendedNote, KeyStore, L1NotePayload, L2BlockContext, L2BlockL2Logs } from '@aztec/types'; import { NoteProcessorStats } from '@aztec/types/stats'; import { Database } from '../database/index.js'; +import { NoteDao } from '../database/note_dao.js'; import { getAcirSimulator } from '../simulator/index.js'; /** @@ -27,9 +25,9 @@ interface ProcessedData { */ blockContext: L2BlockContext; /** - * A processed extended notes. + * DAOs of processed notes. */ - extendedNotes: ExtendedNote[]; + noteDaos: NoteDao[]; } /** @@ -50,7 +48,7 @@ export class NoteProcessor { /** * The public counterpart to the private key to be used in note decryption. */ - public readonly publicKey: PublicKey, + public readonly account: CompleteAddress, private keyStore: KeyStore, private db: Database, private node: AztecNode, @@ -113,8 +111,8 @@ export class NoteProcessor { // We are using set for `userPertainingTxIndices` to avoid duplicates. This would happen in case there were // multiple encrypted logs in a tx pertaining to a user. - const extendedNotes: ExtendedNote[] = []; - const privateKey = await this.keyStore.getAccountPrivateKey(this.publicKey); + const noteDaos: NoteDao[] = []; + const privateKey = await this.keyStore.getAccountPrivateKey(this.account.publicKey); // Iterate over all the encrypted logs and try decrypting them. If successful, store the note. for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) { @@ -147,17 +145,19 @@ export class NoteProcessor { ); const index = BigInt(dataStartIndexForTx + commitmentIndex); excludedIndices.add(commitmentIndex); - extendedNotes.push( - new ExtendedNote( - payload.note, - payload.contractAddress, - blockContext.getTxHash(indexOfTxInABlock), + noteDaos.push( + new NoteDao( + new ExtendedNote( + payload.note, + this.account.address, + payload.contractAddress, + payload.storageSlot, + blockContext.getTxHash(indexOfTxInABlock), + ), nonce, - payload.storageSlot, innerNoteHash, siloedNullifier, index, - this.publicKey, ), ); this.stats.decrypted++; @@ -172,7 +172,7 @@ export class NoteProcessor { blocksAndNotes.push({ blockContext: l2BlockContexts[blockIndex], - extendedNotes, + noteDaos, }); } @@ -262,28 +262,28 @@ https://github.com/AztecProtocol/aztec-packages/issues/1641`; * transaction auxiliary data from the database. This function keeps track of new nullifiers * and ensures all other transactions are updated with newly settled block information. * - * @param blocksAndNotes - Array of objects containing L2BlockContexts, user-pertaining transaction indices, and ExtendedNotes. + * @param blocksAndNotes - Array of objects containing L2BlockContexts, user-pertaining transaction indices, and NoteDaos. */ private async processBlocksAndNotes(blocksAndNotes: ProcessedData[]) { - const extendedNotesBatch = blocksAndNotes.flatMap(b => b.extendedNotes); - if (extendedNotesBatch.length) { - await this.db.addExtendedNotes(extendedNotesBatch); - extendedNotesBatch.forEach(note => { + const noteDaos = blocksAndNotes.flatMap(b => b.noteDaos); + if (noteDaos.length) { + await this.db.addNotes(noteDaos); + noteDaos.forEach(noteDao => { this.log( - `Added note for contract ${note.contractAddress} at slot ${ - note.storageSlot - } with nullifier ${note.siloedNullifier.toString()}`, + `Added note for contract ${noteDao.extendedNote.contractAddress} at slot ${ + noteDao.extendedNote.storageSlot + } with nullifier ${noteDao.siloedNullifier.toString()}`, ); }); } const newNullifiers: Fr[] = blocksAndNotes.flatMap(b => b.blockContext.block.newNullifiers); - const removedNotes = await this.db.removeNullifiedNotes(newNullifiers, this.publicKey); - removedNotes.forEach(note => { + const removedNotes = await this.db.removeNullifiedNotes(newNullifiers, this.account.address); + removedNotes.forEach(noteDao => { this.log( - `Removed note for contract ${note.contractAddress} at slot ${ - note.storageSlot - } with nullifier ${note.siloedNullifier.toString()}`, + `Removed note for contract ${noteDao.extendedNote.contractAddress} at slot ${ + noteDao.extendedNote.storageSlot + } with nullifier ${noteDao.siloedNullifier.toString()}`, ); }); } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index a2f24d82d94f..989377c746f0 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -57,6 +57,7 @@ import { import { PXEServiceConfig, getPackageInfo } from '../config/index.js'; import { ContractDataOracle } from '../contract_data_oracle/index.js'; import { Database } from '../database/index.js'; +import { NoteDao } from '../database/note_dao.js'; import { KernelOracle } from '../kernel_oracle/index.js'; import { KernelProver } from '../kernel_prover/kernel_prover.js'; import { getAcirSimulator } from '../simulator/index.js'; @@ -124,8 +125,7 @@ export class PXEService implements PXE { const completeAddress = await CompleteAddress.fromPrivateKeyAndPartialAddress(privKey, partialAddress); const wasAdded = await this.db.addCompleteAddress(completeAddress); if (wasAdded) { - const pubKey = this.keyStore.addAccount(privKey); - this.synchronizer.addAccount(pubKey, this.keyStore, this.config.l2StartingBlock); + this.synchronizer.addAccount(completeAddress, this.keyStore, this.config.l2StartingBlock); this.log.info(`Registered account ${completeAddress.address.toString()}`); this.log.debug(`Registered account\n ${completeAddress.toReadableString()}`); } else { @@ -195,31 +195,23 @@ export class PXEService implements PXE { } public async getNotes(filter: NoteFilter): Promise { - return await this.db.getNotes(filter); + const noteDaos = await this.db.getNotes(filter); + return noteDaos.map(dao => dao.extendedNote); } - public async addNote( - account: AztecAddress, - contractAddress: AztecAddress, - storageSlot: Fr, - note: Note, - txHash: TxHash, - nonce?: Fr, - ) { - const { publicKey } = (await this.db.getCompleteAddress(account)) ?? {}; - if (!publicKey) { + public async addNote(note: ExtendedNote) { + const account = (await this.db.getCompleteAddress(note.owner)) ?? {}; + if (!account) { throw new Error('Unknown account.'); } + const [nonce] = await this.getNoteNonces(note); if (!nonce) { - [nonce] = await this.getNoteNonces(contractAddress, storageSlot, note, txHash); - } - if (!nonce) { - throw new Error(`Cannot find the note in tx: ${txHash}.`); + throw new Error(`Cannot find the note in tx: ${note.txHash}.`); } const { innerNoteHash, siloedNoteHash, uniqueSiloedNoteHash, innerNullifier } = - await this.simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note); + await this.simulator.computeNoteHashAndNullifier(note.contractAddress, nonce, note.storageSlot, note.note); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) // This can always be `uniqueSiloedNoteHash` once notes added from public also include nonces. @@ -230,36 +222,19 @@ export class PXEService implements PXE { } const wasm = await CircuitsWasm.get(); - const siloedNullifier = siloNullifier(wasm, contractAddress, innerNullifier!); + const siloedNullifier = siloNullifier(wasm, note.contractAddress, innerNullifier!); const nullifierIndex = await this.node.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, siloedNullifier.toBuffer()); if (nullifierIndex !== undefined) { throw new Error('The note has been destroyed.'); } - await this.db.addNote( - new ExtendedNote( - note, - contractAddress, - txHash, - nonce, - storageSlot, - innerNoteHash, - siloedNullifier, - index, - publicKey, - ), - ); + await this.db.addNote(new NoteDao(note, nonce, innerNoteHash, siloedNullifier, index)); } - public async getNoteNonces( - contractAddress: AztecAddress, - storageSlot: Fr, - note: Note, - txHash: TxHash, - ): Promise { - const tx = await this.node.getTx(txHash); + public async getNoteNonces(note: ExtendedNote): Promise { + const tx = await this.node.getTx(note.txHash); if (!tx) { - throw new Error(`Unknown tx: ${txHash}`); + throw new Error(`Unknown tx: ${note.txHash}`); } const wasm = await CircuitsWasm.get(); @@ -273,10 +248,10 @@ export class PXEService implements PXE { const nonce = computeCommitmentNonce(wasm, firstNullifier, i); const { siloedNoteHash, uniqueSiloedNoteHash } = await this.simulator.computeNoteHashAndNullifier( - contractAddress, + note.contractAddress, nonce, - storageSlot, - note, + note.storageSlot, + note.note, ); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) // Remove this once notes added from public also include nonces. diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index f4f8f2573596..6ba446df2bf2 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -46,11 +46,11 @@ export class SimulatorOracle implements DBOracle { async getNotes(contractAddress: AztecAddress, storageSlot: Fr) { const noteDaos = await this.db.getNotes({ contractAddress, storageSlot }); - return noteDaos.map(({ contractAddress, storageSlot, nonce, note, innerNoteHash, siloedNullifier, index }) => ({ - contractAddress, - storageSlot, + return noteDaos.map(({ extendedNote, nonce, innerNoteHash, siloedNullifier, index }) => ({ + contractAddress: extendedNote.contractAddress, + storageSlot: extendedNote.storageSlot, nonce, - note, + note: extendedNote.note, innerNoteHash, siloedNullifier, // PXE can use this index to get full MembershipWitness diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.test.ts b/yarn-project/pxe/src/synchronizer/synchronizer.test.ts index 29833507e2b4..ffd5037413d6 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.test.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.test.ts @@ -109,7 +109,7 @@ describe('Synchronizer', () => { await database.addCompleteAddress(completeAddress); // Add the account which will add the note processor to the synchronizer - synchronizer.addAccount(completeAddress.publicKey, keyStore, INITIAL_L2_BLOCK_NUM); + synchronizer.addAccount(completeAddress, keyStore, INITIAL_L2_BLOCK_NUM); await synchronizer.workNoteProcessorCatchUp(); diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.ts b/yarn-project/pxe/src/synchronizer/synchronizer.ts index 56a42dc377f2..2e08c3c5ac1f 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.ts @@ -1,4 +1,4 @@ -import { AztecAddress, CircuitsWasm, Fr, HistoricBlockData, PublicKey } from '@aztec/circuits.js'; +import { AztecAddress, CircuitsWasm, CompleteAddress, Fr, HistoricBlockData } from '@aztec/circuits.js'; import { computeGlobalsHash } from '@aztec/circuits.js/abis'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { InterruptibleSleep } from '@aztec/foundation/sleep'; @@ -179,9 +179,9 @@ export class Synchronizer { if (noteProcessor.status.syncedToBlock === this.synchedToBlock) { // Note processor caught up, move it to `noteProcessors` from `noteProcessorsToCatchUp`. - this.log(`Note processor for ${noteProcessor.publicKey.toString()} has caught up`, { + this.log(`Note processor for account ${noteProcessor.account.address.toString()} has caught up`, { eventName: 'note-processor-caught-up', - publicKey: noteProcessor.publicKey.toString(), + publicKey: noteProcessor.account.publicKey.toString(), duration: noteProcessor.timer.ms(), dbSize: this.db.estimateSize(), ...noteProcessor.stats, @@ -234,16 +234,16 @@ export class Synchronizer { * Creates a NoteProcessor instance for the account and pushes it into the noteProcessors array. * The method resolves immediately after pushing the new note processor. * - * @param publicKey - The public key for the account. + * @param account - A complete address of the account toa dd. * @param keyStore - The key store. * @param startingBlock - The block where to start scanning for notes for this accounts. * @returns A promise that resolves once the account is added to the Synchronizer. */ - public addAccount(publicKey: PublicKey, keyStore: KeyStore, startingBlock: number) { - const processor = this.noteProcessors.find(x => x.publicKey.equals(publicKey)); + public addAccount(account: CompleteAddress, keyStore: KeyStore, startingBlock: number) { + const processor = this.noteProcessors.find(x => x.account.equals(account)); if (processor) return; - this.noteProcessorsToCatchUp.push(new NoteProcessor(publicKey, keyStore, this.db, this.node, startingBlock)); + this.noteProcessorsToCatchUp.push(new NoteProcessor(account, keyStore, this.db, this.node, startingBlock)); } /** @@ -255,15 +255,9 @@ export class Synchronizer { * @throws If checking a sync status of account which is not registered. */ public async isAccountStateSynchronized(account: AztecAddress) { - const completeAddress = await this.db.getCompleteAddress(account); - if (!completeAddress) { - throw new Error(`Checking if account is synched is not possible for ${account} because it is not registered.`); - } - const processor = this.noteProcessors.find(x => x.publicKey.equals(completeAddress.publicKey)); + const processor = this.noteProcessors.find(x => x.account.address.equals(account)); if (!processor) { - throw new Error( - `Checking if account is synched is not possible for ${account} because it is only registered as a recipient.`, - ); + throw new Error(`Account ${account} not found.`); } return await processor.isSynchronized(); } @@ -286,7 +280,7 @@ export class Synchronizer { public getSyncStatus() { return { blocks: this.synchedToBlock, - notes: Object.fromEntries(this.noteProcessors.map(n => [n.publicKey.toString(), n.status.syncedToBlock])), + notes: Object.fromEntries(this.noteProcessors.map(n => [n.account.publicKey.toString(), n.status.syncedToBlock])), }; } } diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index d0c698bf1a14..31d47ab2cd62 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -168,33 +168,19 @@ export interface PXE { getNotes(filter: NoteFilter): Promise; /** - * Adds a note to the database. Throw if the note hash of the note doesn't exist in the tree. - * @param account - The account the note is associated with. - * @param contract - The contract address of the note. - * @param storageSlot - The storage slot of the note. + * Adds a note to the database. + * @throws If the note hash of the note doesn't exist in the tree. * @param note - The note to add. - * @param txHash - The tx hash of the tx containing the note. - * @param nonce - The nonce of the note. If undefined, will look for the first index that matches the note. */ - addNote( - account: AztecAddress, - contract: AztecAddress, - storageSlot: Fr, - note: Note, - txHash: TxHash, - nonce?: Fr, - ): Promise; + addNote(note: ExtendedNote): Promise; /** - * Finds the nonce(s) for a note in a tx with given a note at a specified contract address and storage slot. - * @param contract - The contract address of the note. - * @param storageSlot - The storage slot of the note. - * @param note - The note as emitted from Noir contract. - * @param txHash - The tx hash of the tx containing the note. + * Finds the nonce(s) for a given note. + * @param note - The note to find the nonces for. * @returns The nonces of the note. - * @remarks More than single nonce may be returned since there might be more than one nonce for a given note. + * @remarks More than a single nonce may be returned since there might be more than one nonce for a given note. */ - getNoteNonces(contract: AztecAddress, storageSlot: Fr, note: Note, txHash: TxHash): Promise; + getNoteNonces(note: ExtendedNote): Promise; /** * Simulate the execution of a view (read-only) function on a deployed contract without actually modifying state. diff --git a/yarn-project/types/src/mocks.ts b/yarn-project/types/src/mocks.ts index 5257375c5ad8..459c436afff2 100644 --- a/yarn-project/types/src/mocks.ts +++ b/yarn-project/types/src/mocks.ts @@ -5,7 +5,7 @@ import { Fr, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - Proof + Proof, } from '@aztec/circuits.js'; import { makePrivateKernelPublicInputsFinal, makePublicCallRequest } from '@aztec/circuits.js/factories'; import { ContractArtifact } from '@aztec/foundation/abi'; @@ -60,11 +60,5 @@ export const randomExtendedNote = ({ txHash = randomTxHash(), storageSlot = Fr.random(), }: Partial = {}) => { - return new ExtendedNote( - note, - owner, - contractAddress, - storageSlot, - txHash, - ); + return new ExtendedNote(note, owner, contractAddress, storageSlot, txHash); }; From becd6b6a8a0e8be95c27d7d42435cbd00c44e79a Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 13:19:11 +0000 Subject: [PATCH 24/41] fix --- yarn-project/pxe/src/pxe_service/pxe_service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 989377c746f0..ef3d01f388ff 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -125,6 +125,7 @@ export class PXEService implements PXE { const completeAddress = await CompleteAddress.fromPrivateKeyAndPartialAddress(privKey, partialAddress); const wasAdded = await this.db.addCompleteAddress(completeAddress); if (wasAdded) { + this.keyStore.addAccount(privKey); this.synchronizer.addAccount(completeAddress, this.keyStore, this.config.l2StartingBlock); this.log.info(`Registered account ${completeAddress.address.toString()}`); this.log.debug(`Registered account\n ${completeAddress.toReadableString()}`); @@ -201,8 +202,9 @@ export class PXEService implements PXE { public async addNote(note: ExtendedNote) { const account = (await this.db.getCompleteAddress(note.owner)) ?? {}; + console.log('account', account); if (!account) { - throw new Error('Unknown account.'); + throw new Error('Unknown note owner: ' + note.owner.toString()); } const [nonce] = await this.getNoteNonces(note); From 47df975ae42dfd9323379bf69eef1c5c86335663 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 13:29:15 +0000 Subject: [PATCH 25/41] formatting fixes --- yarn-project/pxe/src/database/database.ts | 2 +- yarn-project/pxe/src/note_processor/note_processor.test.ts | 1 - yarn-project/pxe/src/pxe_service/pxe_service.ts | 2 -- yarn-project/types/src/interfaces/pxe.ts | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/yarn-project/pxe/src/database/database.ts b/yarn-project/pxe/src/database/database.ts index a03cdfa1bc4b..7b703adf3b48 100644 --- a/yarn-project/pxe/src/database/database.ts +++ b/yarn-project/pxe/src/database/database.ts @@ -1,7 +1,7 @@ import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { ContractDatabase, MerkleTreeId, NoteFilter, PublicKey } from '@aztec/types'; +import { ContractDatabase, MerkleTreeId, NoteFilter } from '@aztec/types'; import { NoteDao } from './note_dao.js'; 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 63e47b5dfd74..dbf0602f80ba 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -5,7 +5,6 @@ import { Point } from '@aztec/foundation/fields'; import { ConstantKeyPair } from '@aztec/key-store'; import { AztecNode, - ExtendedNote, FunctionL2Logs, INITIAL_L2_BLOCK_NUM, KeyPair, diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index ef3d01f388ff..ae1da3f0fd46 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -39,7 +39,6 @@ import { LogFilter, MerkleTreeId, NodeInfo, - Note, NoteFilter, PXE, SimulationError, @@ -202,7 +201,6 @@ export class PXEService implements PXE { public async addNote(note: ExtendedNote) { const account = (await this.db.getCompleteAddress(note.owner)) ?? {}; - console.log('account', account); if (!account) { throw new Error('Unknown note owner: ' + note.owner.toString()); } diff --git a/yarn-project/types/src/interfaces/pxe.ts b/yarn-project/types/src/interfaces/pxe.ts index 31d47ab2cd62..f52eb27273a0 100644 --- a/yarn-project/types/src/interfaces/pxe.ts +++ b/yarn-project/types/src/interfaces/pxe.ts @@ -8,7 +8,6 @@ import { GetUnencryptedLogsResponse, L2Tx, LogFilter, - Note, Tx, TxExecutionRequest, TxHash, From be5e7afa94ff5f37b2910d18d3d97d53131fcdb6 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 14:02:45 +0000 Subject: [PATCH 26/41] fixes --- yarn-project/pxe/src/database/memory_db.test.ts | 7 ++++++- .../pxe/src/note_processor/note_processor.test.ts | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/yarn-project/pxe/src/database/memory_db.test.ts b/yarn-project/pxe/src/database/memory_db.test.ts index 1eb0a2c42168..a82561108f03 100644 --- a/yarn-project/pxe/src/database/memory_db.test.ts +++ b/yarn-project/pxe/src/database/memory_db.test.ts @@ -17,7 +17,12 @@ describe('Memory DB', () => { const createNotes = (numberOfNotes: number, sameStorage = true) => Array(numberOfNotes) .fill(0) - .map(() => randomNoteDao({ storageSlot: sameStorage ? storageSlot : Fr.random() })); + .map(() => + randomNoteDao({ + contractAddress: sameStorage ? contractAddress : AztecAddress.random(), + storageSlot: sameStorage ? storageSlot : Fr.random(), + }), + ); it('should add and get notes', async () => { const notes = createNotes(3, false); 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 dbf0602f80ba..4df997f2337a 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -154,7 +154,7 @@ describe('Note Processor', () => { expect(addNotesSpy).toHaveBeenCalledTimes(1); expect(addNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ - ...ownedL1NotePayloads[0], + extendedNote: expect.objectContaining({ ...ownedL1NotePayloads[0] }), index: BigInt(firstBlockDataStartIndex + 2), }), ]); @@ -175,17 +175,17 @@ describe('Note Processor', () => { expect(addNotesSpy).toHaveBeenCalledTimes(1); expect(addNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ - ...ownedL1NotePayloads[0], + extendedNote: expect.objectContaining({ ...ownedL1NotePayloads[0] }), // Index 1 log in the 2nd tx. index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (2 - 1) + 1), }), expect.objectContaining({ - ...ownedL1NotePayloads[1], + extendedNote: expect.objectContaining({ ...ownedL1NotePayloads[1] }), // Index 0 log in the 4th tx. index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 0), }), expect.objectContaining({ - ...ownedL1NotePayloads[2], + extendedNote: expect.objectContaining({ ...ownedL1NotePayloads[2] }), // Index 2 log in the 4th tx. index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 2), }), @@ -206,7 +206,7 @@ describe('Note Processor', () => { await noteProcessor.process(blockContexts, encryptedLogsArr); const addedNoteDaos: NoteDao[] = addNotesSpy.mock.calls[0][0]; - expect(addedNoteDaos).toEqual([ + expect(addedNoteDaos.map(dao => dao.extendedNote)).toEqual([ expect.objectContaining({ ...ownedL1NotePayloads[0] }), expect.objectContaining({ ...ownedL1NotePayloads[1] }), expect.objectContaining({ ...ownedL1NotePayloads[2] }), From f7c194ca07349856b80071c6801204997b6c0d33 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 15:50:59 +0000 Subject: [PATCH 27/41] reverting stupid changes --- yarn-project/pxe/src/database/database.ts | 6 +-- .../pxe/src/database/memory_db.test.ts | 8 ++-- yarn-project/pxe/src/database/memory_db.ts | 30 ++++++++----- .../pxe/src/database/note_dao.test.ts | 34 ++++++++++----- yarn-project/pxe/src/database/note_dao.ts | 42 +++++++++++++++---- .../src/note_processor/note_processor.test.ts | 15 ++++--- .../pxe/src/note_processor/note_processor.ts | 30 +++++++------ .../pxe/src/pxe_service/pxe_service.ts | 42 +++++++++++++++---- .../pxe/src/simulator_oracle/index.ts | 8 ++-- .../pxe/src/synchronizer/synchronizer.test.ts | 2 +- .../pxe/src/synchronizer/synchronizer.ts | 26 +++++++----- 11 files changed, 164 insertions(+), 79 deletions(-) diff --git a/yarn-project/pxe/src/database/database.ts b/yarn-project/pxe/src/database/database.ts index 7b703adf3b48..dc99768ffcca 100644 --- a/yarn-project/pxe/src/database/database.ts +++ b/yarn-project/pxe/src/database/database.ts @@ -1,4 +1,4 @@ -import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; +import { CompleteAddress, HistoricBlockData, PublicKey } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { ContractDatabase, MerkleTreeId, NoteFilter } from '@aztec/types'; @@ -50,10 +50,10 @@ export interface Database extends ContractDatabase { * Remove nullified notes associated with the given account and nullifiers. * * @param nullifiers - An array of Fr instances representing nullifiers to be matched. - * @param account - An account for which the records are being removed. + * @param account - A PublicKey instance representing the account for which the records are being removed. * @returns Removed notes. */ - removeNullifiedNotes(nullifiers: Fr[], account: AztecAddress): Promise; + removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise; /** * Retrieve the stored Merkle tree roots from the database. diff --git a/yarn-project/pxe/src/database/memory_db.test.ts b/yarn-project/pxe/src/database/memory_db.test.ts index a82561108f03..077f705167a1 100644 --- a/yarn-project/pxe/src/database/memory_db.test.ts +++ b/yarn-project/pxe/src/database/memory_db.test.ts @@ -32,8 +32,8 @@ describe('Memory DB', () => { for (let i = 0; i < notes.length; ++i) { const result = await db.getNotes({ - contractAddress: notes[i].extendedNote.contractAddress, - storageSlot: notes[i].extendedNote.storageSlot, + contractAddress: notes[i].contractAddress, + storageSlot: notes[i].storageSlot, }); expect(result).toEqual([notes[i]]); } @@ -45,8 +45,8 @@ describe('Memory DB', () => { for (let i = 0; i < notes.length; ++i) { const result = await db.getNotes({ - contractAddress: notes[i].extendedNote.contractAddress, - storageSlot: notes[i].extendedNote.storageSlot, + contractAddress: notes[i].contractAddress, + storageSlot: notes[i].storageSlot, }); expect(result).toEqual([notes[i]]); } diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 743a4ff5c994..bd6042497579 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -1,4 +1,4 @@ -import { CompleteAddress, HistoricBlockData } from '@aztec/circuits.js'; +import { CompleteAddress, HistoricBlockData, PublicKey } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -54,23 +54,31 @@ export class MemoryDB extends MemoryContractDatabase implements Database { return Promise.resolve(); } - public getNotes(filter: NoteFilter): Promise { - const notes = this.notesTable.filter( - noteDao => - (filter.contractAddress == undefined || noteDao.extendedNote.contractAddress.equals(filter.contractAddress)) && - (filter.txHash == undefined || noteDao.extendedNote.txHash.equals(filter.txHash)) && - (filter.storageSlot == undefined || noteDao.extendedNote.storageSlot.equals(filter.storageSlot!)) && - (filter.owner == undefined || noteDao.extendedNote.owner.equals(filter.owner!)), + public async getNotes(filter: NoteFilter): Promise { + let ownerPublicKey: PublicKey | undefined; + if (filter.owner !== undefined) { + const ownerCompleteAddress = await this.getCompleteAddress(filter.owner); + if (ownerCompleteAddress === undefined) { + throw new Error(`Owner ${filter.owner.toString()} not found in memory database`); + } + ownerPublicKey = ownerCompleteAddress.publicKey; + } + + return this.notesTable.filter( + note => + (filter.contractAddress == undefined || note.contractAddress.equals(filter.contractAddress)) && + (filter.txHash == undefined || note.txHash.equals(filter.txHash)) && + (filter.storageSlot == undefined || note.storageSlot.equals(filter.storageSlot!)) && + (ownerPublicKey == undefined || note.publicKey.equals(ownerPublicKey!)), ); - return Promise.resolve(notes); } - public removeNullifiedNotes(nullifiers: Fr[], account: AztecAddress) { + public removeNullifiedNotes(nullifiers: Fr[], account: PublicKey) { const nullifierSet = new Set(nullifiers.map(nullifier => nullifier.toString())); const [remaining, removed] = this.notesTable.reduce( (acc: [NoteDao[], NoteDao[]], note) => { const nullifier = note.siloedNullifier.toString(); - if (note.extendedNote.owner.equals(account) && nullifierSet.has(nullifier)) { + if (note.publicKey.equals(account) && nullifierSet.has(nullifier)) { acc[1].push(note); } else { acc[0].push(note); diff --git a/yarn-project/pxe/src/database/note_dao.test.ts b/yarn-project/pxe/src/database/note_dao.test.ts index fe981f814640..f4c22304a3f5 100644 --- a/yarn-project/pxe/src/database/note_dao.test.ts +++ b/yarn-project/pxe/src/database/note_dao.test.ts @@ -1,16 +1,30 @@ -import { Fr } from '@aztec/circuits.js'; -import { ExtendedNote, randomExtendedNote } from '@aztec/types'; +import { AztecAddress, Fr, Point } from '@aztec/circuits.js'; +import { Note, randomTxHash } from '@aztec/types'; import { NoteDao } from './note_dao.js'; -export const randomNoteDao = (extendedNoteAttributes: Partial = {}) => { - const extendedNote = randomExtendedNote(extendedNoteAttributes); - const nonce = Fr.random(); - const innerNoteHash = Fr.random(); - const siloedNullifier = Fr.random(); - const index = BigInt(0); - - return new NoteDao(extendedNote, nonce, innerNoteHash, siloedNullifier, index); +export const randomNoteDao = ({ + note = Note.random(), + contractAddress = AztecAddress.random(), + txHash = randomTxHash(), + storageSlot = Fr.random(), + nonce = Fr.random(), + innerNoteHash = Fr.random(), + siloedNullifier = Fr.random(), + index = BigInt(0), + publicKey = Point.random(), +}: Partial = {}) => { + return new NoteDao( + note, + contractAddress, + storageSlot, + txHash, + nonce, + innerNoteHash, + siloedNullifier, + index, + publicKey, + ); }; describe('Note DAO', () => { diff --git a/yarn-project/pxe/src/database/note_dao.ts b/yarn-project/pxe/src/database/note_dao.ts index cb238f610a10..25bc1eeb7945 100644 --- a/yarn-project/pxe/src/database/note_dao.ts +++ b/yarn-project/pxe/src/database/note_dao.ts @@ -1,14 +1,20 @@ -import { Fr } from '@aztec/circuits.js'; +import { AztecAddress, Fr, Point, PublicKey } from '@aztec/circuits.js'; import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; -import { BufferReader, ExtendedNote } from '@aztec/types'; +import { BufferReader, Note, TxHash } from '@aztec/types'; /** * A note with contextual data. */ export class NoteDao { constructor( - /** The extended note. */ - public extendedNote: ExtendedNote, + /** The note as emitted from the Noir contract. */ + public note: Note, + /** The contract address this note is created in. */ + public contractAddress: AztecAddress, + /** The specific storage location of the note on the contract. */ + public storageSlot: Fr, + /** The hash of the tx the note was created in. */ + public txHash: TxHash, /** The nonce of the note. */ public nonce: Fr, /** @@ -20,27 +26,47 @@ export class NoteDao { public siloedNullifier: Fr, /** The location of the relevant note in the note hash tree. */ public index: bigint, + /** The public key with which the note was encrypted. */ + public publicKey: PublicKey, ) {} toBuffer(): Buffer { return Buffer.concat([ - this.extendedNote.toBuffer(), + this.note.toBuffer(), + this.contractAddress.toBuffer(), + this.storageSlot.toBuffer(), + this.txHash.buffer, this.nonce.toBuffer(), this.innerNoteHash.toBuffer(), this.siloedNullifier.toBuffer(), toBufferBE(this.index, 32), + this.publicKey.toBuffer(), ]); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - const extendedNote = ExtendedNote.fromBuffer(reader); + const note = Note.fromBuffer(reader); + const contractAddress = AztecAddress.fromBuffer(reader); + const storageSlot = Fr.fromBuffer(reader); + const txHash = new TxHash(reader.readBytes(TxHash.SIZE)); const nonce = Fr.fromBuffer(reader); const innerNoteHash = Fr.fromBuffer(reader); const siloedNullifier = Fr.fromBuffer(reader); const index = toBigIntBE(reader.readBytes(32)); + const publicKey = Point.fromBuffer(reader); - return new this(extendedNote, nonce, innerNoteHash, siloedNullifier, index); + return new this( + note, + contractAddress, + storageSlot, + txHash, + nonce, + innerNoteHash, + siloedNullifier, + index, + publicKey, + ); } toString() { @@ -60,6 +86,6 @@ export class NoteDao { // TODO: update // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer const indexSize = Math.ceil(Math.log2(Number(this.index))); - return this.extendedNote.note.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize; + return this.note.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize; } } 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 4df997f2337a..b897d57023f8 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -1,5 +1,5 @@ import { AcirSimulator } from '@aztec/acir-simulator'; -import { CircuitsWasm, CompleteAddress, Fr, MAX_NEW_COMMITMENTS_PER_TX } from '@aztec/circuits.js'; +import { CircuitsWasm, Fr, MAX_NEW_COMMITMENTS_PER_TX } from '@aztec/circuits.js'; import { Grumpkin, pedersenHashInputs } from '@aztec/circuits.js/barretenberg'; import { Point } from '@aztec/foundation/fields'; import { ConstantKeyPair } from '@aztec/key-store'; @@ -34,7 +34,6 @@ describe('Note Processor', () => { let addNotesSpy: any; let noteProcessor: NoteProcessor; let owner: KeyPair; - let ownerAddress: CompleteAddress; let keyStore: MockProxy; let simulator: MockProxy; const firstBlockNum = 123; @@ -120,7 +119,6 @@ describe('Note Processor', () => { wasm = await CircuitsWasm.get(); grumpkin = new Grumpkin(wasm); owner = ConstantKeyPair.random(grumpkin); - ownerAddress = await CompleteAddress.fromPrivateKeyAndPartialAddress(await owner.getPrivateKey(), Fr.random()); }); beforeEach(() => { @@ -131,7 +129,14 @@ describe('Note Processor', () => { keyStore = mock(); simulator = mock(); keyStore.getAccountPrivateKey.mockResolvedValue(owner.getPrivateKey()); - noteProcessor = new NoteProcessor(ownerAddress, keyStore, database, aztecNode, INITIAL_L2_BLOCK_NUM, simulator); + noteProcessor = new NoteProcessor( + owner.getPublicKey(), + keyStore, + database, + aztecNode, + INITIAL_L2_BLOCK_NUM, + simulator, + ); simulator.computeNoteHashAndNullifier.mockImplementation((...args) => Promise.resolve({ @@ -206,7 +211,7 @@ describe('Note Processor', () => { await noteProcessor.process(blockContexts, encryptedLogsArr); const addedNoteDaos: NoteDao[] = addNotesSpy.mock.calls[0][0]; - expect(addedNoteDaos.map(dao => dao.extendedNote)).toEqual([ + expect(addedNoteDaos.map(dao => dao)).toEqual([ expect.objectContaining({ ...ownedL1NotePayloads[0] }), expect.objectContaining({ ...ownedL1NotePayloads[1] }), expect.objectContaining({ ...ownedL1NotePayloads[2] }), diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 69b548614727..ef1a4919dbdb 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -1,15 +1,15 @@ import { CircuitsWasm, - CompleteAddress, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, + PublicKey } from '@aztec/circuits.js'; import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/abis'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; -import { AztecNode, ExtendedNote, KeyStore, L1NotePayload, L2BlockContext, L2BlockL2Logs } from '@aztec/types'; +import { AztecNode, KeyStore, L1NotePayload, L2BlockContext, L2BlockL2Logs } from '@aztec/types'; import { NoteProcessorStats } from '@aztec/types/stats'; import { Database } from '../database/index.js'; @@ -48,7 +48,7 @@ export class NoteProcessor { /** * The public counterpart to the private key to be used in note decryption. */ - public readonly account: CompleteAddress, + public readonly publicKey: PublicKey, private keyStore: KeyStore, private db: Database, private node: AztecNode, @@ -112,7 +112,7 @@ export class NoteProcessor { // We are using set for `userPertainingTxIndices` to avoid duplicates. This would happen in case there were // multiple encrypted logs in a tx pertaining to a user. const noteDaos: NoteDao[] = []; - const privateKey = await this.keyStore.getAccountPrivateKey(this.account.publicKey); + const privateKey = await this.keyStore.getAccountPrivateKey(this.publicKey); // Iterate over all the encrypted logs and try decrypting them. If successful, store the note. for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) { @@ -147,17 +147,15 @@ export class NoteProcessor { excludedIndices.add(commitmentIndex); noteDaos.push( new NoteDao( - new ExtendedNote( - payload.note, - this.account.address, - payload.contractAddress, - payload.storageSlot, - blockContext.getTxHash(indexOfTxInABlock), - ), + payload.note, + payload.contractAddress, + payload.storageSlot, + blockContext.getTxHash(indexOfTxInABlock), nonce, innerNoteHash, siloedNullifier, index, + this.publicKey, ), ); this.stats.decrypted++; @@ -270,19 +268,19 @@ https://github.com/AztecProtocol/aztec-packages/issues/1641`; await this.db.addNotes(noteDaos); noteDaos.forEach(noteDao => { this.log( - `Added note for contract ${noteDao.extendedNote.contractAddress} at slot ${ - noteDao.extendedNote.storageSlot + `Added note for contract ${noteDao.contractAddress} at slot ${ + noteDao.storageSlot } with nullifier ${noteDao.siloedNullifier.toString()}`, ); }); } const newNullifiers: Fr[] = blocksAndNotes.flatMap(b => b.blockContext.block.newNullifiers); - const removedNotes = await this.db.removeNullifiedNotes(newNullifiers, this.account.address); + const removedNotes = await this.db.removeNullifiedNotes(newNullifiers, this.publicKey); removedNotes.forEach(noteDao => { this.log( - `Removed note for contract ${noteDao.extendedNote.contractAddress} at slot ${ - noteDao.extendedNote.storageSlot + `Removed note for contract ${noteDao.contractAddress} at slot ${ + noteDao.storageSlot } with nullifier ${noteDao.siloedNullifier.toString()}`, ); }); diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index ae1da3f0fd46..2b54e730f808 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -124,8 +124,8 @@ export class PXEService implements PXE { const completeAddress = await CompleteAddress.fromPrivateKeyAndPartialAddress(privKey, partialAddress); const wasAdded = await this.db.addCompleteAddress(completeAddress); if (wasAdded) { - this.keyStore.addAccount(privKey); - this.synchronizer.addAccount(completeAddress, this.keyStore, this.config.l2StartingBlock); + const pubKey = this.keyStore.addAccount(privKey); + this.synchronizer.addAccount(pubKey, this.keyStore, this.config.l2StartingBlock); this.log.info(`Registered account ${completeAddress.address.toString()}`); this.log.debug(`Registered account\n ${completeAddress.toReadableString()}`); } else { @@ -196,13 +196,29 @@ export class PXEService implements PXE { public async getNotes(filter: NoteFilter): Promise { const noteDaos = await this.db.getNotes(filter); - return noteDaos.map(dao => dao.extendedNote); + + // TODO(benesjan): Refactor --> This type conversion is ugly but I decided to keep it this way for now because + // key derivation will affect all this + const extendedNotes = noteDaos.map(async dao => { + let owner = filter.owner; + if (owner === undefined) { + const completeAddresses = (await this.db.getCompleteAddresses()).find(address => + address.publicKey.equals(dao.publicKey), + ); + if (completeAddresses === undefined) { + throw new Error(`Cannot find complete address for public key ${dao.publicKey.toString()}`); + } + owner = completeAddresses.address; + } + return new ExtendedNote(dao.note, owner, dao.contractAddress, dao.storageSlot, dao.txHash); + }); + return Promise.all(extendedNotes); } public async addNote(note: ExtendedNote) { - const account = (await this.db.getCompleteAddress(note.owner)) ?? {}; - if (!account) { - throw new Error('Unknown note owner: ' + note.owner.toString()); + const { publicKey } = (await this.db.getCompleteAddress(note.owner)) ?? {}; + if (!publicKey) { + throw new Error('Unknown account.'); } const [nonce] = await this.getNoteNonces(note); @@ -228,7 +244,19 @@ export class PXEService implements PXE { throw new Error('The note has been destroyed.'); } - await this.db.addNote(new NoteDao(note, nonce, innerNoteHash, siloedNullifier, index)); + await this.db.addNote( + new NoteDao( + note.note, + note.contractAddress, + note.storageSlot, + note.txHash, + nonce, + innerNoteHash, + siloedNullifier, + index, + publicKey, + ), + ); } public async getNoteNonces(note: ExtendedNote): Promise { diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 6ba446df2bf2..f4f8f2573596 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -46,11 +46,11 @@ export class SimulatorOracle implements DBOracle { async getNotes(contractAddress: AztecAddress, storageSlot: Fr) { const noteDaos = await this.db.getNotes({ contractAddress, storageSlot }); - return noteDaos.map(({ extendedNote, nonce, innerNoteHash, siloedNullifier, index }) => ({ - contractAddress: extendedNote.contractAddress, - storageSlot: extendedNote.storageSlot, + return noteDaos.map(({ contractAddress, storageSlot, nonce, note, innerNoteHash, siloedNullifier, index }) => ({ + contractAddress, + storageSlot, nonce, - note: extendedNote.note, + note, innerNoteHash, siloedNullifier, // PXE can use this index to get full MembershipWitness diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.test.ts b/yarn-project/pxe/src/synchronizer/synchronizer.test.ts index ffd5037413d6..29833507e2b4 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.test.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.test.ts @@ -109,7 +109,7 @@ describe('Synchronizer', () => { await database.addCompleteAddress(completeAddress); // Add the account which will add the note processor to the synchronizer - synchronizer.addAccount(completeAddress, keyStore, INITIAL_L2_BLOCK_NUM); + synchronizer.addAccount(completeAddress.publicKey, keyStore, INITIAL_L2_BLOCK_NUM); await synchronizer.workNoteProcessorCatchUp(); diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.ts b/yarn-project/pxe/src/synchronizer/synchronizer.ts index 2e08c3c5ac1f..56a42dc377f2 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.ts @@ -1,4 +1,4 @@ -import { AztecAddress, CircuitsWasm, CompleteAddress, Fr, HistoricBlockData } from '@aztec/circuits.js'; +import { AztecAddress, CircuitsWasm, Fr, HistoricBlockData, PublicKey } from '@aztec/circuits.js'; import { computeGlobalsHash } from '@aztec/circuits.js/abis'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { InterruptibleSleep } from '@aztec/foundation/sleep'; @@ -179,9 +179,9 @@ export class Synchronizer { if (noteProcessor.status.syncedToBlock === this.synchedToBlock) { // Note processor caught up, move it to `noteProcessors` from `noteProcessorsToCatchUp`. - this.log(`Note processor for account ${noteProcessor.account.address.toString()} has caught up`, { + this.log(`Note processor for ${noteProcessor.publicKey.toString()} has caught up`, { eventName: 'note-processor-caught-up', - publicKey: noteProcessor.account.publicKey.toString(), + publicKey: noteProcessor.publicKey.toString(), duration: noteProcessor.timer.ms(), dbSize: this.db.estimateSize(), ...noteProcessor.stats, @@ -234,16 +234,16 @@ export class Synchronizer { * Creates a NoteProcessor instance for the account and pushes it into the noteProcessors array. * The method resolves immediately after pushing the new note processor. * - * @param account - A complete address of the account toa dd. + * @param publicKey - The public key for the account. * @param keyStore - The key store. * @param startingBlock - The block where to start scanning for notes for this accounts. * @returns A promise that resolves once the account is added to the Synchronizer. */ - public addAccount(account: CompleteAddress, keyStore: KeyStore, startingBlock: number) { - const processor = this.noteProcessors.find(x => x.account.equals(account)); + public addAccount(publicKey: PublicKey, keyStore: KeyStore, startingBlock: number) { + const processor = this.noteProcessors.find(x => x.publicKey.equals(publicKey)); if (processor) return; - this.noteProcessorsToCatchUp.push(new NoteProcessor(account, keyStore, this.db, this.node, startingBlock)); + this.noteProcessorsToCatchUp.push(new NoteProcessor(publicKey, keyStore, this.db, this.node, startingBlock)); } /** @@ -255,9 +255,15 @@ export class Synchronizer { * @throws If checking a sync status of account which is not registered. */ public async isAccountStateSynchronized(account: AztecAddress) { - const processor = this.noteProcessors.find(x => x.account.address.equals(account)); + const completeAddress = await this.db.getCompleteAddress(account); + if (!completeAddress) { + throw new Error(`Checking if account is synched is not possible for ${account} because it is not registered.`); + } + const processor = this.noteProcessors.find(x => x.publicKey.equals(completeAddress.publicKey)); if (!processor) { - throw new Error(`Account ${account} not found.`); + throw new Error( + `Checking if account is synched is not possible for ${account} because it is only registered as a recipient.`, + ); } return await processor.isSynchronized(); } @@ -280,7 +286,7 @@ export class Synchronizer { public getSyncStatus() { return { blocks: this.synchedToBlock, - notes: Object.fromEntries(this.noteProcessors.map(n => [n.account.publicKey.toString(), n.status.syncedToBlock])), + notes: Object.fromEntries(this.noteProcessors.map(n => [n.publicKey.toString(), n.status.syncedToBlock])), }; } } From dc3522e9f79cb581905f181a6f8a7b6c8e430c55 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 15:52:25 +0000 Subject: [PATCH 28/41] cspell --- cspell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cspell.json b/cspell.json index 00506c7af678..f549ebafcf73 100644 --- a/cspell.json +++ b/cspell.json @@ -14,6 +14,7 @@ "barretenberg", "bbfree", "bbmalloc", + "benesjan", "bodyparser", "bootnode", "Brillig", From 8e91d654330a8fdfab51a9c32076ab05d1f5b093 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 16:01:52 +0000 Subject: [PATCH 29/41] reverting unnecessary changes to artifacts --- .../blank-react/src/artifacts/Blank.json | 10 +-- .../boxes/blank/src/artifacts/Blank.json | 10 +-- .../boxes/token/src/artifacts/Token.json | 74 +++++++++---------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/yarn-project/boxes/blank-react/src/artifacts/Blank.json b/yarn-project/boxes/blank-react/src/artifacts/Blank.json index 42966767d89d..b626f0d25939 100644 --- a/yarn-project/boxes/blank-react/src/artifacts/Blank.json +++ b/yarn-project/boxes/blank-react/src/artifacts/Blank.json @@ -37,23 +37,23 @@ "fileMap": { "1": { "source": "contract Blank {\n use dep::aztec::{\n abi,\n oracle::{\n get_public_key::get_public_key,\n },\n };\n\n #[aztec(private)]\n fn constructor() {}\n\n #[aztec(private)]\n fn getPublicKey(\n address: Field,\n ) -> [Field; 2]{\n let pub_key = get_public_key(address);\n \n [pub_key.x, pub_key.y]\n }\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/blank-react/src/contracts/src/main.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/blank-react/src/contracts/src/main.nr" }, "34": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\nuse crate::hash::pedersen_hash;\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n note_hash_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.note_hash_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { note_hash_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n pedersen_hash([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n pedersen_hash(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n pedersen_hash(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" }, "35": { "source": "use crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\nuse crate::hash::pedersen_hash;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n pedersen_hash([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" }, "38": { "source": "use dep::std::hash::{pedersen_hash_with_separator, sha256};\nuse crate::constants_gen::{\n GENERATOR_INDEX__SIGNATURE_PAYLOAD,\n GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET,\n};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n // TODO(#1205) This is probably not the right index to use\n pedersen_hash([secret], GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET)\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n pedersen_hash_with_separator(inputs, hash_index)\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" }, "58": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: Field) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" } } } diff --git a/yarn-project/boxes/blank/src/artifacts/Blank.json b/yarn-project/boxes/blank/src/artifacts/Blank.json index 8dcb2487d354..9be43a48e317 100644 --- a/yarn-project/boxes/blank/src/artifacts/Blank.json +++ b/yarn-project/boxes/blank/src/artifacts/Blank.json @@ -37,23 +37,23 @@ "fileMap": { "1": { "source": "contract Blank {\n use dep::aztec::{\n abi,\n oracle::{\n get_public_key::get_public_key,\n },\n };\n\n #[aztec(private)]\n fn constructor() {}\n\n #[aztec(private)]\n fn getPublicKey(\n address: Field,\n ) -> [Field; 2]{\n let pub_key = get_public_key(address);\n \n [pub_key.x, pub_key.y]\n }\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/blank/src/contracts/src/main.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/blank/src/contracts/src/main.nr" }, "34": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\nuse crate::hash::pedersen_hash;\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n note_hash_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.note_hash_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { note_hash_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n pedersen_hash([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n pedersen_hash(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n pedersen_hash(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" }, "35": { "source": "use crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\nuse crate::hash::pedersen_hash;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n pedersen_hash([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" }, "38": { "source": "use dep::std::hash::{pedersen_hash_with_separator, sha256};\nuse crate::constants_gen::{\n GENERATOR_INDEX__SIGNATURE_PAYLOAD,\n GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET,\n};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n // TODO(#1205) This is probably not the right index to use\n pedersen_hash([secret], GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET)\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n pedersen_hash_with_separator(inputs, hash_index)\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" }, "58": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: Field) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" } } } diff --git a/yarn-project/boxes/token/src/artifacts/Token.json b/yarn-project/boxes/token/src/artifacts/Token.json index a9b925326513..1117f77a9d7b 100644 --- a/yarn-project/boxes/token/src/artifacts/Token.json +++ b/yarn-project/boxes/token/src/artifacts/Token.json @@ -3185,7 +3185,7 @@ "fileMap": { "1": { "source": "// docs:start:token_all\n// docs:start:imports\nmod types;\n\n// Minimal token implementation that supports `AuthWit` accounts.\n// The auth message follows a similar pattern to the cross-chain message and includes a designated caller.\n// The designated caller is ALWAYS used here, and not based on a flag as cross-chain.\n// message hash = H([caller, contract, selector, ...args])\n// To be read as `caller` calls function at `contract` defined by `selector` with `args`\n// Including a nonce in the message hash ensures that the message can only be used once.\n\ncontract Token {\n // Libs\n use dep::std::option::Option;\n\n use dep::safe_math::SafeU120;\n\n use dep::aztec::{\n note::{\n note_getter_options::NoteGetterOptions,\n note_header::NoteHeader,\n utils as note_utils,\n },\n context::{PrivateContext, PublicContext, Context},\n hash::{compute_secret_hash},\n state_vars::{map::Map, public_state::PublicState, set::Set},\n types::type_serialization::{\n field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN},\n bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN},\n aztec_address_serialization::{AztecAddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN},\n },\n types::address::{AztecAddress},\n selector::compute_selector,\n };\n\n // docs:start:import_authwit\n use dep::authwit::{\n auth::{\n assert_current_call_valid_authwit, \n assert_current_call_valid_authwit_public, \n },\n };\n // docs:end:import_authwit\n\n use crate::types::{\n transparent_note::{TransparentNote, TransparentNoteMethods, TRANSPARENT_NOTE_LEN},\n token_note::{TokenNote, TokenNoteMethods, TOKEN_NOTE_LEN},\n balances_map::{BalancesMap},\n safe_u120_serialization::{SafeU120SerializationMethods, SAFE_U120_SERIALIZED_LEN}\n };\n // docs:end::imports\n\n // docs:start:storage_struct\n struct Storage {\n // docs:start:storage_admin\n admin: PublicState,\n // docs:end:storage_admin\n // docs:start:storage_minters\n minters: Map>,\n // docs:end:storage_minters\n // docs:start:storage_balances\n balances: BalancesMap,\n // docs:end:storage_balances\n total_supply: PublicState,\n // docs:start:storage_pending_shields\n pending_shields: Set,\n // docs:end:storage_pending_shields\n public_balances: Map>,\n }\n // docs:end:storage_struct\n\n // docs:start:storage_init\n impl Storage {\n fn init(context: Context) -> pub Self {\n Storage {\n // docs:start:storage_admin_init\n admin: PublicState::new(\n context,\n 1,\n AztecAddressSerializationMethods,\n ),\n // docs:end:storage_admin_init\n // docs:start:storage_minters_init\n minters: Map::new(\n context,\n 2,\n |context, slot| {\n PublicState::new(\n context,\n slot,\n BoolSerializationMethods,\n )\n },\n ),\n // docs:end:storage_minters_init\n balances: BalancesMap::new(context, 3),\n total_supply: PublicState::new(\n context,\n 4,\n SafeU120SerializationMethods,\n ),\n // docs:start:storage_pending_shields_init\n pending_shields: Set::new(context, 5, TransparentNoteMethods),\n // docs:end:storage_pending_shields_init\n public_balances: Map::new(\n context,\n 6,\n |context, slot| {\n PublicState::new(\n context,\n slot,\n SafeU120SerializationMethods,\n )\n },\n ),\n }\n }\n }\n // docs:end:storage_init\n\n // docs:start:constructor\n #[aztec(private)]\n fn constructor(admin: AztecAddress) {\n let selector = compute_selector(\"_initialize((Field))\");\n context.call_public_function(context.this_address(), selector, [admin.address]);\n }\n // docs:end:constructor\n\n // docs:start:set_admin\n #[aztec(public)]\n fn set_admin(\n new_admin: AztecAddress,\n ) {\n assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), \"caller is not admin\");\n // docs:start:write_admin\n storage.admin.write(new_admin);\n // docs:end:write_admin\n }\n // docs:end:set_admin\n\n // docs:start:set_minter\n #[aztec(public)]\n fn set_minter(\n minter: AztecAddress,\n approve: bool,\n ) {\n // docs:start:read_admin\n assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), \"caller is not admin\");\n // docs:end:read_admin\n // docs:start:write_minter\n storage.minters.at(minter.address).write(approve);\n // docs:end:write_minter\n }\n // docs:end:set_minter\n\n // docs:start:mint_public\n #[aztec(public)]\n fn mint_public(\n to: AztecAddress,\n amount: Field,\n ) -> Field {\n // docs:start:read_minter\n assert(storage.minters.at(context.msg_sender()).read(), \"caller is not minter\");\n // docs:end:read_minter\n let amount = SafeU120::new(amount);\n let new_balance = storage.public_balances.at(to.address).read().add(amount);\n let supply = storage.total_supply.read().add(amount);\n\n storage.public_balances.at(to.address).write(new_balance);\n storage.total_supply.write(supply);\n 1\n }\n // docs:end:mint_public\n\n // docs:start:mint_private\n #[aztec(public)]\n fn mint_private(\n amount: Field,\n secret_hash: Field,\n ) -> Field {\n assert(storage.minters.at(context.msg_sender()).read(), \"caller is not minter\");\n let pending_shields = storage.pending_shields;\n let mut note = TransparentNote::new(amount, secret_hash);\n let supply = storage.total_supply.read().add(SafeU120::new(amount));\n\n storage.total_supply.write(supply);\n // docs:start:insert_from_public\n pending_shields.insert_from_public(&mut note);\n // docs:end:insert_from_public\n 1\n }\n // docs:end:mint_private\n\n // docs:start:shield\n #[aztec(public)]\n fn shield(\n from: AztecAddress,\n amount: Field,\n secret_hash: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n // The redeem is only spendable once, so we need to ensure that you cannot insert multiple shields from the same message.\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n\n let pending_shields = storage.pending_shields;\n let mut note = TransparentNote::new(amount.value as Field, secret_hash);\n\n storage.public_balances.at(from.address).write(from_balance);\n pending_shields.insert_from_public(&mut note);\n 1\n }\n // docs:end:shield\n\n // docs:start:transfer_public\n #[aztec(public)]\n fn transfer_public(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n storage.public_balances.at(from.address).write(from_balance);\n\n let to_balance = storage.public_balances.at(to.address).read().add(amount);\n storage.public_balances.at(to.address).write(to_balance);\n\n 1\n }\n // docs:end:transfer_public\n\n // docs:start:burn_public\n #[aztec(public)]\n fn burn_public(\n from: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n storage.public_balances.at(from.address).write(from_balance);\n\n let new_supply = storage.total_supply.read().sub(amount);\n storage.total_supply.write(new_supply);\n\n 1\n }\n // docs:end:burn_public\n\n // docs:start:redeem_shield\n #[aztec(private)]\n fn redeem_shield(\n to: AztecAddress,\n amount: Field,\n secret: Field,\n ) -> Field {\n let pending_shields = storage.pending_shields;\n let secret_hash = compute_secret_hash(secret);\n let options = NoteGetterOptions::new().select(0, amount).select(1, secret_hash).set_limit(1);\n let notes = pending_shields.get_notes(options);\n let note = notes[0].unwrap_unchecked();\n pending_shields.remove(note);\n\n storage.balances.at(to).add(SafeU120::new(amount));\n\n 1\n }\n // docs:end:redeem_shield\n\n // docs:start:unshield\n #[aztec(private)]\n fn unshield(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n storage.balances.at(from).sub(SafeU120::new(amount));\n\n let selector = compute_selector(\"_increase_public_balance((Field),Field)\");\n let _void = context.call_public_function(context.this_address(), selector, [to.address, amount]);\n\n 1\n }\n // docs:end:unshield\n\n // docs:start:transfer\n #[aztec(private)]\n fn transfer(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n storage.balances.at(from).sub(amount);\n storage.balances.at(to).add(amount);\n\n 1\n }\n // docs:end:transfer\n\n // docs:start:burn\n #[aztec(private)]\n fn burn(\n from: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n storage.balances.at(from).sub(SafeU120::new(amount));\n\n let selector = compute_selector(\"_reduce_total_supply(Field)\");\n let _void = context.call_public_function(context.this_address(), selector, [amount]);\n\n 1\n }\n // docs:end:burn\n\n // docs:start:initialize\n #[aztec(public)]\n internal fn _initialize(\n new_admin: AztecAddress,\n ) {\n storage.admin.write(new_admin);\n storage.minters.at(new_admin.address).write(true);\n }\n // docs:end:initialize\n\n /// Internal ///\n\n // docs:start:increase_public_balance\n #[aztec(public)]\n internal fn _increase_public_balance(\n to: AztecAddress,\n amount: Field,\n ) {\n let new_balance = storage.public_balances.at(to.address).read().add(SafeU120::new(amount));\n storage.public_balances.at(to.address).write(new_balance);\n }\n // docs:end:increase_public_balance\n\n // docs:start:reduce_total_supply\n #[aztec(public)]\n internal fn _reduce_total_supply(\n amount: Field,\n ) {\n // Only to be called from burn.\n let new_supply = storage.total_supply.read().sub(SafeU120::new(amount));\n storage.total_supply.write(new_supply);\n }\n // docs:end:reduce_total_supply\n\n /// Unconstrained ///\n\n // docs:start:admin\n unconstrained fn admin() -> Field {\n storage.admin.read().address\n }\n // docs:end:admin\n\n // docs:start:is_minter\n unconstrained fn is_minter(\n minter: AztecAddress,\n ) -> bool {\n storage.minters.at(minter.address).read()\n }\n // docs:end:is_minter\n\n // docs:start:total_supply\n unconstrained fn total_supply() -> u120 {\n storage.total_supply.read().value\n }\n // docs:end:total_supply\n\n // docs:start:balance_of_private\n unconstrained fn balance_of_private(\n owner: AztecAddress,\n ) -> u120 {\n storage.balances.at(owner).balance_of().value\n }\n // docs:end:balance_of_private\n\n // docs:start:balance_of_public\n unconstrained fn balance_of_public(\n owner: AztecAddress,\n ) -> u120 {\n storage.public_balances.at(owner.address).read().value\n }\n // docs:end:balance_of_public\n\n // Below this point is the stuff of nightmares.\n // This should ideally not be required. What do we do if vastly different types of preimages?\n\n // docs:start:compute_note_hash_and_nullifier\n // Computes note hash and nullifier.\n // Note 1: Needs to be defined by every contract producing logs.\n // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes.\n unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; TOKEN_NOTE_LEN]) -> [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n if (storage_slot == 5) {\n note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, preimage)\n } else {\n note_utils::compute_note_hash_and_nullifier(TokenNoteMethods, note_header, preimage)\n }\n }\n // docs:end:compute_note_hash_and_nullifier\n}\n// docs:end:token_all\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/main.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/main.nr" }, "18": { "source": "struct GrumpkinScalar {\n low: Field,\n high: Field,\n}\n\nimpl GrumpkinScalar {\n pub fn new(low: Field, high: Field) -> Self {\n // TODO: check that the low and high value fit within the grumpkin modulus\n GrumpkinScalar { low, high }\n }\n}\n\nglobal GRUMPKIN_SCALAR_SERIALIZED_LEN: Field = 2;\n\npub fn deserialize_grumpkin_scalar(fields: [Field; GRUMPKIN_SCALAR_SERIALIZED_LEN]) -> GrumpkinScalar {\n GrumpkinScalar { low: fields[0], high: fields[1] }\n}\n\npub fn serialize_grumpkin_scalar(scalar: GrumpkinScalar) -> [Field; GRUMPKIN_SCALAR_SERIALIZED_LEN] {\n [scalar.low, scalar.high]\n}\n", @@ -3205,147 +3205,147 @@ }, "37": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\nuse crate::hash::pedersen_hash;\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n note_hash_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.note_hash_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { note_hash_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n pedersen_hash([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n pedersen_hash(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n pedersen_hash(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/abi.nr" }, "38": { "source": "use crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\nuse crate::hash::pedersen_hash;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n pedersen_hash([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/address.nr" }, "40": { "source": "use crate::constants_gen::{\n EMPTY_NULLIFIED_COMMITMENT,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n};\n\nuse crate::abi;\n\nuse crate::abi::{\n hash_args,\n CallContext,\n ContractDeploymentData,\n HistoricBlockData,\n FunctionData,\n PrivateCircuitPublicInputs,\n PublicCircuitPublicInputs,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// l1 to l2 messaging\nuse crate::messaging::process_l1_to_l2_message;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem;\n\nuse crate::types::{\n vec::BoundedVec,\n point::Point,\n};\n\nuse crate::utils::arr_copy_slice;\n\nuse crate::oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n};\n\nuse dep::std::option::Option;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: abi::PrivateContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n pending_read_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n nullified_commitments: BoundedVec,\n\n private_call_stack : BoundedVec,\n public_call_stack : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n block_data: HistoricBlockData,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: abi::PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(0),\n pending_read_requests: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n nullified_commitments: BoundedVec::new(0),\n\n block_data: inputs.block_data,\n\n private_call_stack: BoundedVec::new(0),\n public_call_stack: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> Field {\n self.inputs.call_context.function_selector\n }\n\n pub fn finish(self) -> abi::PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = abi::PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n pending_read_requests: self.pending_read_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n nullified_commitments: self.nullified_commitments.storage,\n private_call_stack: self.private_call_stack.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.block_data,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n self.read_requests.push(read_request);\n }\n\n pub fn push_pending_read_request(&mut self, pending_read_request: Field) {\n self.pending_read_requests.push(pending_read_request);\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n // We never push a zero nullified_commitment as zero is used to indicate the end\n // of a field array in private kernel. This routine transparently replaces a\n // zero value into the special placeholder: EMPTY_NULLIFIED_COMMITMENT.\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n let mut non_zero_nullified = nullified_commitment;\n if (non_zero_nullified == 0) {\n non_zero_nullified = EMPTY_NULLIFIED_COMMITMENT;\n }\n self.nullified_commitments.push(non_zero_nullified);\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) \n // docs:end:context_message_portal\n {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n msg_key: Field,\n content: Field,\n secret: Field\n ) \n // docs:end:context_consume_l1_to_l2_message\n {\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, self.this_address(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PrivateCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n function_selector: fields[8], // practically same as fields[1]\n is_delegate_call : fields[9] as bool,\n is_static_call : fields[10] as bool,\n is_contract_deployment: fields[11] as bool,\n },\n // TODO handle the offsets as a variable incremented during extraction?\n args_hash: fields[12],\n return_values: arr_copy_slice(fields, [0; RETURN_VALUES_LENGTH], 13),\n read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 17),\n pending_read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 49),\n new_commitments: arr_copy_slice(fields, [0; MAX_NEW_COMMITMENTS_PER_CALL], 81),\n new_nullifiers: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 97),\n nullified_commitments: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 113),\n private_call_stack: arr_copy_slice(fields, [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], 129),\n public_call_stack: arr_copy_slice(fields, [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], 133),\n new_l2_to_l1_msgs: arr_copy_slice(fields, [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], 137),\n encrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 139),\n unencrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 141),\n encrypted_log_preimages_length: fields[143],\n unencrypted_log_preimages_length: fields[144],\n block_data: HistoricBlockData {\n // Must match order in `private_circuit_public_inputs.hpp`\n note_hash_tree_root : fields[145],\n nullifier_tree_root : fields[146],\n contract_tree_root : fields[147],\n l1_to_l2_messages_tree_root : fields[148],\n blocks_tree_root : fields[149],\n public_data_tree_root: fields[150],\n global_variables_hash: fields[151],\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: Point::new(fields[152], fields[153]),\n constructor_vk_hash : fields[154],\n function_tree_root : fields[155],\n contract_address_salt : fields[156],\n portal_contract_address : fields[157],\n },\n chain_id: fields[158],\n version: fields[159],\n },\n is_execution_request: fields[160] as bool,\n };\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.private_call_stack.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PublicCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n function_selector: fields[8], // practically same as fields[1]\n is_delegate_call : fields[9] as bool,\n is_static_call : fields[10] as bool,\n is_contract_deployment: fields[11] as bool,\n },\n args_hash: fields[12],\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [0; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [0; MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_data: HistoricBlockData::empty(),\n prover_address: 0,\n },\n is_execution_request: true,\n };\n\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.public_call_stack.push(item.hash());\n }\n}\n\nuse crate::abi::{\n ContractStorageRead,\n ContractStorageUpdateRequest\n};\n\nstruct PublicContext {\n inputs: abi::PublicContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_read: BoundedVec,\n public_call_stack: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicContext {\n pub fn new(inputs: abi::PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = ContractStorageRead::empty();\n let empty_storage_update = ContractStorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_read: BoundedVec::new(empty_storage_read),\n public_call_stack: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_data: inputs.block_data,\n prover_address: 0,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n pub fn selector(self) -> Field {\n self.inputs.call_context.function_selector\n }\n\n pub fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n pub fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n pub fn finish(self) -> abi::PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = abi::PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_read: self.contract_storage_read.storage,\n return_values: self.return_values.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.inputs.block_data,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n }\n\n pub fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, this, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_public_function(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = abi::hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n pub fn call_public_function_no_args(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context {\n private: Option::some(context),\n public: Option::none()\n }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context {\n public: Option::some(context),\n private: Option::none()\n }\n }\n\n pub fn none() -> Context {\n Context {\n public: Option::none(),\n private: Option::none()\n }\n }\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/context.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/context.nr" }, "41": { "source": "use dep::std::hash::{pedersen_hash_with_separator, sha256};\nuse crate::constants_gen::{\n GENERATOR_INDEX__SIGNATURE_PAYLOAD,\n GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET,\n};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n // TODO(#1205) This is probably not the right index to use\n pedersen_hash([secret], GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET)\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n pedersen_hash_with_separator(inputs, hash_index)\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/hash.nr" }, "42": { "source": "use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse crate::types::point::Point;\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n log: [Field; N],\n) {\n let _ = oracle::logs::emit_encrypted_log(contract_address, storage_slot, encryption_pub_key, log);\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(\n context: &mut PublicContext,\n log: T,\n) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(\n context: &mut PrivateContext,\n log: T,\n) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/log.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/log.nr" }, "47": { "source": "use crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\nuse crate::constants_gen::EMPTY_NULLIFIED_COMMITMENT;\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n broadcast: bool,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialize = note_interface.serialize;\n let preimage = serialize(*note);\n assert(notify_created_note(storage_slot, preimage, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n let broadcast = note_interface.broadcast;\n broadcast(context, storage_slot, *note);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(\n context: &mut PrivateContext,\n note: Note,\n note_interface: NoteInterface,\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = EMPTY_NULLIFIED_COMMITMENT;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // `nullified_commitment` is used to inform the kernel which pending commitment\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(nullifier, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr" }, "48": { "source": "use dep::std::option::Option;\nuse crate::constants_gen::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n};\nuse crate::oracle;\nuse crate::types::vec::BoundedVec;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: Note,\n) {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n let contract_address = context.this_address();\n assert(header.contract_address == contract_address);\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(\n fields: [Field; N],\n selects: BoundedVec, N>,\n) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n assert(fields[select.field_index] == select.value, \"Mismatch return note field.\");\n }\n}\n\nfn check_notes_order(fields_0: [Field; N], fields_1: [Field; N], sorts: BoundedVec, N>) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let note = get_note_internal(storage_slot, note_interface);\n\n check_note_header(*context, storage_slot, note_interface, note);\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let opt_notes = get_notes_internal(storage_slot, note_interface, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let serialize = note_interface.serialize;\n let fields = serialize(note);\n check_note_header(*context, storage_slot, note_interface, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n };\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n 0,\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n placeholder_note,\n placeholder_fields,\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteViewerOptions,\n) -> [Option; MAX_NOTES_PER_PAGE] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>,\n) -> (u8, [u8; N], [Field; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n num_selects += 1;\n };\n };\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n };\n\n (num_selects, select_by, select_values, sort_by, sort_order)\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_getter.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_getter.nr" }, "50": { "source": "use crate::hash::pedersen_hash;\nuse crate::constants_gen::{GENERATOR_INDEX__UNIQUE_COMMITMENT, GENERATOR_INDEX__SILOED_COMMITMENT};\n\npub fn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([storage_slot, note_hash], 0)\n}\n\npub fn compute_siloed_hash(contract_address: Field, inner_note_hash: Field) -> Field {\n let inputs = [contract_address, inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)\n}\n\npub fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_hash.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_hash.nr" }, "54": { "source": "use crate::note::{\n note_hash::{compute_inner_hash, compute_siloed_hash, compute_unique_hash},\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\npub fn compute_inner_note_hash(\n note_interface: NoteInterface,\n note: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n\n compute_inner_hash(header.storage_slot, note_hash)\n}\n\npub fn compute_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let inner_note_hash = compute_inner_note_hash(note_interface, note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\npub fn compute_unique_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let siloed_note_hash = compute_siloed_note_hash(note_interface, note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_note_hash_for_read_or_nullify(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note_interface, note_with_header)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note_interface, note_with_header)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note_interface, note_with_header)\n }\n\n}\n\npub fn compute_note_hash_and_nullifier(\n note_interface: NoteInterface,\n note_header: NoteHeader,\n preimage: [Field; S],\n) -> [Field; 4] {\n let deserialize = note_interface.deserialize;\n let set_header = note_interface.set_header;\n let mut note = deserialize(arr_copy_slice(preimage, [0; N], 0));\n set_header(&mut note, note_header);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n let inner_note_hash = compute_inner_hash(note_header.storage_slot, note_hash);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let compute_nullifier = note_interface.compute_nullifier;\n let inner_nullifier = compute_nullifier(note);\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/utils.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/note/utils.nr" }, "56": { "source": "#[oracle(packArguments)]\nfn pack_arguments_oracle(_args: [Field; N]) -> Field {}\n\n// TODO: explain what this does.\nunconstrained pub fn pack_arguments(args: [Field; N]) -> Field {\n pack_arguments_oracle(args)\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/arguments.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/arguments.nr" }, "57": { "source": "use crate::constants_gen::CALL_PRIVATE_FUNCTION_RETURN_SIZE;\n\n#[oracle(callPrivateFunction)]\nfn call_private_function_oracle(\n _contract_address: Field,\n _function_selector: Field,\n _args_hash: Field\n) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {}\n\nunconstrained pub fn call_private_function_internal(\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {\n call_private_function_oracle(\n contract_address,\n function_selector,\n args_hash,\n )\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr" }, "61": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: Field) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr" }, "62": { "source": "use crate::oracle::get_public_key::get_public_key;\nuse crate::types::point::Point;\n\n#[oracle(getSecretKey)]\nfn get_secret_key_oracle(\n _owner: Point,\n) -> [Field; dep::std::grumpkin_scalar::GRUMPKIN_SCALAR_SERIALIZED_LEN] {\n}\n\nunconstrained fn get_secret_key_internal(owner_public_key: Point) -> dep::std::grumpkin_scalar::GrumpkinScalar {\n dep::std::grumpkin_scalar::deserialize_grumpkin_scalar(get_secret_key_oracle(owner_public_key))\n}\n\npub fn get_secret_key(owner: Field) -> dep::std::grumpkin_scalar::GrumpkinScalar {\n let owner_public_key = get_public_key(owner);\n let secret = get_secret_key_internal(owner_public_key);\n\n // Constrain the owner - Nullifier secret key is currently just the encryption private key so we can constrain\n // the owner by deriving the public key from the secret key and checking the result.\n let computed_public_key = dep::std::grumpkin_scalar_mul::grumpkin_fixed_base(secret);\n assert(owner_public_key.x == computed_public_key[0]);\n assert(owner_public_key.y == computed_public_key[1]);\n\n secret\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key.nr" }, "63": { "source": "\n\n#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/rand.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/rand.nr" }, "64": { "source": "\n// contract_address + \n// args_hash +\n// crate::abi::FUNCTION_DATA_SIZE +\n// crate::abi::CALL_CONTEXT_SIZE +\n// = 2 + 4 + 7\nglobal ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE: Field = 13;\n\n#[oracle(enqueuePublicFunctionCall)]\nfn enqueue_public_function_call_oracle(\n _contract_address: Field, \n _function_selector: Field, \n _args_hash: Field,\n) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {}\n\nunconstrained pub fn enqueue_public_function_call_internal(\n contract_address: Field, \n function_selector: Field,\n args_hash: Field\n) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {\n enqueue_public_function_call_oracle(\n contract_address, \n function_selector, \n args_hash,\n )\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr" }, "65": { "source": "use crate::constants_gen::RETURN_VALUES_LENGTH;\n\n#[oracle(callPublicFunction)]\nfn call_public_function_oracle(\n _contract_address: Field, \n _function_selector: Field, \n _args_hash: Field\n) -> [Field; RETURN_VALUES_LENGTH] {}\n\nunconstrained pub fn call_public_function_internal(\n contract_address: Field, \n function_selector: Field,\n args_hash: Field\n) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_oracle(\n contract_address, \n function_selector, \n args_hash,\n )\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/public_call.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/public_call.nr" }, "66": { "source": "use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _preimage: [Field; N],\n _inner_note_hash: Field,\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n preimage: [Field; N],\n inner_note_hash: Field,\n) -> Field {\n notify_created_note_oracle(storage_slot, preimage, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(\n _nullifier: Field,\n _inner_note_hash: Field,\n) -> Field {}\n\nunconstrained pub fn notify_nullified_note(\n nullifier: Field,\n inner_note_hash: Field,\n) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _return_size: u32,\n _placeholder_fields: [Field; S],\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n mut placeholder_fields: [Field; S],\n)-> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(storage_slot, num_selects, select_by, select_values, sort_by, sort_order, limit, offset, return_size, placeholder_fields)\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n) -> [Option; S] {\n let fields = get_notes_oracle_wrapper(storage_slot, num_selects, select_by, select_values, sort_by, sort_order, limit, offset, placeholder_fields);\n let num_notes = fields[0] as u32;\n let contract_address = fields[1];\n let deserialize = note_interface.deserialize;\n let set_header = note_interface.set_header;\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let preimage = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = deserialize(preimage);\n set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n };\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(\n _inner_nullifier: Field,\n) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/notes.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/notes.nr" }, "67": { "source": "\n#[oracle(storageRead)]\nfn storage_read_oracle(\n _storage_slot: Field,\n _number_of_elements: Field,\n) -> [Field; N] {}\n\nunconstrained fn storage_read_oracle_wrapper(_storage_slot: Field)-> [Field; N] {\n storage_read_oracle(_storage_slot, N)\n}\n\npub fn storage_read(\n storage_slot: Field,\n deserialize: fn ([Field; N]) -> T,\n) -> T {\n let fields = storage_read_oracle_wrapper(storage_slot);\n deserialize(fields)\n}\n\n#[oracle(storageWrite)]\nfn storage_write_oracle(\n _storage_slot: Field,\n _values: [Field; N],\n) -> [Field; N] {}\n\n// TODO: Remove return value.\nunconstrained pub fn storage_write(\n storage_slot: Field,\n fields: [Field; N]\n) {\n let _hash = storage_write_oracle(storage_slot, fields);\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/storage.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/storage.nr" }, "68": { "source": "use crate::types::point::Point;\nuse crate::constants_gen::NUM_FIELDS_PER_SHA256;\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: Field,\n _storage_slot: Field,\n _encryption_pub_key: Point,\n _preimage: [Field; N],\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n preimage: [Field; N],\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n encryption_pub_key,\n preimage,\n ), 0]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(_contract_address: Field, _event_selector: Field, _message: T) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(contract_address: Field, event_selector: Field, message: T) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/logs.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/logs.nr" }, "69": { "source": "use crate::abi::FunctionData;\nuse crate::abi::PrivateCircuitPublicInputs;\nuse crate::constants_gen::GENERATOR_INDEX__CALL_STACK_ITEM;\nuse crate::hash::pedersen_hash;\n\nstruct PrivateCallStackItem {\n contract_address: Field,\n function_data: FunctionData,\n public_inputs: PrivateCircuitPublicInputs,\n is_execution_request: bool,\n}\n\nimpl PrivateCallStackItem {\n pub fn hash(self) -> Field {\n pedersen_hash([\n self.contract_address,\n self.function_data.hash(),\n self.public_inputs.hash(),\n ], GENERATOR_INDEX__CALL_STACK_ITEM)\n }\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/private_call_stack_item.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/private_call_stack_item.nr" }, "70": { "source": "use crate::{\n abi,\n hash::pedersen_hash,\n abi::{\n PublicCircuitPublicInputs,\n FunctionData,\n },\n};\nuse crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n GENERATOR_INDEX__CALL_STACK_ITEM,\n};\n\n// oracles\nuse crate::oracle::{\n enqueue_public_function_call::enqueue_public_function_call_internal,\n};\n\nstruct PublicCallStackItem {\n contract_address: Field,\n function_data: FunctionData,\n public_inputs: PublicCircuitPublicInputs,\n is_execution_request: bool,\n}\n\nimpl PublicCallStackItem {\n pub fn hash(self) -> Field {\n pedersen_hash([\n self.contract_address,\n self.function_data.hash(),\n self.public_inputs.hash(),\n ], GENERATOR_INDEX__CALL_STACK_ITEM)\n }\n}\n\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/public_call_stack_item.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/public_call_stack_item.nr" }, "74": { "source": "use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse crate::hash::pedersen_hash;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n ) -> Map {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map {\n context,\n storage_slot,\n state_var_constructor,\n }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: Field) -> V {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key],0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/map.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/map.nr" }, "75": { "source": "use crate::context::{Context};\nuse crate::oracle::storage::storage_read;\nuse crate::oracle::storage::storage_write;\nuse crate::types::type_serialization::TypeSerializationInterface;\nuse dep::std::option::Option;\n\n// docs:start:public_state_struct\nstruct PublicState {\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n}\n// docs:end:public_state_struct\n\nimpl PublicState {\n // docs:start:public_state_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicState {\n context,\n storage_slot,\n serialization_methods,\n }\n }\n // docs:end:public_state_struct_new\n\n // docs:start:public_state_struct_read\n pub fn read(self) -> T {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n storage_read(self.storage_slot, self.serialization_methods.deserialize)\n }\n // docs:end:public_state_struct_read\n\n // docs:start:public_state_struct_write\n pub fn write(self, value: T) {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n let serialize = self.serialization_methods.serialize;\n let fields = serialize(value);\n storage_write(self.storage_slot, fields);\n }\n // docs:end:public_state_struct_write\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr" }, "76": { "source": "use dep::std::option::Option;\nuse crate::abi::PublicContextInputs;\nuse crate::constants_gen::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL};\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, create_note_hash_from_public, destroy_note},\n note_getter::{get_notes, view_notes},\n note_getter_options::NoteGetterOptions,\n note_header::NoteHeader,\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n};\n\n// docs:start:struct\nstruct Set {\n context: Context,\n storage_slot: Field,\n note_interface: NoteInterface,\n}\n// docs:end:struct\n\nimpl Set {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n note_interface: NoteInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Set {\n context,\n storage_slot,\n note_interface,\n }\n }\n // docs:end:new\n\n // docs:start:insert\n pub fn insert(self,\n note: &mut Note,\n broadcast: bool,\n ) {\n create_note(\n self.context.private.unwrap(),\n self.storage_slot,\n note,\n self.note_interface,\n broadcast,\n );\n }\n // docs:end:insert\n\n // docs:start:insert_from_public\n pub fn insert_from_public(self, note: &mut Note) {\n create_note_hash_from_public(\n self.context.public.unwrap(),\n self.storage_slot,\n note,\n self.note_interface,\n );\n }\n // docs:end:insert_from_public\n \n // DEPRECATED\n fn assert_contains_and_remove(_self: Self, _note: &mut Note, _nonce: Field) {\n assert(false, \"`assert_contains_and_remove` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note.\");\n }\n\n // DEPRECATED\n fn assert_contains_and_remove_publicly_created(_self: Self, _note: &mut Note) {\n assert(false, \"`assert_contains_and_remove_publicly_created` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note.\");\n }\n\n // docs:start:remove\n pub fn remove(self, note: Note) {\n let context = self.context.private.unwrap();\n let note_hash = compute_note_hash_for_read_or_nullify(self.note_interface, note);\n let has_been_read = context.read_requests.any(|r| r == note_hash);\n assert(has_been_read, \"Can only remove a note that has been read from the set.\");\n\n destroy_note(\n context,\n note,\n self.note_interface,\n );\n }\n // docs:end:remove\n\n // docs:start:get_notes\n pub fn get_notes(\n self,\n options: NoteGetterOptions,\n ) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let storage_slot = self.storage_slot;\n let opt_notes = get_notes(\n self.context.private.unwrap(),\n storage_slot,\n self.note_interface,\n options,\n );\n opt_notes\n }\n // docs:end:get_notes\n\n // docs:start:view_notes\n unconstrained pub fn view_notes(\n self,\n options: NoteViewerOptions,\n ) -> [Option; MAX_NOTES_PER_PAGE] {\n view_notes(self.storage_slot, self.note_interface, options)\n }\n // docs:end:view_notes\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/set.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/set.nr" }, "79": { "source": "struct AztecAddress {\n address: Field\n}\n\nimpl AztecAddress {\n pub fn new(address: Field) -> Self {\n Self {\n address\n }\n }\n\n pub fn eq(self: Self, other: Self) -> bool {\n self.address == other.address\n }\n\n pub fn serialize(self: Self) -> [Field; 1] {\n [self.address]\n }\n\n pub fn deserialize(fields: [Field; 1]) -> Self {\n Self {\n address: fields[0]\n }\n }\n}\n\nstruct EthereumAddress {\n address: Field\n}\n\nimpl EthereumAddress {\n pub fn new(address: Field) -> Self {\n // Check that it actually will fit. Spending a lot of constraints here :grimacing:\n let bytes = address.to_be_bytes(32);\n for i in 0..12 {\n assert(bytes[i] == 0, \"Value too large for an ethereum address\");\n }\n Self {\n address\n }\n }\n\n\n pub fn serialize(self: Self) -> [Field; 1] {\n [self.address]\n }\n\n pub fn deserialize(fields: [Field; 1]) -> Self {\n Self {\n address: fields[0]\n }\n }\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/address.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/types/address.nr" }, "81": { "source": "\nstruct BoundedVec {\n storage: [T; MaxLen],\n len: Field,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0 }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64);\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn push_array(&mut self, array: [T; Len]) {\n let newLen = self.len + array.len();\n assert(newLen as u64 <= MaxLen as u64);\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = newLen;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n\n let elem = self.storage[self.len - 1];\n self.len -= 1;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}\n\n#[test]\nfn test_vec_push_pop() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n assert(vec.len == 0);\n vec.push(2);\n assert(vec.len == 1);\n vec.push(4);\n assert(vec.len == 2);\n vec.push(6);\n assert(vec.len == 3);\n let x = vec.pop();\n assert(x == 6);\n assert(vec.len == 2);\n assert(vec.get(0) == 2);\n assert(vec.get(1) == 4);\n}\n\n#[test]\nfn test_vec_push_array() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4]);\n assert(vec.len == 2);\n assert(vec.get(0) == 2);\n assert(vec.get(1) == 4);\n}\n\n#[test(should_fail)]\nfn test_vec_get_out_of_bound() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4]);\n let _x = vec.get(2);\n}\n\n#[test(should_fail)]\nfn test_vec_get_not_declared() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2]);\n let _x = vec.get(1);\n}\n\n#[test(should_fail)]\nfn test_vec_get_uninitialized() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n let _x = vec.get(0);\n}\n\n#[test(should_fail)]\nfn test_vec_push_overflow() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push(1);\n vec.push(2);\n}\n\n#[test]\nfn test_vec_any() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4, 6]);\n assert(vec.any(|v| v == 2) == true);\n assert(vec.any(|v| v == 4) == true);\n assert(vec.any(|v| v == 6) == true);\n assert(vec.any(|v| v == 3) == false);\n}\n\n#[test]\nfn test_vec_any_not_default() {\n let default_value = 1;\n let mut vec: BoundedVec = BoundedVec::new(default_value);\n vec.push_array([2, 4]);\n assert(vec.any(|v| v == default_value) == false);\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/vec.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/types/vec.nr" }, "83": { "source": "use crate::types::type_serialization::TypeSerializationInterface;\n\nglobal BOOL_SERIALIZED_LEN: Field = 1;\n\nfn deserializeBool(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool {\n fields[0] as bool\n}\n\nfn serializeBool(value: bool) -> [Field; BOOL_SERIALIZED_LEN] {\n [value as Field]\n}\n\nglobal BoolSerializationMethods = TypeSerializationInterface {\n deserialize: deserializeBool,\n serialize: serializeBool,\n};", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization.nr" }, "86": { "source": "use crate::types::type_serialization::TypeSerializationInterface;\nuse crate::types::address::AztecAddress;\n\nglobal AZTEC_ADDRESS_SERIALIZED_LEN: Field = 1;\n\nfn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> AztecAddress {\n AztecAddress::new(fields[0])\n}\n\nfn serialize(value: AztecAddress) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [value.address]\n}\n\nglobal AztecAddressSerializationMethods = TypeSerializationInterface {\n deserialize,\n serialize,\n};", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization.nr" }, "87": { "source": "pub fn arr_copy_slice(\n src: [T; N],\n mut dst: [T; M],\n offset: Field,\n) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n\npub fn field_from_bytes(bytes: [u8; N], big_endian: bool) -> Field {\n assert(bytes.len() as u32 < 32, \"field_from_bytes: N must be less than 32\");\n let mut as_field = 0;\n let mut offset = 1;\n for i in 0..N {\n let mut index = i;\n if big_endian {\n index = N - i - 1;\n }\n as_field += (bytes[index] as Field) * offset;\n offset *= 256;\n }\n\n as_field\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/aztec/src/utils.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/aztec/src/utils.nr" }, "90": { "source": "use dep::aztec::{\n context::{PrivateContext, PublicContext, Context},\n constants_gen::{EMPTY_NULLIFIED_COMMITMENT, GENERATOR_INDEX__SIGNATURE_PAYLOAD},\n types::address::AztecAddress,\n abi::hash_args,\n hash::pedersen_hash,\n};\n\nglobal IS_VALID_SELECTOR = 0xe86ab4ff;\nglobal IS_VALID_PUBLIC_SELECTOR = 0xf3661153;\n\n// @todo #2676 Should use different generator than the payload to limit probability of collisions.\n\n// docs:start:assert_valid_authwit\n// Assert that `on_behalf_of` have authorized `message_hash` with a valid authentication witness\npub fn assert_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress, message_hash: Field) {\n let result = context.call_private_function(on_behalf_of.address, IS_VALID_SELECTOR, [message_hash])[0];\n context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT);\n assert(result == IS_VALID_SELECTOR, \"Message not authorized by account\");\n}\n// docs:end:assert_valid_authwit\n\n// docs:start:assert_current_call_valid_authwit\n// Assert that `on_behalf_of` have authorized the current call with a valid authentication witness\npub fn assert_current_call_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress) {\n // message_hash = H(caller, contract_this, selector, args_hash)\n let message_hash = pedersen_hash(\n [context.msg_sender(), context.this_address(), context.selector(), context.args_hash],\n GENERATOR_INDEX__SIGNATURE_PAYLOAD\n );\n assert_valid_authwit(context, on_behalf_of, message_hash);\n}\n// docs:end:assert_current_call_valid_authwit\n\n// docs:start:assert_valid_authwit_public\n// Assert that `on_behalf_of` have authorized `message_hash` in a public context\npub fn assert_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress, message_hash: Field) {\n let result = context.call_public_function(on_behalf_of.address, IS_VALID_PUBLIC_SELECTOR, [message_hash])[0];\n context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT);\n assert(result == IS_VALID_SELECTOR, \"Message not authorized by account\");\n}\n// docs:end:assert_valid_authwit_public\n\n// docs:start:assert_current_call_valid_authwit_public\n// Assert that `on_behalf_of` have authorized the current call in a public context\npub fn assert_current_call_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress) {\n // message_hash = H(caller, contract_this, selector, args_hash)\n let message_hash = pedersen_hash(\n [context.msg_sender(), context.this_address(), context.selector(), context.args_hash],\n GENERATOR_INDEX__SIGNATURE_PAYLOAD\n );\n assert_valid_authwit_public(context, on_behalf_of, message_hash);\n}\n// docs:end:assert_current_call_valid_authwit_public\n\n// docs:start:compute_authwit_message_hash\n// Compute the message hash to be used by an authentication witness \npub fn compute_authwit_message_hash(\n caller: AztecAddress, \n target: AztecAddress, \n selector: Field, \n args: [Field; N]\n) -> Field {\n let args_hash = hash_args(args);\n pedersen_hash([caller.address, target.address, selector, args_hash], GENERATOR_INDEX__SIGNATURE_PAYLOAD)\n}\n// docs:end:compute_authwit_message_hash", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/authwit/src/auth.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/authwit/src/auth.nr" }, "92": { "source": "struct SafeU120 {\n value: u120,\n}\n\nimpl SafeU120 {\n pub fn min() -> Self {\n Self {\n value: 0\n }\n }\n\n pub fn max() -> Self {\n Self {\n value: 0xffffffffffffffffffffffffffffff\n }\n }\n\n pub fn new(\n value: Field,\n ) -> Self {\n // Check that it actually will fit. Spending a lot of constraints here :grimacing:\n let bytes = value.to_be_bytes(32);\n for i in 0..17 {\n assert(bytes[i] == 0, \"Value too large for SafeU120\");\n }\n Self {\n value: value as u120\n }\n }\n\n pub fn is_zero(\n self: Self,\n ) -> bool {\n self.value == 0\n }\n\n pub fn eq(\n self: Self,\n other: Self\n ) -> bool {\n self.value == other.value\n }\n\n pub fn lt(self: Self, other: Self) -> bool {\n self.value < other.value\n }\n\n pub fn le(self: Self, other: Self) -> bool {\n self.value <= other.value\n }\n\n pub fn gt(self: Self, other: Self) -> bool {\n self.value > other.value\n }\n\n pub fn ge(self: Self, other: Self) -> bool {\n self.value >= other.value\n }\n\n pub fn sub(\n self: Self,\n b: Self,\n ) -> Self {\n assert(self.value >= b.value, \"Underflow\");\n Self {\n value: self.value - b.value\n }\n }\n\n pub fn add(\n self: Self,\n b: Self,\n ) -> Self {\n let c: u120 = self.value + b.value;\n assert(c >= self.value, \"Overflow\");\n Self {\n value: c\n }\n }\n\n pub fn mul(\n self: Self,\n b: Self,\n ) -> Self {\n let c: u120 = self.value * b.value;\n if !b.is_zero() {\n assert(c / b.value == self.value, \"Overflow\");\n }\n Self {\n value: c\n }\n }\n\n pub fn div(\n self: Self,\n b: Self,\n ) -> Self {\n assert(!b.is_zero(), \"Divide by zero\");\n Self {\n value: self.value / b.value\n }\n }\n\n pub fn mul_div(\n self: Self,\n b: Self,\n divisor: Self\n ) -> Self {\n self.mul(b).div(divisor)\n }\n\n pub fn mul_div_up(\n self: Self,\n b: Self,\n divisor: Self\n ) -> Self {\n let c = self.mul(b);\n assert(!divisor.is_zero(), \"Divide by zero\");\n let adder = ((self.value * b.value % divisor.value) as u120 > 0) as u120;\n c.div(divisor).add(Self {value: adder})\n }\n\n // todo: implement mul_div with 240 bit intermediate values.\n}\n\n#[test]\nfn test_init() {\n let a = SafeU120::new(1);\n assert(a.value == 1);\n}\n\n#[test]\nfn test_init_max() {\n let a = SafeU120::max();\n assert(a.value == 0xffffffffffffffffffffffffffffff);\n}\n\n#[test]\nfn test_init_min() {\n let a = SafeU120::min();\n assert(a.value == 0);\n}\n\n#[test]\nfn test_is_zero() {\n let a = SafeU120::min();\n assert(a.value == 0);\n assert(a.is_zero() == true);\n}\n\n#[test]\nfn test_eq() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(1);\n assert(a.eq(b));\n}\n\n#[test]\nfn test_lt() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n assert(a.lt(b));\n assert(b.lt(a) == false);\n}\n\n\n#[test]\nfn test_le() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(2);\n let c = SafeU120::new(5);\n assert(a.le(b));\n assert(a.le(c));\n assert(c.le(a) == false);\n}\n\n#[test]\nfn test_gt() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n assert(b.gt(a));\n assert(a.gt(b) == false);\n}\n\n\n#[test]\nfn test_ge() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(2);\n let c = SafeU120::new(5);\n assert(a.ge(b));\n assert(a.ge(c) == false);\n assert(c.ge(a));\n}\n\n#[test(should_fail)]\nfn test_init_too_large() {\n let b = SafeU120::max().value as Field + 1; // max + 1\n let _a = SafeU120::new(b);\n}\n\n#[test]\nfn test_add() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n let c = SafeU120::add(a, b);\n assert(c.value == 3);\n}\n\n#[test(should_fail)]\nfn test_add_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(1);\n let _c = SafeU120::add(a, b);\n}\n\n#[test]\nfn test_sub() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(1);\n let c = SafeU120::sub(a, b);\n assert(c.value == 1);\n}\n\n#[test(should_fail)]\nfn test_sub_underflow() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n let _c = SafeU120::sub(a, b);\n}\n\n#[test]\nfn test_mul() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(3);\n let c = SafeU120::mul(a, b);\n assert(c.value == 6);\n}\n\n#[test(should_fail)]\nfn test_mul_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let _c = SafeU120::mul(a, b);\n}\n\n#[test]\nfn test_div() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::div(a, b);\n assert(c.value == 2);\n}\n\n#[test(should_fail)]\nfn test_div_by_zero() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(0);\n let _c = SafeU120::div(a, b);\n}\n\n#[test]\nfn test_mul_div() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(2);\n let d = SafeU120::mul_div(a, b, c);\n assert(d.value == 9);\n}\n\n#[test(should_fail)]\nfn test_mul_div_zero_divisor() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(0);\n let _d = SafeU120::mul_div(a, b, c);\n}\n\n#[test(should_fail)]\nfn test_mul_div_ghost_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let c = SafeU120::new(4);\n let _d = SafeU120::mul_div(a, b, c);\n}\n\n#[test]\nfn test_mul_div_up_rounding() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(5);\n let d = SafeU120::mul_div_up(a, b, c);\n assert(d.value == 4);\n}\n\n#[test]\nfn test_mul_div_up_non_rounding() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(2);\n let d = SafeU120::mul_div_up(a, b, c);\n assert(d.value == 9);\n}\n\n\n#[test(should_fail)]\nfn test_mul_div_up_ghost_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let c = SafeU120::new(9);\n let _d = SafeU120::mul_div_up(a, b, c);\n}\n\n// It should not be possible for us to overflow `mul_div_up` through the adder, since that require the divisor to be 1\n// since we otherwise would not be at the max value. If divisor is 1, adder is 0.\n#[test(should_fail)]\nfn test_mul_div_up_zero_divisor() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(0);\n let _d = SafeU120::mul_div_up(a, b, c);\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/aztec-nr/safe-math/src/safe_u120.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/aztec-nr/safe-math/src/safe_u120.nr" }, "98": { "source": "// docs:start:token_types_all\nuse dep::aztec::{\n note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_siloed_note_hash,\n },\n hash::{compute_secret_hash, pedersen_hash},\n context::PrivateContext,\n};\n\nglobal TRANSPARENT_NOTE_LEN: Field = 2;\n\n// Transparent note represents a note that is created in the clear (public execution),\n// but can only be spent by those that know the preimage of the \"secret_hash\"\nstruct TransparentNote {\n amount: Field,\n secret_hash: Field,\n // the secret is just here for ease of use and won't be (de)serialized\n secret: Field,\n // header is just here to satisfy the NoteInterface\n header: NoteHeader,\n}\n\nimpl TransparentNote {\n\n // CONSTRUCTORS\n\n pub fn new(amount: Field, secret_hash: Field) -> Self {\n TransparentNote {\n amount: amount,\n secret_hash: secret_hash,\n secret: 0,\n header: NoteHeader::empty(),\n }\n }\n\n // new oracle call primitive\n // get me the secret corresponding to this hash\n pub fn new_from_secret(amount: Field, secret: Field) -> Self {\n TransparentNote {\n amount: amount,\n secret_hash: compute_secret_hash(secret),\n secret: secret,\n header: NoteHeader::empty(),\n }\n }\n\n\n // STANDARD NOTE_INTERFACE FUNCTIONS\n\n pub fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] {\n [self.amount, self.secret_hash]\n }\n\n pub fn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> Self {\n TransparentNote {\n amount: preimage[0],\n secret_hash: preimage[1],\n secret: 0,\n header: NoteHeader::empty(),\n }\n }\n\n pub fn compute_note_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n self.amount,\n self.secret_hash,\n ],0)\n }\n\n pub fn compute_nullifier(self) -> Field {\n // TODO(#1386): should use `compute_note_hash_for_read_or_nullify` once public functions inject nonce!\n let siloed_note_hash = compute_siloed_note_hash(TransparentNoteMethods, self);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([self.secret, siloed_note_hash], 0)\n }\n\n pub fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n\n // CUSTOM FUNCTIONS FOR THIS NOTE TYPE\n\n pub fn knows_secret(self, secret: Field) {\n let hash = compute_secret_hash(secret);\n assert(self.secret_hash == hash);\n }\n}\n\nfn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> TransparentNote {\n TransparentNote::deserialize(preimage)\n}\n\nfn serialize(note: TransparentNote) -> [Field; TRANSPARENT_NOTE_LEN] {\n note.serialize()\n}\n\nfn compute_note_hash(note: TransparentNote) -> Field {\n note.compute_note_hash()\n}\n\nfn compute_nullifier(note: TransparentNote) -> Field {\n note.compute_nullifier()\n}\n\nfn get_header(note: TransparentNote) -> NoteHeader {\n note.header\n}\n\nfn set_header(note: &mut TransparentNote, header: NoteHeader) {\n note.set_header(header)\n}\n\nfn broadcast(context: &mut PrivateContext, slot: Field, note: TransparentNote) {\n assert(false, \"TransparentNote does not support broadcast\");\n}\n\nglobal TransparentNoteMethods = NoteInterface {\n deserialize,\n serialize,\n compute_note_hash,\n compute_nullifier,\n get_header,\n set_header,\n broadcast,\n};\n// docs:end:token_types_all", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/transparent_note.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/transparent_note.nr" }, "99": { "source": "use dep::std::option::Option;\nuse dep::safe_math::SafeU120;\nuse dep::aztec::{\n context::Context,\n constants_gen::MAX_READ_REQUESTS_PER_CALL,\n state_vars::set::Set,\n types::address::AztecAddress,\n};\nuse dep::aztec::note::{\n note_getter::view_notes,\n note_getter_options::{NoteGetterOptions, SortOrder},\n note_viewer_options::NoteViewerOptions\n};\nuse dep::aztec::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_note_hash_for_read_or_nullify,\n};\nuse dep::aztec::oracle::{\n rand::rand,\n get_secret_key::get_secret_key,\n get_public_key::get_public_key,\n};\n\nuse crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN, TokenNoteMethods};\n\n// A set implementing standard manipulation of balances.\n// Does not require spending key, but only knowledge.\n// Spending key requirement should be enforced by the contract using this.\nstruct BalanceSet {\n context: Context,\n owner: AztecAddress,\n set: Set\n}\n\nimpl BalanceSet {\n pub fn new(context: Context, owner: AztecAddress, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n let set = Set {\n context,\n storage_slot,\n note_interface: TokenNoteMethods,\n };\n Self {\n context,\n owner,\n set,\n }\n }\n\n unconstrained pub fn balance_of(self: Self) -> SafeU120 {\n self.balance_of_with_offset(0)\n }\n\n unconstrained pub fn balance_of_with_offset(self: Self, offset: u32) -> SafeU120 {\n // Same as SafeU120::new(0), but fewer constraints because no check. \n let mut balance = SafeU120::min();\n // docs:start:view_notes\n let options = NoteViewerOptions::new().set_offset(offset);\n let opt_notes = self.set.view_notes(options);\n // docs:end:view_notes\n let len = opt_notes.len();\n for i in 0..len {\n if opt_notes[i].is_some() {\n balance = balance.add(opt_notes[i].unwrap_unchecked().amount);\n }\n }\n if (opt_notes[len - 1].is_some()) {\n balance = balance.add(self.balance_of_with_offset(offset + opt_notes.len() as u32));\n }\n\n balance\n }\n\n pub fn add(self: Self, addend: SafeU120) {\n let mut addend_note = TokenNote::new(addend, self.owner);\n\n // docs:start:insert\n self.set.insert(&mut addend_note, true);\n // docs:end:insert\n }\n\n pub fn sub(self: Self, subtrahend: SafeU120) {\n // docs:start:get_notes\n let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend);\n let maybe_notes = self.set.get_notes(options);\n // docs:end:get_notes\n\n let mut minuend: SafeU120 = SafeU120::min();\n for i in 0..maybe_notes.len() {\n if maybe_notes[i].is_some() {\n let note = maybe_notes[i].unwrap_unchecked();\n\n // Removes the note from the owner's set of notes.\n // This will call the the `compute_nullifer` function of the `token_note`\n // which require knowledge of the secret key (currently the users encryption key).\n // The contract logic must ensure that the spending key is used as well.\n // docs:start:remove\n self.set.remove(note);\n // docs:end:remove\n\n minuend = minuend.add(note.amount);\n }\n }\n\n // This is to provide a nicer error msg,\n // without it minuend-subtrahend would still catch it, but more generic error then.\n // without the == true, it includes 'minuend.ge(subtrahend)' as part of the error.\n assert(minuend.ge(subtrahend) == true, \"Balance too low\");\n\n self.add(minuend.sub(subtrahend));\n }\n}\n\npub fn filter_notes_min_sum(notes: [Option; MAX_READ_REQUESTS_PER_CALL], min_sum: SafeU120) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let mut selected = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let mut sum = SafeU120::min();\n for i in 0..notes.len() {\n if notes[i].is_some() & sum.lt(min_sum) {\n let note = notes[i].unwrap_unchecked();\n selected[i] = Option::some(note);\n sum = sum.add(note.amount);\n }\n }\n selected\n}", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balance_set.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balance_set.nr" }, "100": { "source": "use dep::aztec::context::{PrivateContext, PublicContext, Context};\nuse dep::aztec::types::address::AztecAddress;\nuse dep::std::option::Option;\nuse crate::types::balance_set::BalanceSet;\nuse dep::aztec::hash::pedersen_hash;\n\nstruct BalancesMap {\n context: Context,\n storage_slot: Field,\n}\n\nimpl BalancesMap {\n pub fn new(\n context: Context,\n storage_slot: Field,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self {\n context,\n storage_slot,\n }\n }\n\n pub fn at(self, owner: AztecAddress) -> BalanceSet {\n let derived_storage_slot = pedersen_hash([self.storage_slot, owner.address],0);\n BalanceSet::new(self.context, owner, derived_storage_slot)\n }\n}\n", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balances_map.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balances_map.nr" }, "101": { "source": "use dep::aztec::{\n note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_note_hash_for_read_or_nullify,\n },\n hash::pedersen_hash,\n context::PrivateContext,\n constants_gen::MAX_READ_REQUESTS_PER_CALL,\n state_vars::set::Set,\n log::emit_encrypted_log,\n};\nuse dep::aztec::types::address::AztecAddress;\nuse dep::aztec::oracle::{\n rand::rand,\n get_secret_key::get_secret_key,\n get_public_key::get_public_key,\n};\n\nuse dep::safe_math::SafeU120;\nuse dep::std::option::Option;\n\nglobal TOKEN_NOTE_LEN: Field = 3; // 3 plus a header.\n\nstruct TokenNote {\n // the amount of tokens in the note\n amount: SafeU120,\n // the provider of secrets for the nullifier. The owner (recipient) to ensure that the note \n // can be privately spent. When nullifier secret and encryption private key is same \n // we can simply use the owner for this one.\n owner: AztecAddress,\n // randomness of the note to hide contents.\n randomness: Field,\n // the note header (contract_address, nonce, storage_slot)\n // included in the note such that it becomes part of encrypted logs for later use.\n header: NoteHeader,\n}\n\nimpl TokenNote {\n pub fn new(amount: SafeU120, owner: AztecAddress) -> Self {\n Self {\n amount,\n owner,\n randomness: rand(),\n header: NoteHeader::empty(),\n }\n }\n\n pub fn serialize(self) -> [Field; TOKEN_NOTE_LEN] {\n [self.amount.value as Field, self.owner.address, self.randomness]\n }\n\n pub fn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> Self {\n Self {\n amount: SafeU120::new(preimage[0]),\n owner: AztecAddress::new(preimage[1]),\n randomness: preimage[2],\n header: NoteHeader::empty(),\n }\n }\n\n pub fn compute_note_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n self.amount.value as Field, \n self.owner.address as Field,\n self.randomness,\n ],0)\n }\n\n // docs:start:nullifier\n pub fn compute_nullifier(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(TokenNoteMethods, self);\n let secret = get_secret_key(self.owner.address);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n // docs:end:nullifier\n\n pub fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n // Broadcasts the note as an encrypted log on L1.\n pub fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n // We only bother inserting the note if non-empty to save funds on gas.\n if !self.amount.is_zero() {\n let encryption_pub_key = get_public_key(self.owner.address);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n encryption_pub_key,\n self.serialize(),\n );\n }\n }\n}\n\nfn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> TokenNote {\n TokenNote::deserialize(preimage)\n}\n\nfn serialize(note: TokenNote) -> [Field; TOKEN_NOTE_LEN] {\n note.serialize()\n}\n\nfn compute_note_hash(note: TokenNote) -> Field {\n note.compute_note_hash()\n}\n\nfn compute_nullifier(note: TokenNote) -> Field {\n note.compute_nullifier()\n}\n\nfn get_header(note: TokenNote) -> NoteHeader {\n note.header\n}\n\nfn set_header(note: &mut TokenNote, header: NoteHeader) {\n note.set_header(header)\n}\n\n// Broadcasts the note as an encrypted log on L1.\nfn broadcast(context: &mut PrivateContext, slot: Field, note: TokenNote) {\n note.broadcast(context, slot);\n}\n\nglobal TokenNoteMethods = NoteInterface {\n deserialize,\n serialize,\n compute_note_hash,\n compute_nullifier,\n get_header,\n set_header,\n broadcast,\n};", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/token_note.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/token_note.nr" }, "102": { "source": "use dep::aztec::types::type_serialization::TypeSerializationInterface;\nuse dep::safe_math::SafeU120;\n\nglobal SAFE_U120_SERIALIZED_LEN: Field = 1;\n\n// This is safe when reading from storage IF only correct safeu120 was written to storage\nfn deserializeU120(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 {\n SafeU120{value: fields[0] as u120}\n}\n\nfn serializeU120(value: SafeU120) -> [Field; SAFE_U120_SERIALIZED_LEN] {\n [value.value as Field]\n}\n\nglobal SafeU120SerializationMethods = TypeSerializationInterface {\n deserialize: deserializeU120,\n serialize: serializeU120,\n};", - "path": "/mnt/user-data/jan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/safe_u120_serialization.nr" + "path": "/mnt/user-data/kev/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/safe_u120_serialization.nr" } } } From b5b346e5ad8c86975df6692c1a17924fed0b5480 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 16:06:29 +0000 Subject: [PATCH 30/41] fixes --- .../pxe/src/note_processor/note_processor.test.ts | 10 +++++----- yarn-project/pxe/src/note_processor/note_processor.ts | 7 +------ 2 files changed, 6 insertions(+), 11 deletions(-) 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 b897d57023f8..ea13498b4f04 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -159,7 +159,7 @@ describe('Note Processor', () => { expect(addNotesSpy).toHaveBeenCalledTimes(1); expect(addNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ - extendedNote: expect.objectContaining({ ...ownedL1NotePayloads[0] }), + ...ownedL1NotePayloads[0], index: BigInt(firstBlockDataStartIndex + 2), }), ]); @@ -180,17 +180,17 @@ describe('Note Processor', () => { expect(addNotesSpy).toHaveBeenCalledTimes(1); expect(addNotesSpy).toHaveBeenCalledWith([ expect.objectContaining({ - extendedNote: expect.objectContaining({ ...ownedL1NotePayloads[0] }), + ...ownedL1NotePayloads[0], // Index 1 log in the 2nd tx. index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (2 - 1) + 1), }), expect.objectContaining({ - extendedNote: expect.objectContaining({ ...ownedL1NotePayloads[1] }), + ...ownedL1NotePayloads[1], // Index 0 log in the 4th tx. index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 0), }), expect.objectContaining({ - extendedNote: expect.objectContaining({ ...ownedL1NotePayloads[2] }), + ...ownedL1NotePayloads[2], // Index 2 log in the 4th tx. index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 2), }), @@ -202,7 +202,7 @@ describe('Note Processor', () => { await noteProcessor.process(blockContexts, encryptedLogsArr); }); - it('should be able to recover two note payloads containing the same note', async () => { + it('should be able to recover two note payloads with containing the same note', async () => { const note = L1NotePayload.random(); const note2 = L1NotePayload.random(); // All note payloads except one have the same contract address, storage slot, and the actual note. diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index ef1a4919dbdb..44bb4c89a92f 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -1,9 +1,4 @@ -import { - CircuitsWasm, - MAX_NEW_COMMITMENTS_PER_TX, - MAX_NEW_NULLIFIERS_PER_TX, - PublicKey -} from '@aztec/circuits.js'; +import { CircuitsWasm, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, PublicKey } from '@aztec/circuits.js'; import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/abis'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { Fr } from '@aztec/foundation/fields'; From 1e91d0df0cb3d15f8776c7d8163502668871e6d4 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 16:21:37 +0000 Subject: [PATCH 31/41] fixes --- yarn-project/aztec.js/src/index.ts | 3 ++- yarn-project/end-to-end/src/sample-dapp/index.test.mjs | 5 +++-- yarn-project/end-to-end/src/shared/browser.ts | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index f164c0663e8f..4f315d036fb7 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -13,7 +13,8 @@ export { AztecAddress, EthAddress, Point, Fr, FunctionSelector, GrumpkinScalar } export { ContractData, DeployedContract, - ExtendedContractData as ExtendedContractData, + ExtendedContractData, + ExtendedNote, FunctionCall, GrumpkinPrivateKey, L2BlockL2Logs, diff --git a/yarn-project/end-to-end/src/sample-dapp/index.test.mjs b/yarn-project/end-to-end/src/sample-dapp/index.test.mjs index ff54db4b24cb..20bb40ad4b4e 100644 --- a/yarn-project/end-to-end/src/sample-dapp/index.test.mjs +++ b/yarn-project/end-to-end/src/sample-dapp/index.test.mjs @@ -1,5 +1,5 @@ import { createSandbox } from '@aztec/aztec-sandbox'; -import { Contract, Fr, Note, computeMessageSecretHash, createAccount } from '@aztec/aztec.js'; +import { Contract, ExtendedNote, Fr, Note, computeMessageSecretHash, createAccount } from '@aztec/aztec.js'; import { TokenContractArtifact } from '@aztec/noir-contracts/artifacts'; describe('token', () => { @@ -19,7 +19,8 @@ describe('token', () => { const storageSlot = new Fr(5); const note = new Note([new Fr(initialBalance), secretHash]); - await pxe.addNote(owner.getAddress(), token.address, storageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, owner.getAddress(), token.address, storageSlot, receipt.txHash); + await pxe.addNote(extendedNote); await token.methods.redeem_shield({ address: owner.getAddress() }, initialBalance, secret).send().wait(); }, 120_000); diff --git a/yarn-project/end-to-end/src/shared/browser.ts b/yarn-project/end-to-end/src/shared/browser.ts index d5fa2d1a3c6c..95ded0f40c56 100644 --- a/yarn-project/end-to-end/src/shared/browser.ts +++ b/yarn-project/end-to-end/src/shared/browser.ts @@ -1,7 +1,6 @@ /* eslint-disable no-console */ import * as AztecJs from '@aztec/aztec.js'; import { TokenContractArtifact } from '@aztec/noir-contracts/artifacts'; -import { ExtendedNote } from '@aztec/types'; import { Server } from 'http'; import Koa from 'koa'; @@ -172,10 +171,11 @@ export const browserTestSuite = (setup: () => Server, pageLogger: AztecJs.DebugL const { GrumpkinScalar, DeployMethod, - createPXEClient: createPXEClient, + createPXEClient, getUnsafeSchnorrAccount, Contract, Fr, + ExtendedNote, Note, computeMessageSecretHash, getSandboxAccountsWallets, From 942f8610c34785e741a2999afeee0905dca61750 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 27 Oct 2023 16:47:43 +0000 Subject: [PATCH 32/41] fix --- yarn-project/end-to-end/src/sample-dapp/index.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/sample-dapp/index.mjs b/yarn-project/end-to-end/src/sample-dapp/index.mjs index 7318dd22a8c5..de98301f5816 100644 --- a/yarn-project/end-to-end/src/sample-dapp/index.mjs +++ b/yarn-project/end-to-end/src/sample-dapp/index.mjs @@ -1,4 +1,5 @@ import { + ExtendedNote, Fr, L2BlockL2Logs, Note, @@ -45,7 +46,8 @@ async function mintPrivateFunds(pxe) { const storageSlot = new Fr(5); const note = new Note([new Fr(mintAmount), secretHash]); - await pxe.addNote(owner.getAddress(), token.address, storageSlot, note, receipt.txHash); + const extendedNote = new ExtendedNote(note, owner.getAddress(), token.address, storageSlot, receipt.txHash); + await pxe.addNote(extendedNote); await token.methods.redeem_shield(owner.getAddress(), mintAmount, secret).send().wait(); From 9c9039a3d2ca8cde04f30018f0743be281e13ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Mon, 30 Oct 2023 16:04:06 +0100 Subject: [PATCH 33/41] Update yarn-project/pxe/src/database/note_dao.ts Co-authored-by: Santiago Palladino --- yarn-project/pxe/src/database/note_dao.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/pxe/src/database/note_dao.ts b/yarn-project/pxe/src/database/note_dao.ts index 25bc1eeb7945..f98df0063f3d 100644 --- a/yarn-project/pxe/src/database/note_dao.ts +++ b/yarn-project/pxe/src/database/note_dao.ts @@ -56,7 +56,7 @@ export class NoteDao { const index = toBigIntBE(reader.readBytes(32)); const publicKey = Point.fromBuffer(reader); - return new this( + return new NoteDao( note, contractAddress, storageSlot, From c90ce2894fcaa384cbc015c47de07e89865de795 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 30 Oct 2023 15:29:17 +0000 Subject: [PATCH 34/41] fixes after merge --- .../src/client/simulator.test.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/simulator.test.ts b/yarn-project/acir-simulator/src/client/simulator.test.ts index e21c118b7191..d1b5cade92ff 100644 --- a/yarn-project/acir-simulator/src/client/simulator.test.ts +++ b/yarn-project/acir-simulator/src/client/simulator.test.ts @@ -5,6 +5,7 @@ import { ABIParameterVisibility } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { TokenContractArtifact } from '@aztec/noir-contracts/artifacts'; +import { Note } from '@aztec/types'; import { MockProxy, mock } from 'jest-mock-extended'; @@ -49,19 +50,19 @@ describe('Simulator', () => { const nonce = Fr.random(); const storageSlot = Fr.random(); - const createPreimage = (amount = 123n) => [new Fr(amount), owner.toField(), Fr.random()]; + const createNote = (amount = 123n) => new Note([new Fr(amount), owner.toField(), Fr.random()]); it('should compute note hashes and nullifier', async () => { oracle.getFunctionArtifactByName.mockResolvedValue(artifact); - const preimage = createPreimage(); - const valueNoteHash = hashFields(preimage); + const note = createNote(); + const valueNoteHash = hashFields(note.items); const innerNoteHash = hashFields([storageSlot, valueNoteHash]); const siloedNoteHash = siloCommitment(circuitsWasm, contractAddress, innerNoteHash); const uniqueSiloedNoteHash = computeUniqueCommitment(circuitsWasm, nonce, siloedNoteHash); const innerNullifier = hashFields([uniqueSiloedNoteHash, ownerPk.low, ownerPk.high]); - const result = await simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, preimage); + const result = await simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note); expect(result).toEqual({ innerNoteHash, @@ -74,22 +75,22 @@ describe('Simulator', () => { it('throw if the contract does not implement "compute_note_hash_and_nullifier"', async () => { oracle.getFunctionArtifactByName.mockResolvedValue(undefined); - const preimage = createPreimage(); + const note = createNote(); await expect( - simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, preimage), + simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note), ).rejects.toThrowError(/Mandatory implementation of "compute_note_hash_and_nullifier" missing/); }); it('throw if a note has more fields than "compute_note_hash_and_nullifier" can process', async () => { - const preimage = createPreimage(); - const wrongPreimageLength = preimage.length - 1; + const note = createNote(); + const wrongPreimageLength = note.length - 1; const modifiedArtifact: FunctionArtifactWithDebugMetadata = { ...artifact, parameters: [ ...artifact.parameters.slice(0, -1), { - name: 'preimage', + name: 'note', type: { kind: 'array', length: wrongPreimageLength, @@ -104,7 +105,7 @@ describe('Simulator', () => { oracle.getFunctionArtifactByName.mockResolvedValue(modifiedArtifact); await expect( - simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, preimage), + simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, note), ).rejects.toThrowError( new RegExp(`"compute_note_hash_and_nullifier" can only handle a maximum of ${wrongPreimageLength} fields`), ); From a17e9eae7f06f6c17d195a061675d9eec6814ae9 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 30 Oct 2023 15:30:00 +0000 Subject: [PATCH 35/41] wait options check --- yarn-project/aztec.js/src/contract/sent_tx.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/yarn-project/aztec.js/src/contract/sent_tx.ts b/yarn-project/aztec.js/src/contract/sent_tx.ts index 2e617f4724fb..6ec66f8c7992 100644 --- a/yarn-project/aztec.js/src/contract/sent_tx.ts +++ b/yarn-project/aztec.js/src/contract/sent_tx.ts @@ -61,6 +61,9 @@ export class SentTx { * @returns The transaction receipt. */ public async wait(opts?: WaitOpts): Promise> { + if (opts?.getNotes && !opts.waitForNotesSync) { + throw new Error('Cannot set getNotes to true if waitForNotesSync is false'); + } const receipt = await this.waitForReceipt(opts); if (receipt.status !== TxStatus.MINED) throw new Error(`Transaction ${await this.getTxHash()} was ${receipt.status}`); From 4a8d7cbdb4a18e6dab50928e4c75a6ecb82c5ab7 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 30 Oct 2023 15:43:44 +0000 Subject: [PATCH 36/41] typos --- yarn-project/circuits.js/src/utils/serialize.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn-project/circuits.js/src/utils/serialize.ts b/yarn-project/circuits.js/src/utils/serialize.ts index c8846079e29b..c1c79ba0d304 100644 --- a/yarn-project/circuits.js/src/utils/serialize.ts +++ b/yarn-project/circuits.js/src/utils/serialize.ts @@ -1,7 +1,7 @@ /** * For serializing an array of fixed length buffers. * TODO move to foundation pkg. - * @param arr - Array of bufffers. + * @param arr - Array of buffers. * @returns The serialized buffers. */ export function serializeBufferArrayToVector(arr: Buffer[]): Buffer { @@ -29,7 +29,7 @@ type DeserializeFn = ( /** * Deserializes an array from a vector on an element-by-element basis. - * @param deserialize - A function used to deserialize each element of the vecotr. + * @param deserialize - A function used to deserialize each element of the vector. * @param vector - The vector to deserialize. * @param offset - The position in the vector to start deserializing from. * @returns Deserialized array and how many bytes we advanced by. @@ -174,7 +174,7 @@ export function serializeToBufferArray(...objs: Bufferable[]): Buffer[] { ret.push(boolToBuffer(obj)); } else if (typeof obj === 'number') { // Note: barretenberg assumes everything is big-endian - ret.push(numToUInt32BE(obj)); // TODO: Are we always passsing numbers as UInt32? + ret.push(numToUInt32BE(obj)); // TODO: Are we always passing numbers as UInt32? } else if (typeof obj === 'string') { ret.push(numToUInt32BE(obj.length)); ret.push(Buffer.from(obj)); From 9abab92c6933076a7759a225ba484f66369b28ec Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 30 Oct 2023 15:44:01 +0000 Subject: [PATCH 37/41] updated NoteDao.getSize --- yarn-project/pxe/src/database/note_dao.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/yarn-project/pxe/src/database/note_dao.ts b/yarn-project/pxe/src/database/note_dao.ts index f98df0063f3d..9155e16536a9 100644 --- a/yarn-project/pxe/src/database/note_dao.ts +++ b/yarn-project/pxe/src/database/note_dao.ts @@ -83,9 +83,8 @@ export class NoteDao { * @returns - Its size in bytes. */ public getSize() { - // TODO: update - // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer const indexSize = Math.ceil(Math.log2(Number(this.index))); - return this.note.items.length * Fr.SIZE_IN_BYTES + 7 * Fr.SIZE_IN_BYTES + 4 + indexSize; + const noteSize = 4 + this.note.items.length * Fr.SIZE_IN_BYTES; + return noteSize + AztecAddress.SIZE_IN_BYTES + Fr.SIZE_IN_BYTES * 4 + TxHash.SIZE + Point.SIZE_IN_BYTES + indexSize; } } From a0663a40001ff2ba9f32dda7145b60839749b53f Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 30 Oct 2023 15:45:52 +0000 Subject: [PATCH 38/41] formatting fix --- yarn-project/acir-simulator/src/client/simulator.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 156b0f939b5d..092fa49b7359 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -155,12 +155,7 @@ export class AcirSimulator { * @param note - The note. * @returns The nullifier. */ - public async computeNoteHashAndNullifier( - contractAddress: AztecAddress, - nonce: Fr, - storageSlot: Fr, - note: Note, - ) { + public async computeNoteHashAndNullifier(contractAddress: AztecAddress, nonce: Fr, storageSlot: Fr, note: Note) { const artifact: FunctionArtifactWithDebugMetadata | undefined = await this.db.getFunctionArtifactByName( contractAddress, 'compute_note_hash_and_nullifier', From 14f3a6dced020fef3e9e3823abb9350461a7d1ee Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 30 Oct 2023 15:51:23 +0000 Subject: [PATCH 39/41] fix addPendingShieldNoteToPXE --- yarn-project/boxes/token/src/tests/token.contract.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/boxes/token/src/tests/token.contract.test.ts b/yarn-project/boxes/token/src/tests/token.contract.test.ts index 0f8b57e7ae54..27d8bb5fef89 100644 --- a/yarn-project/boxes/token/src/tests/token.contract.test.ts +++ b/yarn-project/boxes/token/src/tests/token.contract.test.ts @@ -44,7 +44,7 @@ describe('e2e_token_contract', () => { const addPendingShieldNoteToPXE = async (accountIndex: number, amount: bigint, secretHash: Fr, txHash: TxHash) => { const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. const note = new Note([new Fr(amount), secretHash]); - const extendedNote = new ExtendedNote(note, accounts[0].address, asset.address, storageSlot, txHash); + const extendedNote = new ExtendedNote(note, accounts[accountIndex].address, asset.address, storageSlot, txHash); await wallets[accountIndex].addNote(extendedNote); }; From 5ebb99c9ce988d8fe80854516641892e9684a3f2 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 30 Oct 2023 16:17:59 +0000 Subject: [PATCH 40/41] fix --- yarn-project/aztec.js/src/contract/sent_tx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/aztec.js/src/contract/sent_tx.ts b/yarn-project/aztec.js/src/contract/sent_tx.ts index 6ec66f8c7992..5b84b1cd660c 100644 --- a/yarn-project/aztec.js/src/contract/sent_tx.ts +++ b/yarn-project/aztec.js/src/contract/sent_tx.ts @@ -61,7 +61,7 @@ export class SentTx { * @returns The transaction receipt. */ public async wait(opts?: WaitOpts): Promise> { - if (opts?.getNotes && !opts.waitForNotesSync) { + if (opts?.getNotes && opts.waitForNotesSync === false) { throw new Error('Cannot set getNotes to true if waitForNotesSync is false'); } const receipt = await this.waitForReceipt(opts); From c68f24ddbfaea282b851d15389ecd77506ee7485 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 30 Oct 2023 16:18:54 +0000 Subject: [PATCH 41/41] fix --- yarn-project/end-to-end/src/e2e_token_contract.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/e2e_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_token_contract.test.ts index 4841032d3e6b..0d072e489691 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract.test.ts @@ -33,7 +33,7 @@ describe('e2e_token_contract', () => { const addPendingShieldNoteToPXE = async (accountIndex: number, amount: bigint, secretHash: Fr, txHash: TxHash) => { const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. const note = new Note([new Fr(amount), secretHash]); - const extendedNote = new ExtendedNote(note, accounts[0].address, asset.address, storageSlot, txHash); + const extendedNote = new ExtendedNote(note, accounts[accountIndex].address, asset.address, storageSlot, txHash); await wallets[accountIndex].addNote(extendedNote); };