From de6e69f8fad51e9823ff3772986f624146a9dd34 Mon Sep 17 00:00:00 2001 From: Josh Crites Date: Tue, 14 Apr 2026 20:45:37 -0400 Subject: [PATCH 01/30] feat(docs): autogenerate node JSON-RPC API reference from TypeScript source Adds a generation script that parses the AztecNode and AztecNodeAdmin interfaces to produce the API reference doc, ensuring it stays in sync with the actual RPC surface. Fixes missing endpoints (getCheckpointedBlockNumber, getCheckpointsDataForEpoch, etc.) and removes stale methods. --- .../operators/reference/node-api-reference.md | 692 ++++++++------ .../operators/reference/node-api-reference.md | 672 ++++++++------ docs/package.json | 1 + .../generate_node_api_reference.sh | 70 ++ .../generate_node_api_reference.ts | 852 ++++++++++++++++++ 5 files changed, 1772 insertions(+), 515 deletions(-) create mode 100755 docs/scripts/node_api_reference_generation/generate_node_api_reference.sh create mode 100644 docs/scripts/node_api_reference_generation/generate_node_api_reference.ts diff --git a/docs/docs-operate/operators/reference/node-api-reference.md b/docs/docs-operate/operators/reference/node-api-reference.md index f1218e4f3698..d2a6e90e3313 100644 --- a/docs/docs-operate/operators/reference/node-api-reference.md +++ b/docs/docs-operate/operators/reference/node-api-reference.md @@ -3,9 +3,12 @@ id: node_api_reference displayed_sidebar: operatorsSidebar title: Node JSON RPC API reference description: Complete reference for the Aztec Node JSON RPC API, including block queries, transaction submission, world state access, and administrative operations. -references: ["yarn-project/stdlib/src/interfaces/aztec-node.ts"] +references: ["yarn-project/stdlib/src/interfaces/aztec-node.ts", "yarn-project/stdlib/src/interfaces/aztec-node-admin.ts"] --- + + + This document provides a complete reference for the Aztec Node JSON RPC API. All methods are exposed via JSON RPC on the node's configured ports. ## API endpoint @@ -22,11 +25,11 @@ All methods use standard JSON RPC 2.0 format with methods prefixed by `node_` or ### node_getBlockNumber -Returns the latest block number synchronized by the node. +Method to fetch the latest block number synchronized by the node. **Parameters**: None -**Returns**: `number` +**Returns**: `number` - The block number. **Example**: @@ -38,11 +41,11 @@ curl -X POST http://localhost:8080 \ ### node_getProvenBlockNumber -Returns the latest proven block number. +Fetches the latest proven block number. **Parameters**: None -**Returns**: `number` +**Returns**: `number` - The block number. **Example**: @@ -52,401 +55,477 @@ curl -X POST http://localhost:8080 \ -d '{"jsonrpc":"2.0","method":"node_getProvenBlockNumber","params":[],"id":1}' ``` +### node_getCheckpointedBlockNumber + +Fetches the latest checkpointed block number. + +**Parameters**: None + +**Returns**: `number` - The block number. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getCheckpointedBlockNumber","params":[],"id":1}' +``` + +### node_getCheckpointNumber + +Method to fetch the latest checkpoint number synchronized by the node. + +**Parameters**: None + +**Returns**: `number` - The checkpoint number. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getCheckpointNumber","params":[],"id":1}' +``` + ### node_getL2Tips -Returns the tips of the L2 chain (latest, pending, proven). +Returns the tips of the L2 chain. **Parameters**: None -**Returns**: Object containing `latest`, `pending`, and `proven` block info +**Returns**: `L2Tips` **Example**: ```bash -curl -s -X POST http://localhost:8080 \ +curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getL2Tips","params":[],"id":67}' \ - | jq -r ".result.proven.number" + -d '{"jsonrpc":"2.0","method":"node_getL2Tips","params":[],"id":1}' ``` ### node_getBlock -Gets a block by its number. +Get a block specified by its block number or 'latest'. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number or "latest" +1. `blockParameter` - `number | "latest"` - The block parameter (block number, block hash, or 'latest'). -**Returns**: `L2Block | null` +**Returns**: `L2Block` - The requested block. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getBlock","params":[12345],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlock","params":["latest"],"id":1}' ``` -### node_getBlocks +### node_getBlockByHash -Gets multiple blocks in a range. +Get a block specified by its hash. **Parameters**: -1. `from` - `number` - Starting block number (≥ 1) -2. `limit` - `number` - Max blocks to return (1-100) +1. `blockHash` - `BlockHash` - The block hash being requested. -**Returns**: `L2Block[]` +**Returns**: `L2Block` - The requested block. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getBlocks","params":[100,50],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockByHash","params":["0x1234..."],"id":1}' ``` -### node_getBlockHeader +### node_getBlockByArchive -Gets a block header. +Get a block specified by its archive root. **Parameters**: -1. `blockNumber` - `number | "latest" | undefined` - Block number or omit for latest +1. `archive` - `Fr` - The archive root being requested. -**Returns**: `BlockHeader | null` +**Returns**: `L2Block` - The requested block. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getBlockHeader","params":["latest"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockByArchive","params":["0x1234..."],"id":1}' ``` -## Transaction operations - -### node_sendTx +### node_getBlocks -Submits a transaction to the P2P mempool. +Method to request blocks. Will attempt to return all requested blocks but will return only those available. **Parameters**: -1. `tx` - `Tx` - The transaction object +1. `from` - `number` - The start of the range of blocks to return. +2. `limit` - `number` - The maximum number of blocks to return. -**Returns**: `void` +**Returns**: `L2Block[]` - The blocks requested. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_sendTx","params":[{"data":"0x..."}],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlocks","params":[12345,12345],"id":1}' ``` -### node_getTxReceipt +### node_getBlockHeader -Gets a transaction receipt. +Returns the block header for a given block number, block hash, or 'latest'. **Parameters**: -1. `txHash` - `string` - Transaction hash (32-byte hex) +1. `block` - `number | "latest" | undefined` - The block parameter (block number, block hash, or 'latest'). Defaults to 'latest'. -**Returns**: `TxReceipt` - Receipt with status (mined, pending, or dropped) +**Returns**: `BlockHeader` - The requested block header. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getTxReceipt","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockHeader","params":["latest"],"id":1}' ``` -### node_getTxEffect +### node_getBlockHeaderByArchive -Gets the transaction effect for a given transaction. +Get a block header specified by its archive root. **Parameters**: -1. `txHash` - `string` - Transaction hash +1. `archive` - `Fr` - The archive root being requested. -**Returns**: `IndexedTxEffect | null` +**Returns**: `BlockHeader` - The requested block header. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getTxEffect","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockHeaderByArchive","params":["0x1234..."],"id":1}' ``` -### node_getTxByHash +### node_getCheckpoints -Gets a single pending transaction by hash. +Retrieves a collection of checkpoints. **Parameters**: -1. `txHash` - `string` - Transaction hash +1. `checkpointNumber` - `number` - The first checkpoint to be retrieved. +2. `limit` - `number` - The number of checkpoints to be retrieved. -**Returns**: `Tx | null` +**Returns**: `PublishedCheckpoint[]` - The collection of complete checkpoints. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getTxByHash","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getCheckpoints","params":[12345,12345],"id":1}' ``` -### node_getPendingTxs - -Gets pending transactions from the mempool. +### node_getCheckpointedBlocks **Parameters**: -1. `limit` - `number | undefined` - Max txs to return (1-100, default: 100) -2. `after` - `string | undefined` - Return txs after this tx hash +1. `from` - `number` +2. `limit` - `number` -**Returns**: `Tx[]` +**Returns**: `CheckpointedL2Block[]` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPendingTxs","params":[50],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getCheckpointedBlocks","params":[12345,12345],"id":1}' ``` -### node_getPendingTxCount +### node_getCheckpointsDataForEpoch -Gets the count of pending transactions. +Gets lightweight checkpoint metadata for a given epoch, without fetching full block data. -**Parameters**: None +**Parameters**: + +1. `epochNumber` - `number` - Epoch for which we want checkpoint data -**Returns**: `number` +**Returns**: `CheckpointData[]` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPendingTxCount","params":[],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getCheckpointsDataForEpoch","params":[12345],"id":1}' ``` -### node_isValidTx +## Transaction operations + +### node_sendTx -Validates a transaction for correctness. +Method to submit a transaction to the p2p pool. **Parameters**: -1. `tx` - `Tx` - Transaction to validate -2. `options` - `object | undefined` - Options: `isSimulation`, `skipFeeEnforcement` +1. `tx` - `Tx` - The transaction to be submitted. -**Returns**: `TxValidationResult` +**Returns**: `void` - Nothing. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_isValidTx","params":[{"data":"0x..."},{"isSimulation":true}],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_sendTx","params":[{"data":"0x..."}],"id":1}' ``` -### node_simulatePublicCalls +### node_getTxReceipt -Simulates the public part of a transaction. +Fetches a transaction receipt for a given transaction hash. Returns a mined receipt if it was added +to the chain, a pending receipt if it's still in the mempool of the connected Aztec node, or a dropped +receipt if not found in the connected Aztec node. **Parameters**: -1. `tx` - `Tx` - Transaction to simulate -2. `skipFeeEnforcement` - `boolean | undefined` - Skip fee enforcement +1. `txHash` - `TxHash` - The transaction hash. -**Returns**: `PublicSimulationOutput` +**Returns**: `TxReceipt` - A receipt of the transaction. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_simulatePublicCalls","params":[{"data":"0x..."},false],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getTxReceipt","params":["0x1234..."],"id":1}' ``` -## State queries - -### node_getPublicStorageAt +### node_getTxEffect -Gets public storage value at a contract slot. +Gets a tx effect. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `contract` - `string` - Contract address (32-byte hex) -3. `slot` - `string` - Storage slot (32-byte hex) +1. `txHash` - `TxHash` - The hash of the tx corresponding to the tx effect. -**Returns**: `string` - Storage value (32-byte hex) +**Returns**: `IndexedTxEffect | undefined` - The requested tx effect with block info (or undefined if not found). **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPublicStorageAt","params":["latest","0x1234...","0x0000..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getTxEffect","params":["0x1234..."],"id":1}' ``` -### node_getWorldStateSyncStatus +### node_getTxByHash -Gets the sync status of the node's world state. +Method to retrieve a single pending tx. -**Parameters**: None +**Parameters**: -**Returns**: `WorldStateSyncStatus` +1. `txHash` - `TxHash` - The transaction hash to return. + +**Returns**: `Tx` - The pending tx if it exists. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getWorldStateSyncStatus","params":[],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getTxByHash","params":["0x1234..."],"id":1}' ``` -## Merkle tree queries +### node_getTxsByHash -### node_findLeavesIndexes +Method to retrieve multiple pending txs. -Finds indexes of leaves in a merkle tree. +**Parameters**: + +1. `txHashes` - `TxHash[]` + +**Returns**: `Tx[]` - The pending txs if exist. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getTxsByHash","params":[["0x1234..."]],"id":1}' +``` + +### node_getPendingTxs + +Method to retrieve pending txs. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `treeId` - `number` - Tree ID (0-6) -3. `leafValues` - `string[]` - Leaf values (max 1000, 32-byte hex each) +1. `limit` - `number | undefined` +2. `after` - `TxHash | undefined` + +**Returns**: `Tx[]` - The pending txs. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getPendingTxs","params":[12345,"0x1234..."],"id":1}' +``` + +### node_getPendingTxCount -**Tree IDs**: +Retrieves the number of pending txs -- `0` - NULLIFIER_TREE -- `1` - NOTE_HASH_TREE -- `2` - PUBLIC_DATA_TREE -- `3` - L1_TO_L2_MESSAGE_TREE -- `4` - ARCHIVE -- `5` - BLOCKS_TREE +**Parameters**: None -**Returns**: Array of leaf indexes with block metadata +**Returns**: `number` - The number of pending txs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_findLeavesIndexes","params":["latest",1,["0x1234...","0x5678..."]],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPendingTxCount","params":[],"id":1}' ``` -### node_getNullifierSiblingPath +### node_isValidTx -Gets sibling path for a nullifier tree leaf. +Returns true if the transaction is valid for inclusion at the current state. Valid transactions can be +made invalid by *other* transactions if e.g. they emit the same nullifiers, or come become invalid +due to e.g. the expiration_timestamp property. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `leafIndex` - `string` - Leaf index (bigint as string) +1. `tx` - `Tx` - The transaction to validate for correctness. +2. `options` - `object | undefined` -**Returns**: `string[]` - Sibling path +**Returns**: `TxValidationResult` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getNullifierSiblingPath","params":[12345,"100"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_isValidTx","params":[{"data":"0x..."},{}],"id":1}' ``` -### node_getNoteHashSiblingPath +### node_simulatePublicCalls -Gets sibling path for a note hash tree leaf. +Simulates the public part of a transaction with the current state. +This currently just checks that the transaction execution succeeds. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `leafIndex` - `string` - Leaf index (bigint as string) +1. `tx` - `Tx` - The transaction to simulate. +2. `skipFeeEnforcement` - `boolean | undefined` -**Returns**: `string[]` - Sibling path +**Returns**: `PublicSimulationOutput` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getNoteHashSiblingPath","params":["latest","100"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_simulatePublicCalls","params":[{"data":"0x..."},true],"id":1}' ``` -### node_getArchiveSiblingPath +## State queries + +### node_getPublicStorageAt -Gets sibling path for an archive tree leaf. +Gets the storage value at the given contract storage slot. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `leafIndex` - `string` - Leaf index (bigint as string) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `contract` - `AztecAddress` - Address of the contract to query. +3. `slot` - `Fr` - Slot to query. -**Returns**: `string[]` - Sibling path +**Returns**: `Fr` - Storage value at the given contract slot. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getArchiveSiblingPath","params":[12345,"50"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPublicStorageAt","params":["latest","0x1234...","0x1234..."],"id":1}' ``` -### node_getPublicDataSiblingPath - -Gets sibling path for a public data tree leaf. +### node_getWorldStateSyncStatus -**Parameters**: +Returns the sync status of the node's world state -1. `blockNumber` - `number | "latest"` - Block number -2. `leafIndex` - `string` - Leaf index (bigint as string) +**Parameters**: None -**Returns**: `string[]` - Sibling path +**Returns**: `WorldStateSyncStatus` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPublicDataSiblingPath","params":["latest","200"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getWorldStateSyncStatus","params":[],"id":1}' ``` ## Membership witnesses +### node_findLeavesIndexes + +Find the indexes of the given leaves in the given tree along with a block metadata pointing to the block in which +the leaves were inserted. + +**Parameters**: + +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `treeId` - `MerkleTreeId` - The tree to search in. +3. `leafValues` - `Fr[]` - The values to search for. + +**Returns**: `DataInBlock | undefined[]` - The indices of leaves and the block metadata of a block in which the leaves were inserted. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_findLeavesIndexes","params":["latest",1,["0x1234..."]],"id":1}' +``` + ### node_getNullifierMembershipWitness -Gets a nullifier membership witness. +Returns a nullifier membership witness for a given nullifier at a given block. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `nullifier` - `string` - Nullifier value (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `nullifier` - `Fr` - Nullifier we try to find witness for. -**Returns**: `NullifierMembershipWitness | null` +**Returns**: `NullifierMembershipWitness` - The nullifier membership witness (if found). **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getNullifierMembershipWitness","params":[12345,"0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getNullifierMembershipWitness","params":["latest","0x1234..."],"id":1}' ``` ### node_getLowNullifierMembershipWitness -Gets a low nullifier membership witness for non-inclusion proofs. +Returns a low nullifier membership witness for a given nullifier at a given block. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `nullifier` - `string` - Nullifier value (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `nullifier` - `Fr` - Nullifier we try to find the low nullifier witness for. -**Returns**: `NullifierMembershipWitness | null` +**Returns**: `NullifierMembershipWitness` - The low nullifier membership witness (if found). **Example**: @@ -458,52 +537,58 @@ curl -X POST http://localhost:8080 \ ### node_getPublicDataWitness -Gets a public data tree witness for a leaf slot. +Returns a public data tree witness for a given leaf slot at a given block. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `leafSlot` - `string` - Leaf slot (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `leafSlot` - `Fr` - The leaf slot we try to find the witness for. -**Returns**: `PublicDataWitness | null` +**Returns**: `PublicDataWitness` - The public data witness (if found). **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPublicDataWitness","params":[12345,"0x0000..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPublicDataWitness","params":["latest","0x1234..."],"id":1}' ``` ### node_getBlockHashMembershipWitness -Gets a membership witness for a block hash in the archive tree. Block hashes are the leaves of the archive tree - each time a new block is added to the chain, its block hash is appended as a new leaf. +Returns a membership witness for a given block hash in the archive tree. + +Block hashes are the leaves of the archive tree. Each time a new block is added to the chain, +its block hash is appended as a new leaf to the archive tree. This method finds the membership +witness (leaf index and sibling path) for a given block hash, which can be used to prove that +a specific block exists in the chain's history. **Parameters**: -1. `block` - `number | "latest"` - Block number at which to query the archive tree -2. `blockHash` - `string` - Block hash to find in the archive tree (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data +(which contains the root of the archive tree in which we are searching for the block hash). +2. `blockHash` - `BlockHash` - The block hash to find in the archive tree. -**Returns**: `MembershipWitness | null` +**Returns**: `MembershipWitness | undefined` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getBlockHashMembershipWitness","params":[12345,"0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockHashMembershipWitness","params":["latest","0x1234..."],"id":1}' ``` ### node_getNoteHashMembershipWitness -Gets note hash tree membership witness. +Returns a membership witness for a given note hash at a given block. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `noteHash` - `string` - Note hash value (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `noteHash` - `Fr` - The note hash we try to find the witness for. -**Returns**: `MembershipWitness | null` +**Returns**: `MembershipWitness | undefined` **Example**: @@ -517,52 +602,52 @@ curl -X POST http://localhost:8080 \ ### node_getL1ToL2MessageMembershipWitness -Gets L1 to L2 message membership witness. +Returns the index and a sibling path for a leaf in the committed l1 to l2 data tree. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `l1ToL2Message` - `string` - L1 to L2 message (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `l1ToL2Message` - `Fr` - The l1ToL2Message to get the index / sibling path for. -**Returns**: `[string, string[]] | null` - Tuple of [index, sibling path] +**Returns**: `[bigint, SiblingPath] | undefined` - A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found). **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getL1ToL2MessageMembershipWitness","params":[12345,"0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getL1ToL2MessageMembershipWitness","params":["latest","0x1234..."],"id":1}' ``` -### node_getL1ToL2MessageBlock +### node_getL1ToL2MessageCheckpoint -Gets the L2 block number when an L1 to L2 message becomes available. +Returns the L2 checkpoint number in which this L1 to L2 message becomes available, or undefined if not found. **Parameters**: -1. `l1ToL2Message` - `string` - L1 to L2 message (32-byte hex) +1. `l1ToL2Message` - `Fr` -**Returns**: `number | null` +**Returns**: `number | undefined` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getL1ToL2MessageBlock","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getL1ToL2MessageCheckpoint","params":["0x1234..."],"id":1}' ``` ### node_isL1ToL2MessageSynced -Checks if an L1 to L2 message is synced. +Returns whether an L1 to L2 message is synced by archiver. -**Parameters**: +**Deprecated**: Use `getL1ToL2MessageCheckpoint` instead. This method may return true even if the message is not ready to use. -1. `l1ToL2Message` - `string` - L1 to L2 message (32-byte hex) +**Parameters**: -**Returns**: `boolean` +1. `l1ToL2Message` - `Fr` - The L1 to L2 message to check. -**Deprecated**: Use `node_getL1ToL2MessageBlock` instead. +**Returns**: `boolean` - Whether the message is synced. **Example**: @@ -574,13 +659,14 @@ curl -X POST http://localhost:8080 \ ### node_getL2ToL1Messages -Gets all L2 to L1 messages in a block. +Returns all the L2 to L1 messages in an epoch. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number +1. `epoch` - `number` - The epoch at which to get the data. -**Returns**: `string[][] | null` - Array of message arrays +**Returns**: `Fr[][][][]` - A nested array of the L2 to L1 messages in each tx of each block in each checkpoint in the epoch (empty +array if the epoch is not found). **Example**: @@ -592,91 +678,104 @@ curl -X POST http://localhost:8080 \ ## Log queries -### node_getPrivateLogs +### node_getPublicLogs -Gets private logs from a block range. +Gets public logs based on the provided filter. **Parameters**: -1. `from` - `number` - Starting block (≥ 1) -2. `limit` - `number` - Number of blocks (max 1000) +1. `filter` - `LogFilter` - The filter to apply to the logs. -**Returns**: `PrivateLog[]` +**Returns**: `GetPublicLogsResponse` - The requested logs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPrivateLogs","params":[100,50],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPublicLogs","params":[{"fromBlock":100,"toBlock":200}],"id":1}' ``` -### node_getPublicLogs +### node_getContractClassLogs -Gets public logs based on filter. +Gets contract class logs based on the provided filter. **Parameters**: -1. `filter` - `LogFilter` - Filter object with `fromBlock`, `toBlock`, `contractAddress`, etc. +1. `filter` - `LogFilter` - The filter to apply to the logs. -**Returns**: `GetPublicLogsResponse` +**Returns**: `GetContractClassLogsResponse` - The requested logs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPublicLogs","params":[{"fromBlock":100,"toBlock":200}],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getContractClassLogs","params":[{"fromBlock":100,"toBlock":200}],"id":1}' ``` -### node_getContractClassLogs +### node_getPrivateLogsByTags -Gets contract class logs based on filter. +Gets private logs that match any of the `tags`. For each tag, an array of matching logs is returned. An empty +array implies no logs match that tag. **Parameters**: -1. `filter` - `LogFilter` - Filter object +1. `tags` - `SiloedTag[]` - The tags to search for. +2. `page` - `number | undefined` - The page number (0-indexed) for pagination. +3. `referenceBlock` - `BlockHash | undefined` - Optional block hash used to ensure the block still exists before logs are retrieved. +This block is expected to represent the latest block to which the client has synced (called anchor block in PXE). +If specified and the block is not found, an error is thrown. This helps detect reorgs, which could result in +undefined behavior in the client's code. -**Returns**: `GetContractClassLogsResponse` +**Returns**: `TxScopedL2Log[][]` - An array of log arrays, one per tag. Returns at most 10 logs per tag per page. If 10 logs are returned +for a tag, the caller should fetch the next page to check for more logs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getContractClassLogs","params":[{"fromBlock":100}],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPrivateLogsByTags","params":[["0x1234..."],12345,"0x1234..."],"id":1}' ``` -### node_getLogsByTags +### node_getPublicLogsByTagsFromContract -Gets logs matching specific tags. +Gets public logs that match any of the `tags` from the specified contract. For each tag, an array of matching +logs is returned. An empty array implies no logs match that tag. **Parameters**: -1. `tags` - `string[]` - Array of tags (max 1000, 32-byte hex each) -2. `logsPerTag` - `number | undefined` - Max logs per tag (1-10, default: 10) +1. `contractAddress` - `AztecAddress` - The contract address to search logs for. +2. `tags` - `Tag[]` - The tags to search for. +3. `page` - `number | undefined` - The page number (0-indexed) for pagination. +4. `referenceBlock` - `BlockHash | undefined` - Optional block hash used to ensure the block still exists before logs are retrieved. +This block is expected to represent the latest block to which the client has synced (called anchor block in PXE). +If specified and the block is not found, an error is thrown. This helps detect reorgs, which could result in +undefined behavior in the client's code. -**Returns**: `TxScopedL2Log[][]` - For each tag, array of matching logs +**Returns**: `TxScopedL2Log[][]` - An array of log arrays, one per tag. Returns at most 10 logs per tag per page. If 10 logs are returned +for a tag, the caller should fetch the next page to check for more logs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getLogsByTags","params":[["0x1234...","0x5678..."],10],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPublicLogsByTagsFromContract","params":["0x1234...",["0x1234..."],12345,"0x1234..."],"id":1}' ``` ## Contract queries ### node_getContractClass -Gets a registered contract class by ID. +Returns a registered contract class given its id. **Parameters**: -1. `id` - `string` - Contract class ID (32-byte hex) +1. `id` - `Fr` - Id of the contract class. -**Returns**: `ContractClassPublic | null` +**Returns**: `ContractClassPublic | undefined` **Example**: @@ -688,13 +787,13 @@ curl -X POST http://localhost:8080 \ ### node_getContract -Gets a deployed contract instance by address. +Returns a publicly deployed contract instance given its address. **Parameters**: -1. `address` - `string` - Contract address (32-byte hex) +1. `address` - `AztecAddress` - Address of the deployed contract. -**Returns**: `ContractInstanceWithAddress | null` +**Returns**: `ContractInstanceWithAddress | undefined` **Example**: @@ -704,15 +803,69 @@ curl -X POST http://localhost:8080 \ -d '{"jsonrpc":"2.0","method":"node_getContract","params":["0x1234..."],"id":1}' ``` +## Fee queries + +### node_getCurrentMinFees + +Method to fetch the current min fees. + +**Parameters**: None + +**Returns**: `GasFees` - The current min fees. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getCurrentMinFees","params":[],"id":1}' +``` + +### node_getPredictedMinFees + +Returns predicted min fees for the current slot and next N slots. +Each entry accounts for the L1 gas oracle transition and congestion growth based on the +given mana usage estimate. Defaults to target usage (steady state). + +**Parameters**: + +1. `manaUsage` - `ManaUsageEstimate | undefined` - Expected mana usage per checkpoint (none, target, or limit). + +**Returns**: `GasFees[]` - An array of GasFees, one per slot in the prediction window. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getPredictedMinFees","params":[1],"id":1}' +``` + +### node_getMaxPriorityFees + +Method to fetch the current max priority fee of txs in the mempool. + +**Parameters**: None + +**Returns**: `GasFees` - The current max priority fees. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getMaxPriorityFees","params":[],"id":1}' +``` + ## Node information ### node_isReady -Checks if the node is ready to accept transactions. +Method to determine if the node is ready to accept transactions. **Parameters**: None -**Returns**: `boolean` +**Returns**: `boolean` - Flag indicating the readiness for tx submission. **Example**: @@ -724,27 +877,28 @@ curl -X POST http://localhost:8080 \ ### node_getNodeInfo -Gets information about the node. +Returns the information about the server's node. Includes current Node version, compatible Noir version, +L1 chain identifier, protocol version, and L1 address of the rollup contract. **Parameters**: None -**Returns**: `NodeInfo` - Node version, protocol version, chain ID, contracts, etc. +**Returns**: `NodeInfo` - The node information. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getNodeInfo","params":[],"id":42}' + -d '{"jsonrpc":"2.0","method":"node_getNodeInfo","params":[],"id":1}' ``` ### node_getNodeVersion -Gets the node package version. +Method to fetch the version of the package. **Parameters**: None -**Returns**: `string` +**Returns**: `string` - The node package version **Example**: @@ -756,11 +910,11 @@ curl -X POST http://localhost:8080 \ ### node_getVersion -Gets the rollup protocol version. +Method to fetch the version of the rollup the node is connected to. **Parameters**: None -**Returns**: `number` +**Returns**: `number` - The rollup version. **Example**: @@ -772,11 +926,11 @@ curl -X POST http://localhost:8080 \ ### node_getChainId -Gets the L1 chain ID. +Method to fetch the chain id of the base-layer for the rollup. **Parameters**: None -**Returns**: `number` +**Returns**: `number` - The chain id. **Example**: @@ -788,11 +942,11 @@ curl -X POST http://localhost:8080 \ ### node_getL1ContractAddresses -Gets deployed L1 contract addresses. +Method to fetch the currently deployed l1 contract addresses. **Parameters**: None -**Returns**: `L1ContractAddresses` +**Returns**: `L1ContractAddresses` - The deployed contract addresses. **Example**: @@ -804,7 +958,7 @@ curl -X POST http://localhost:8080 \ ### node_getProtocolContractAddresses -Gets protocol contract addresses. +Method to fetch the protocol contract addresses. **Parameters**: None @@ -820,11 +974,11 @@ curl -X POST http://localhost:8080 \ ### node_getEncodedEnr -Gets the node's ENR for P2P discovery. +Returns the ENR of this node for peer discovery, if available. **Parameters**: None -**Returns**: `string | null` +**Returns**: `string | undefined` **Example**: @@ -834,27 +988,11 @@ curl -X POST http://localhost:8080 \ -d '{"jsonrpc":"2.0","method":"node_getEncodedEnr","params":[],"id":1}' ``` -### node_getCurrentMinFees - -Gets current min fees for transactions. - -**Parameters**: None - -**Returns**: `GasFees` - -**Example**: - -```bash -curl -X POST http://localhost:8080 \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getCurrentMinFees","params":[],"id":1}' -``` - ## Validator queries ### node_getValidatorsStats -Gets statistics for all validators. +Returns stats for validators if enabled. **Parameters**: None @@ -870,33 +1008,33 @@ curl -X POST http://localhost:8080 \ ### node_getValidatorStats -Gets statistics for a single validator. +Returns stats for a single validator if enabled. **Parameters**: -1. `validatorAddress` - `string` - Validator address (20-byte hex) -2. `fromSlot` - `string | undefined` - Starting slot (bigint as string) -3. `toSlot` - `string | undefined` - Ending slot (bigint as string) +1. `validatorAddress` - `EthAddress` +2. `fromSlot` - `SlotNumber | undefined` +3. `toSlot` - `SlotNumber | undefined` -**Returns**: `SingleValidatorStats | null` +**Returns**: `SingleValidatorStats | undefined` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getValidatorStats","params":["0x1234...","100","200"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getValidatorStats","params":["0x1234...","100","100"],"id":1}' ``` ## Debug operations ### node_registerContractFunctionSignatures -Registers contract function signatures for debugging. +Registers contract function signatures for debugging purposes. **Parameters**: -1. `functionSignatures` - `string[]` - Array of function signatures (max 100) +1. `functionSignatures` - `string[]` - An array of function signatures to register by selector. **Returns**: `void` @@ -905,16 +1043,16 @@ Registers contract function signatures for debugging. ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_registerContractFunctionSignatures","params":[["transfer(address,uint256)"]],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_registerContractFunctionSignatures","params":[["0x1234..."]],"id":1}' ``` ### node_getAllowedPublicSetup -Gets the list of allowed public setup function calls. +Returns the list of allowed public setup elements configured for this node. **Parameters**: None -**Returns**: `AllowedElement[]` +**Returns**: `AllowedElement[]` - The list of allowed elements. **Example**: @@ -948,7 +1086,7 @@ Replace `` with your container name (e.g., `aztec-node`, `aztec- ### nodeAdmin_getConfig -Gets the current node configuration. +Retrieves the configuration of this node. **Parameters**: None @@ -972,11 +1110,11 @@ docker exec -it aztec-node curl -X POST http://localhost:8880 \ ### nodeAdmin_setConfig -Updates the node configuration. +Updates the configuration of this node. **Parameters**: -1. `config` - `Partial` - Configuration updates +1. `config` - `object` - Updated configuration to be merged with the current one. **Returns**: `void` @@ -985,7 +1123,7 @@ Updates the node configuration. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_setConfig","params":[{"archiverPollingIntervalMS":1000}],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_setConfig","params":[{}],"id":1}' ``` **Example (Docker)**: @@ -993,7 +1131,7 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_setConfig","params":[{"archiverPollingIntervalMS":1000}],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_setConfig","params":[{}],"id":1}' ``` ### nodeAdmin_pauseSync @@ -1046,12 +1184,13 @@ docker exec -it aztec-node curl -X POST http://localhost:8880 \ ### nodeAdmin_rollbackTo -Rolls back the database to a target block. +Pauses syncing and rolls back the database to the target L2 block number. **Parameters**: -1. `targetBlockNumber` - `number` - Block to roll back to -2. `force` - `boolean | undefined` - Clear world state/p2p if needed +1. `targetBlockNumber` - `number` - The block number to roll back to. +2. `force` - `boolean | undefined` - If true, clears the world state db and p2p dbs if rolling back to behind the finalized block. +3. `resumeSync` - `boolean | undefined` - If true (default), resumes archiver and world state sync after rollback. **Returns**: `void` @@ -1060,7 +1199,7 @@ Rolls back the database to a target block. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12000,true],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12345,true,true],"id":1}' ``` **Example (Docker)**: @@ -1068,16 +1207,16 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12000,true],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12345,true,true],"id":1}' ``` ### nodeAdmin_startSnapshotUpload -Starts uploading a database snapshot. +Pauses syncing, creates a backup of archiver and world-state databases, and uploads them. Returns immediately. **Parameters**: -1. `location` - `string` - Upload location/URL +1. `location` - `string` - The location to upload the snapshot to. **Returns**: `void` @@ -1086,7 +1225,7 @@ Starts uploading a database snapshot. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_startSnapshotUpload","params":["gs://bucket/snapshots/"],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_startSnapshotUpload","params":["0x1234..."],"id":1}' ``` **Example (Docker)**: @@ -1094,7 +1233,7 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_startSnapshotUpload","params":["gs://bucket/snapshots/"],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_startSnapshotUpload","params":["0x1234..."],"id":1}' ``` ### nodeAdmin_getSlashPayloads @@ -1123,11 +1262,11 @@ docker exec -it aztec-node curl -X POST http://localhost:8880 \ ### nodeAdmin_getSlashOffenses -Gets all offenses for a specific round. +Returns all offenses applicable for the given round. **Parameters**: -1. `round` - `string | "all" | "current"` - Round number or "all"/"current" +1. `round` - `bigint | 'all' | 'current'` **Returns**: `Offense[]` @@ -1136,7 +1275,46 @@ Gets all offenses for a specific round. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["current"],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["0x1234..."],"id":1}' +``` + +**Example (Docker)**: + +```bash +docker exec -it aztec-node curl -X POST http://localhost:8880 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["0x1234..."],"id":1}' +``` + +### nodeAdmin_reloadKeystore + +Reloads keystore configuration from disk. + +What is updated: +- Validator attester keys +- Coinbase address per validator +- Fee recipient address per validator + +What is NOT updated (requires node restart): +- L1 publisher signers (the funded accounts that send L1 transactions) +- Prover keys +- HA signer PostgreSQL connections + +Notes: +- New validators must use a publisher key that was already configured at node + startup (or omit the publisher field to fall back to the attester key). + A validator with an unknown publisher key will cause the reload to be rejected. + +**Parameters**: None + +**Returns**: `void` + +**Example (CLI)**: + +```bash +curl -X POST http://localhost:8880 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"nodeAdmin_reloadKeystore","params":[],"id":1}' ``` **Example (Docker)**: @@ -1144,7 +1322,7 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["current"],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_reloadKeystore","params":[],"id":1}' ``` ## Next steps diff --git a/docs/network_versioned_docs/version-v2.1.11-ignition/operators/reference/node-api-reference.md b/docs/network_versioned_docs/version-v2.1.11-ignition/operators/reference/node-api-reference.md index f1218e4f3698..d68617cf4c4e 100644 --- a/docs/network_versioned_docs/version-v2.1.11-ignition/operators/reference/node-api-reference.md +++ b/docs/network_versioned_docs/version-v2.1.11-ignition/operators/reference/node-api-reference.md @@ -3,9 +3,12 @@ id: node_api_reference displayed_sidebar: operatorsSidebar title: Node JSON RPC API reference description: Complete reference for the Aztec Node JSON RPC API, including block queries, transaction submission, world state access, and administrative operations. -references: ["yarn-project/stdlib/src/interfaces/aztec-node.ts"] +references: ["yarn-project/stdlib/src/interfaces/aztec-node.ts", "yarn-project/stdlib/src/interfaces/aztec-node-admin.ts"] --- + + + This document provides a complete reference for the Aztec Node JSON RPC API. All methods are exposed via JSON RPC on the node's configured ports. ## API endpoint @@ -22,11 +25,11 @@ All methods use standard JSON RPC 2.0 format with methods prefixed by `node_` or ### node_getBlockNumber -Returns the latest block number synchronized by the node. +Method to fetch the latest block number synchronized by the node. **Parameters**: None -**Returns**: `number` +**Returns**: `number` - The block number. **Example**: @@ -38,11 +41,11 @@ curl -X POST http://localhost:8080 \ ### node_getProvenBlockNumber -Returns the latest proven block number. +Fetches the latest proven block number. **Parameters**: None -**Returns**: `number` +**Returns**: `number` - The block number. **Example**: @@ -52,401 +55,477 @@ curl -X POST http://localhost:8080 \ -d '{"jsonrpc":"2.0","method":"node_getProvenBlockNumber","params":[],"id":1}' ``` +### node_getCheckpointedBlockNumber + +Fetches the latest checkpointed block number. + +**Parameters**: None + +**Returns**: `number` - The block number. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getCheckpointedBlockNumber","params":[],"id":1}' +``` + +### node_getCheckpointNumber + +Method to fetch the latest checkpoint number synchronized by the node. + +**Parameters**: None + +**Returns**: `number` - The checkpoint number. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getCheckpointNumber","params":[],"id":1}' +``` + ### node_getL2Tips -Returns the tips of the L2 chain (latest, pending, proven). +Returns the tips of the L2 chain. **Parameters**: None -**Returns**: Object containing `latest`, `pending`, and `proven` block info +**Returns**: `L2Tips` **Example**: ```bash -curl -s -X POST http://localhost:8080 \ +curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getL2Tips","params":[],"id":67}' \ - | jq -r ".result.proven.number" + -d '{"jsonrpc":"2.0","method":"node_getL2Tips","params":[],"id":1}' ``` ### node_getBlock -Gets a block by its number. +Get a block specified by its block number or 'latest'. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number or "latest" +1. `blockParameter` - `number | "latest"` - The block parameter (block number, block hash, or 'latest'). -**Returns**: `L2Block | null` +**Returns**: `L2Block` - The requested block. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getBlock","params":[12345],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlock","params":["latest"],"id":1}' ``` -### node_getBlocks +### node_getBlockByHash -Gets multiple blocks in a range. +Get a block specified by its hash. **Parameters**: -1. `from` - `number` - Starting block number (≥ 1) -2. `limit` - `number` - Max blocks to return (1-100) +1. `blockHash` - `BlockHash` - The block hash being requested. -**Returns**: `L2Block[]` +**Returns**: `L2Block` - The requested block. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getBlocks","params":[100,50],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockByHash","params":["0x1234..."],"id":1}' ``` -### node_getBlockHeader +### node_getBlockByArchive -Gets a block header. +Get a block specified by its archive root. **Parameters**: -1. `blockNumber` - `number | "latest" | undefined` - Block number or omit for latest +1. `archive` - `Fr` - The archive root being requested. -**Returns**: `BlockHeader | null` +**Returns**: `L2Block` - The requested block. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getBlockHeader","params":["latest"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockByArchive","params":["0x1234..."],"id":1}' ``` -## Transaction operations - -### node_sendTx +### node_getBlocks -Submits a transaction to the P2P mempool. +Method to request blocks. Will attempt to return all requested blocks but will return only those available. **Parameters**: -1. `tx` - `Tx` - The transaction object +1. `from` - `number` - The start of the range of blocks to return. +2. `limit` - `number` - The maximum number of blocks to return. -**Returns**: `void` +**Returns**: `L2Block[]` - The blocks requested. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_sendTx","params":[{"data":"0x..."}],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlocks","params":[12345,12345],"id":1}' ``` -### node_getTxReceipt +### node_getBlockHeader -Gets a transaction receipt. +Returns the block header for a given block number, block hash, or 'latest'. **Parameters**: -1. `txHash` - `string` - Transaction hash (32-byte hex) +1. `block` - `number | "latest" | undefined` - The block parameter (block number, block hash, or 'latest'). Defaults to 'latest'. -**Returns**: `TxReceipt` - Receipt with status (mined, pending, or dropped) +**Returns**: `BlockHeader` - The requested block header. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getTxReceipt","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockHeader","params":["latest"],"id":1}' ``` -### node_getTxEffect +### node_getBlockHeaderByArchive -Gets the transaction effect for a given transaction. +Get a block header specified by its archive root. **Parameters**: -1. `txHash` - `string` - Transaction hash +1. `archive` - `Fr` - The archive root being requested. -**Returns**: `IndexedTxEffect | null` +**Returns**: `BlockHeader` - The requested block header. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getTxEffect","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockHeaderByArchive","params":["0x1234..."],"id":1}' ``` -### node_getTxByHash +### node_getCheckpoints -Gets a single pending transaction by hash. +Retrieves a collection of checkpoints. **Parameters**: -1. `txHash` - `string` - Transaction hash +1. `checkpointNumber` - `number` - The first checkpoint to be retrieved. +2. `limit` - `number` - The number of checkpoints to be retrieved. -**Returns**: `Tx | null` +**Returns**: `PublishedCheckpoint[]` - The collection of complete checkpoints. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getTxByHash","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getCheckpoints","params":[12345,12345],"id":1}' ``` -### node_getPendingTxs - -Gets pending transactions from the mempool. +### node_getCheckpointedBlocks **Parameters**: -1. `limit` - `number | undefined` - Max txs to return (1-100, default: 100) -2. `after` - `string | undefined` - Return txs after this tx hash +1. `from` - `number` +2. `limit` - `number` -**Returns**: `Tx[]` +**Returns**: `CheckpointedL2Block[]` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPendingTxs","params":[50],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getCheckpointedBlocks","params":[12345,12345],"id":1}' ``` -### node_getPendingTxCount +### node_getCheckpointsDataForEpoch -Gets the count of pending transactions. +Gets lightweight checkpoint metadata for a given epoch, without fetching full block data. -**Parameters**: None +**Parameters**: + +1. `epochNumber` - `number` - Epoch for which we want checkpoint data -**Returns**: `number` +**Returns**: `CheckpointData[]` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPendingTxCount","params":[],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getCheckpointsDataForEpoch","params":[12345],"id":1}' ``` -### node_isValidTx +## Transaction operations + +### node_sendTx -Validates a transaction for correctness. +Method to submit a transaction to the p2p pool. **Parameters**: -1. `tx` - `Tx` - Transaction to validate -2. `options` - `object | undefined` - Options: `isSimulation`, `skipFeeEnforcement` +1. `tx` - `Tx` - The transaction to be submitted. -**Returns**: `TxValidationResult` +**Returns**: `void` - Nothing. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_isValidTx","params":[{"data":"0x..."},{"isSimulation":true}],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_sendTx","params":[{"data":"0x..."}],"id":1}' ``` -### node_simulatePublicCalls +### node_getTxReceipt -Simulates the public part of a transaction. +Fetches a transaction receipt for a given transaction hash. Returns a mined receipt if it was added +to the chain, a pending receipt if it's still in the mempool of the connected Aztec node, or a dropped +receipt if not found in the connected Aztec node. **Parameters**: -1. `tx` - `Tx` - Transaction to simulate -2. `skipFeeEnforcement` - `boolean | undefined` - Skip fee enforcement +1. `txHash` - `TxHash` - The transaction hash. -**Returns**: `PublicSimulationOutput` +**Returns**: `TxReceipt` - A receipt of the transaction. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_simulatePublicCalls","params":[{"data":"0x..."},false],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getTxReceipt","params":["0x1234..."],"id":1}' ``` -## State queries - -### node_getPublicStorageAt +### node_getTxEffect -Gets public storage value at a contract slot. +Gets a tx effect. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `contract` - `string` - Contract address (32-byte hex) -3. `slot` - `string` - Storage slot (32-byte hex) +1. `txHash` - `TxHash` - The hash of the tx corresponding to the tx effect. -**Returns**: `string` - Storage value (32-byte hex) +**Returns**: `IndexedTxEffect | undefined` - The requested tx effect with block info (or undefined if not found). **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPublicStorageAt","params":["latest","0x1234...","0x0000..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getTxEffect","params":["0x1234..."],"id":1}' ``` -### node_getWorldStateSyncStatus +### node_getTxByHash -Gets the sync status of the node's world state. +Method to retrieve a single pending tx. -**Parameters**: None +**Parameters**: -**Returns**: `WorldStateSyncStatus` +1. `txHash` - `TxHash` - The transaction hash to return. + +**Returns**: `Tx` - The pending tx if it exists. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getWorldStateSyncStatus","params":[],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getTxByHash","params":["0x1234..."],"id":1}' ``` -## Merkle tree queries +### node_getTxsByHash -### node_findLeavesIndexes +Method to retrieve multiple pending txs. + +**Parameters**: + +1. `txHashes` - `TxHash[]` -Finds indexes of leaves in a merkle tree. +**Returns**: `Tx[]` - The pending txs if exist. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getTxsByHash","params":[["0x1234..."]],"id":1}' +``` + +### node_getPendingTxs + +Method to retrieve pending txs. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `treeId` - `number` - Tree ID (0-6) -3. `leafValues` - `string[]` - Leaf values (max 1000, 32-byte hex each) +1. `limit` - `number | undefined` +2. `after` - `TxHash | undefined` -**Tree IDs**: +**Returns**: `Tx[]` - The pending txs. -- `0` - NULLIFIER_TREE -- `1` - NOTE_HASH_TREE -- `2` - PUBLIC_DATA_TREE -- `3` - L1_TO_L2_MESSAGE_TREE -- `4` - ARCHIVE -- `5` - BLOCKS_TREE +**Example**: -**Returns**: Array of leaf indexes with block metadata +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getPendingTxs","params":[12345,"0x1234..."],"id":1}' +``` + +### node_getPendingTxCount + +Retrieves the number of pending txs + +**Parameters**: None + +**Returns**: `number` - The number of pending txs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_findLeavesIndexes","params":["latest",1,["0x1234...","0x5678..."]],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPendingTxCount","params":[],"id":1}' ``` -### node_getNullifierSiblingPath +### node_isValidTx -Gets sibling path for a nullifier tree leaf. +Returns true if the transaction is valid for inclusion at the current state. Valid transactions can be +made invalid by *other* transactions if e.g. they emit the same nullifiers, or come become invalid +due to e.g. the expiration_timestamp property. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `leafIndex` - `string` - Leaf index (bigint as string) +1. `tx` - `Tx` - The transaction to validate for correctness. +2. `options` - `object | undefined` -**Returns**: `string[]` - Sibling path +**Returns**: `TxValidationResult` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getNullifierSiblingPath","params":[12345,"100"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_isValidTx","params":[{"data":"0x..."},{}],"id":1}' ``` -### node_getNoteHashSiblingPath +### node_simulatePublicCalls -Gets sibling path for a note hash tree leaf. +Simulates the public part of a transaction with the current state. +This currently just checks that the transaction execution succeeds. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `leafIndex` - `string` - Leaf index (bigint as string) +1. `tx` - `Tx` - The transaction to simulate. +2. `skipFeeEnforcement` - `boolean | undefined` -**Returns**: `string[]` - Sibling path +**Returns**: `PublicSimulationOutput` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getNoteHashSiblingPath","params":["latest","100"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_simulatePublicCalls","params":[{"data":"0x..."},true],"id":1}' ``` -### node_getArchiveSiblingPath +## State queries -Gets sibling path for an archive tree leaf. +### node_getPublicStorageAt + +Gets the storage value at the given contract storage slot. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `leafIndex` - `string` - Leaf index (bigint as string) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `contract` - `AztecAddress` - Address of the contract to query. +3. `slot` - `Fr` - Slot to query. -**Returns**: `string[]` - Sibling path +**Returns**: `Fr` - Storage value at the given contract slot. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getArchiveSiblingPath","params":[12345,"50"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPublicStorageAt","params":["latest","0x1234...","0x1234..."],"id":1}' ``` -### node_getPublicDataSiblingPath - -Gets sibling path for a public data tree leaf. +### node_getWorldStateSyncStatus -**Parameters**: +Returns the sync status of the node's world state -1. `blockNumber` - `number | "latest"` - Block number -2. `leafIndex` - `string` - Leaf index (bigint as string) +**Parameters**: None -**Returns**: `string[]` - Sibling path +**Returns**: `WorldStateSyncStatus` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPublicDataSiblingPath","params":["latest","200"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getWorldStateSyncStatus","params":[],"id":1}' ``` ## Membership witnesses +### node_findLeavesIndexes + +Find the indexes of the given leaves in the given tree along with a block metadata pointing to the block in which +the leaves were inserted. + +**Parameters**: + +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `treeId` - `MerkleTreeId` - The tree to search in. +3. `leafValues` - `Fr[]` - The values to search for. + +**Returns**: `DataInBlock | undefined[]` - The indices of leaves and the block metadata of a block in which the leaves were inserted. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_findLeavesIndexes","params":["latest",1,["0x1234..."]],"id":1}' +``` + ### node_getNullifierMembershipWitness -Gets a nullifier membership witness. +Returns a nullifier membership witness for a given nullifier at a given block. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `nullifier` - `string` - Nullifier value (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `nullifier` - `Fr` - Nullifier we try to find witness for. -**Returns**: `NullifierMembershipWitness | null` +**Returns**: `NullifierMembershipWitness` - The nullifier membership witness (if found). **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getNullifierMembershipWitness","params":[12345,"0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getNullifierMembershipWitness","params":["latest","0x1234..."],"id":1}' ``` ### node_getLowNullifierMembershipWitness -Gets a low nullifier membership witness for non-inclusion proofs. +Returns a low nullifier membership witness for a given nullifier at a given block. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `nullifier` - `string` - Nullifier value (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `nullifier` - `Fr` - Nullifier we try to find the low nullifier witness for. -**Returns**: `NullifierMembershipWitness | null` +**Returns**: `NullifierMembershipWitness` - The low nullifier membership witness (if found). **Example**: @@ -458,52 +537,58 @@ curl -X POST http://localhost:8080 \ ### node_getPublicDataWitness -Gets a public data tree witness for a leaf slot. +Returns a public data tree witness for a given leaf slot at a given block. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `leafSlot` - `string` - Leaf slot (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `leafSlot` - `Fr` - The leaf slot we try to find the witness for. -**Returns**: `PublicDataWitness | null` +**Returns**: `PublicDataWitness` - The public data witness (if found). **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPublicDataWitness","params":[12345,"0x0000..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPublicDataWitness","params":["latest","0x1234..."],"id":1}' ``` ### node_getBlockHashMembershipWitness -Gets a membership witness for a block hash in the archive tree. Block hashes are the leaves of the archive tree - each time a new block is added to the chain, its block hash is appended as a new leaf. +Returns a membership witness for a given block hash in the archive tree. + +Block hashes are the leaves of the archive tree. Each time a new block is added to the chain, +its block hash is appended as a new leaf to the archive tree. This method finds the membership +witness (leaf index and sibling path) for a given block hash, which can be used to prove that +a specific block exists in the chain's history. **Parameters**: -1. `block` - `number | "latest"` - Block number at which to query the archive tree -2. `blockHash` - `string` - Block hash to find in the archive tree (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data +(which contains the root of the archive tree in which we are searching for the block hash). +2. `blockHash` - `BlockHash` - The block hash to find in the archive tree. -**Returns**: `MembershipWitness | null` +**Returns**: `MembershipWitness | undefined` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getBlockHashMembershipWitness","params":[12345,"0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlockHashMembershipWitness","params":["latest","0x1234..."],"id":1}' ``` ### node_getNoteHashMembershipWitness -Gets note hash tree membership witness. +Returns a membership witness for a given note hash at a given block. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `noteHash` - `string` - Note hash value (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `noteHash` - `Fr` - The note hash we try to find the witness for. -**Returns**: `MembershipWitness | null` +**Returns**: `MembershipWitness | undefined` **Example**: @@ -517,52 +602,52 @@ curl -X POST http://localhost:8080 \ ### node_getL1ToL2MessageMembershipWitness -Gets L1 to L2 message membership witness. +Returns the index and a sibling path for a leaf in the committed l1 to l2 data tree. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number -2. `l1ToL2Message` - `string` - L1 to L2 message (32-byte hex) +1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +2. `l1ToL2Message` - `Fr` - The l1ToL2Message to get the index / sibling path for. -**Returns**: `[string, string[]] | null` - Tuple of [index, sibling path] +**Returns**: `[bigint, SiblingPath] | undefined` - A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found). **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getL1ToL2MessageMembershipWitness","params":[12345,"0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getL1ToL2MessageMembershipWitness","params":["latest","0x1234..."],"id":1}' ``` -### node_getL1ToL2MessageBlock +### node_getL1ToL2MessageCheckpoint -Gets the L2 block number when an L1 to L2 message becomes available. +Returns the L2 checkpoint number in which this L1 to L2 message becomes available, or undefined if not found. **Parameters**: -1. `l1ToL2Message` - `string` - L1 to L2 message (32-byte hex) +1. `l1ToL2Message` - `Fr` -**Returns**: `number | null` +**Returns**: `number | undefined` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getL1ToL2MessageBlock","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getL1ToL2MessageCheckpoint","params":["0x1234..."],"id":1}' ``` ### node_isL1ToL2MessageSynced -Checks if an L1 to L2 message is synced. +Returns whether an L1 to L2 message is synced by archiver. -**Parameters**: +**Deprecated**: Use `getL1ToL2MessageCheckpoint` instead. This method may return true even if the message is not ready to use. -1. `l1ToL2Message` - `string` - L1 to L2 message (32-byte hex) +**Parameters**: -**Returns**: `boolean` +1. `l1ToL2Message` - `Fr` - The L1 to L2 message to check. -**Deprecated**: Use `node_getL1ToL2MessageBlock` instead. +**Returns**: `boolean` - Whether the message is synced. **Example**: @@ -574,13 +659,14 @@ curl -X POST http://localhost:8080 \ ### node_getL2ToL1Messages -Gets all L2 to L1 messages in a block. +Returns all the L2 to L1 messages in an epoch. **Parameters**: -1. `blockNumber` - `number | "latest"` - Block number +1. `epoch` - `number` - The epoch at which to get the data. -**Returns**: `string[][] | null` - Array of message arrays +**Returns**: `Fr[][][][]` - A nested array of the L2 to L1 messages in each tx of each block in each checkpoint in the epoch (empty +array if the epoch is not found). **Example**: @@ -592,91 +678,104 @@ curl -X POST http://localhost:8080 \ ## Log queries -### node_getPrivateLogs +### node_getPublicLogs -Gets private logs from a block range. +Gets public logs based on the provided filter. **Parameters**: -1. `from` - `number` - Starting block (≥ 1) -2. `limit` - `number` - Number of blocks (max 1000) +1. `filter` - `LogFilter` - The filter to apply to the logs. -**Returns**: `PrivateLog[]` +**Returns**: `GetPublicLogsResponse` - The requested logs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPrivateLogs","params":[100,50],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPublicLogs","params":[{"fromBlock":100,"toBlock":200}],"id":1}' ``` -### node_getPublicLogs +### node_getContractClassLogs -Gets public logs based on filter. +Gets contract class logs based on the provided filter. **Parameters**: -1. `filter` - `LogFilter` - Filter object with `fromBlock`, `toBlock`, `contractAddress`, etc. +1. `filter` - `LogFilter` - The filter to apply to the logs. -**Returns**: `GetPublicLogsResponse` +**Returns**: `GetContractClassLogsResponse` - The requested logs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPublicLogs","params":[{"fromBlock":100,"toBlock":200}],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getContractClassLogs","params":[{"fromBlock":100,"toBlock":200}],"id":1}' ``` -### node_getContractClassLogs +### node_getPrivateLogsByTags -Gets contract class logs based on filter. +Gets private logs that match any of the `tags`. For each tag, an array of matching logs is returned. An empty +array implies no logs match that tag. **Parameters**: -1. `filter` - `LogFilter` - Filter object +1. `tags` - `SiloedTag[]` - The tags to search for. +2. `page` - `number | undefined` - The page number (0-indexed) for pagination. +3. `referenceBlock` - `BlockHash | undefined` - Optional block hash used to ensure the block still exists before logs are retrieved. +This block is expected to represent the latest block to which the client has synced (called anchor block in PXE). +If specified and the block is not found, an error is thrown. This helps detect reorgs, which could result in +undefined behavior in the client's code. -**Returns**: `GetContractClassLogsResponse` +**Returns**: `TxScopedL2Log[][]` - An array of log arrays, one per tag. Returns at most 10 logs per tag per page. If 10 logs are returned +for a tag, the caller should fetch the next page to check for more logs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getContractClassLogs","params":[{"fromBlock":100}],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPrivateLogsByTags","params":[["0x1234..."],12345,"0x1234..."],"id":1}' ``` -### node_getLogsByTags +### node_getPublicLogsByTagsFromContract -Gets logs matching specific tags. +Gets public logs that match any of the `tags` from the specified contract. For each tag, an array of matching +logs is returned. An empty array implies no logs match that tag. **Parameters**: -1. `tags` - `string[]` - Array of tags (max 1000, 32-byte hex each) -2. `logsPerTag` - `number | undefined` - Max logs per tag (1-10, default: 10) +1. `contractAddress` - `AztecAddress` - The contract address to search logs for. +2. `tags` - `Tag[]` - The tags to search for. +3. `page` - `number | undefined` - The page number (0-indexed) for pagination. +4. `referenceBlock` - `BlockHash | undefined` - Optional block hash used to ensure the block still exists before logs are retrieved. +This block is expected to represent the latest block to which the client has synced (called anchor block in PXE). +If specified and the block is not found, an error is thrown. This helps detect reorgs, which could result in +undefined behavior in the client's code. -**Returns**: `TxScopedL2Log[][]` - For each tag, array of matching logs +**Returns**: `TxScopedL2Log[][]` - An array of log arrays, one per tag. Returns at most 10 logs per tag per page. If 10 logs are returned +for a tag, the caller should fetch the next page to check for more logs. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getLogsByTags","params":[["0x1234...","0x5678..."],10],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPublicLogsByTagsFromContract","params":["0x1234...",["0x1234..."],12345,"0x1234..."],"id":1}' ``` ## Contract queries ### node_getContractClass -Gets a registered contract class by ID. +Returns a registered contract class given its id. **Parameters**: -1. `id` - `string` - Contract class ID (32-byte hex) +1. `id` - `Fr` - Id of the contract class. -**Returns**: `ContractClassPublic | null` +**Returns**: `ContractClassPublic | undefined` **Example**: @@ -688,13 +787,13 @@ curl -X POST http://localhost:8080 \ ### node_getContract -Gets a deployed contract instance by address. +Returns a publicly deployed contract instance given its address. **Parameters**: -1. `address` - `string` - Contract address (32-byte hex) +1. `address` - `AztecAddress` - Address of the deployed contract. -**Returns**: `ContractInstanceWithAddress | null` +**Returns**: `ContractInstanceWithAddress | undefined` **Example**: @@ -704,15 +803,49 @@ curl -X POST http://localhost:8080 \ -d '{"jsonrpc":"2.0","method":"node_getContract","params":["0x1234..."],"id":1}' ``` +## Fee queries + +### node_getCurrentMinFees + +Method to fetch the current min fees. + +**Parameters**: None + +**Returns**: `GasFees` - The current min fees. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getCurrentMinFees","params":[],"id":1}' +``` + +### node_getMaxPriorityFees + +Method to fetch the current max priority fee of txs in the mempool. + +**Parameters**: None + +**Returns**: `GasFees` - The current max priority fees. + +**Example**: + +```bash +curl -X POST http://localhost:8080 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"node_getMaxPriorityFees","params":[],"id":1}' +``` + ## Node information ### node_isReady -Checks if the node is ready to accept transactions. +Method to determine if the node is ready to accept transactions. **Parameters**: None -**Returns**: `boolean` +**Returns**: `boolean` - Flag indicating the readiness for tx submission. **Example**: @@ -724,27 +857,28 @@ curl -X POST http://localhost:8080 \ ### node_getNodeInfo -Gets information about the node. +Returns the information about the server's node. Includes current Node version, compatible Noir version, +L1 chain identifier, protocol version, and L1 address of the rollup contract. **Parameters**: None -**Returns**: `NodeInfo` - Node version, protocol version, chain ID, contracts, etc. +**Returns**: `NodeInfo` - The node information. **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getNodeInfo","params":[],"id":42}' + -d '{"jsonrpc":"2.0","method":"node_getNodeInfo","params":[],"id":1}' ``` ### node_getNodeVersion -Gets the node package version. +Method to fetch the version of the package. **Parameters**: None -**Returns**: `string` +**Returns**: `string` - The node package version **Example**: @@ -756,11 +890,11 @@ curl -X POST http://localhost:8080 \ ### node_getVersion -Gets the rollup protocol version. +Method to fetch the version of the rollup the node is connected to. **Parameters**: None -**Returns**: `number` +**Returns**: `number` - The rollup version. **Example**: @@ -772,11 +906,11 @@ curl -X POST http://localhost:8080 \ ### node_getChainId -Gets the L1 chain ID. +Method to fetch the chain id of the base-layer for the rollup. **Parameters**: None -**Returns**: `number` +**Returns**: `number` - The chain id. **Example**: @@ -788,11 +922,11 @@ curl -X POST http://localhost:8080 \ ### node_getL1ContractAddresses -Gets deployed L1 contract addresses. +Method to fetch the currently deployed l1 contract addresses. **Parameters**: None -**Returns**: `L1ContractAddresses` +**Returns**: `L1ContractAddresses` - The deployed contract addresses. **Example**: @@ -804,7 +938,7 @@ curl -X POST http://localhost:8080 \ ### node_getProtocolContractAddresses -Gets protocol contract addresses. +Method to fetch the protocol contract addresses. **Parameters**: None @@ -820,11 +954,11 @@ curl -X POST http://localhost:8080 \ ### node_getEncodedEnr -Gets the node's ENR for P2P discovery. +Returns the ENR of this node for peer discovery, if available. **Parameters**: None -**Returns**: `string | null` +**Returns**: `string | undefined` **Example**: @@ -834,27 +968,11 @@ curl -X POST http://localhost:8080 \ -d '{"jsonrpc":"2.0","method":"node_getEncodedEnr","params":[],"id":1}' ``` -### node_getCurrentMinFees - -Gets current min fees for transactions. - -**Parameters**: None - -**Returns**: `GasFees` - -**Example**: - -```bash -curl -X POST http://localhost:8080 \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getCurrentMinFees","params":[],"id":1}' -``` - ## Validator queries ### node_getValidatorsStats -Gets statistics for all validators. +Returns stats for validators if enabled. **Parameters**: None @@ -870,33 +988,33 @@ curl -X POST http://localhost:8080 \ ### node_getValidatorStats -Gets statistics for a single validator. +Returns stats for a single validator if enabled. **Parameters**: -1. `validatorAddress` - `string` - Validator address (20-byte hex) -2. `fromSlot` - `string | undefined` - Starting slot (bigint as string) -3. `toSlot` - `string | undefined` - Ending slot (bigint as string) +1. `validatorAddress` - `EthAddress` +2. `fromSlot` - `SlotNumber | undefined` +3. `toSlot` - `SlotNumber | undefined` -**Returns**: `SingleValidatorStats | null` +**Returns**: `SingleValidatorStats | undefined` **Example**: ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getValidatorStats","params":["0x1234...","100","200"],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getValidatorStats","params":["0x1234...","100","100"],"id":1}' ``` ## Debug operations ### node_registerContractFunctionSignatures -Registers contract function signatures for debugging. +Registers contract function signatures for debugging purposes. **Parameters**: -1. `functionSignatures` - `string[]` - Array of function signatures (max 100) +1. `functionSignatures` - `string[]` - An array of function signatures to register by selector. **Returns**: `void` @@ -905,16 +1023,16 @@ Registers contract function signatures for debugging. ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_registerContractFunctionSignatures","params":[["transfer(address,uint256)"]],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_registerContractFunctionSignatures","params":[["0x1234..."]],"id":1}' ``` ### node_getAllowedPublicSetup -Gets the list of allowed public setup function calls. +Returns the list of allowed public setup elements configured for this node. **Parameters**: None -**Returns**: `AllowedElement[]` +**Returns**: `AllowedElement[]` - The list of allowed elements. **Example**: @@ -948,7 +1066,7 @@ Replace `` with your container name (e.g., `aztec-node`, `aztec- ### nodeAdmin_getConfig -Gets the current node configuration. +Retrieves the configuration of this node. **Parameters**: None @@ -972,11 +1090,11 @@ docker exec -it aztec-node curl -X POST http://localhost:8880 \ ### nodeAdmin_setConfig -Updates the node configuration. +Updates the configuration of this node. **Parameters**: -1. `config` - `Partial` - Configuration updates +1. `config` - `object` - Updated configuration to be merged with the current one. **Returns**: `void` @@ -985,7 +1103,7 @@ Updates the node configuration. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_setConfig","params":[{"archiverPollingIntervalMS":1000}],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_setConfig","params":[{}],"id":1}' ``` **Example (Docker)**: @@ -993,7 +1111,7 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_setConfig","params":[{"archiverPollingIntervalMS":1000}],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_setConfig","params":[{}],"id":1}' ``` ### nodeAdmin_pauseSync @@ -1046,12 +1164,11 @@ docker exec -it aztec-node curl -X POST http://localhost:8880 \ ### nodeAdmin_rollbackTo -Rolls back the database to a target block. +Pauses syncing and rolls back the database to the target L2 block number. **Parameters**: -1. `targetBlockNumber` - `number` - Block to roll back to -2. `force` - `boolean | undefined` - Clear world state/p2p if needed +1. `targetBlockNumber` - `number` - The block number to roll back to. **Returns**: `void` @@ -1060,7 +1177,7 @@ Rolls back the database to a target block. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12000,true],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12345],"id":1}' ``` **Example (Docker)**: @@ -1068,16 +1185,16 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12000,true],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12345],"id":1}' ``` ### nodeAdmin_startSnapshotUpload -Starts uploading a database snapshot. +Pauses syncing, creates a backup of archiver and world-state databases, and uploads them. Returns immediately. **Parameters**: -1. `location` - `string` - Upload location/URL +1. `location` - `string` - The location to upload the snapshot to. **Returns**: `void` @@ -1086,7 +1203,7 @@ Starts uploading a database snapshot. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_startSnapshotUpload","params":["gs://bucket/snapshots/"],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_startSnapshotUpload","params":["0x1234..."],"id":1}' ``` **Example (Docker)**: @@ -1094,12 +1211,12 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_startSnapshotUpload","params":["gs://bucket/snapshots/"],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_startSnapshotUpload","params":["0x1234..."],"id":1}' ``` ### nodeAdmin_getSlashPayloads -Gets all monitored slash payloads for the current round. +Returns all monitored payloads by the slasher for the current round. **Parameters**: None @@ -1123,11 +1240,11 @@ docker exec -it aztec-node curl -X POST http://localhost:8880 \ ### nodeAdmin_getSlashOffenses -Gets all offenses for a specific round. +Returns all offenses applicable for the given round. **Parameters**: -1. `round` - `string | "all" | "current"` - Round number or "all"/"current" +1. `round` - `bigint | 'all' | 'current'` **Returns**: `Offense[]` @@ -1136,7 +1253,46 @@ Gets all offenses for a specific round. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["current"],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["0x1234..."],"id":1}' +``` + +**Example (Docker)**: + +```bash +docker exec -it aztec-node curl -X POST http://localhost:8880 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["0x1234..."],"id":1}' +``` + +### nodeAdmin_reloadKeystore + +Reloads keystore configuration from disk. + +What is updated: +- Validator attester keys +- Coinbase address per validator +- Fee recipient address per validator + +What is NOT updated (requires node restart): +- L1 publisher signers (the funded accounts that send L1 transactions) +- Prover keys +- HA signer PostgreSQL connections + +Notes: +- New validators must use a publisher key that was already configured at node + startup (or omit the publisher field to fall back to the attester key). + A validator with an unknown publisher key will cause the reload to be rejected. + +**Parameters**: None + +**Returns**: `void` + +**Example (CLI)**: + +```bash +curl -X POST http://localhost:8880 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"nodeAdmin_reloadKeystore","params":[],"id":1}' ``` **Example (Docker)**: @@ -1144,7 +1300,7 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["current"],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_reloadKeystore","params":[],"id":1}' ``` ## Next steps diff --git a/docs/package.json b/docs/package.json index 7a5b526c1c45..e7938154c370 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,6 +10,7 @@ "dev:netlify": "yarn netlify dev", "generate:aztec-nr-api": "./scripts/aztec_nr_docs_generation/generate_aztec_nr_docs.sh", "generate:typescript-api": "./scripts/typescript_api_generation/generate_ts_api_docs.sh", + "generate:node-api-reference": "./scripts/node_api_reference_generation/generate_node_api_reference.sh", "preprocess": "yarn node -r dotenv/config ./src/preprocess/index.js", "preprocess:move": "sh scripts/move_processed.sh", "serve": "docusaurus serve", diff --git a/docs/scripts/node_api_reference_generation/generate_node_api_reference.sh b/docs/scripts/node_api_reference_generation/generate_node_api_reference.sh new file mode 100755 index 000000000000..4a8810b18435 --- /dev/null +++ b/docs/scripts/node_api_reference_generation/generate_node_api_reference.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +# Generate Node JSON-RPC API reference documentation from TypeScript source +# +# This script generates a complete markdown reference for the Aztec Node JSON-RPC API +# by parsing interface definitions and Zod schemas from yarn-project/stdlib. +# +# Usage: +# ./generate_node_api_reference.sh [--target-dir ] +# +# Examples: +# ./generate_node_api_reference.sh # Writes to docs-operate/ (source docs) +# ./generate_node_api_reference.sh --target-dir network_versioned_docs/version-v4.1.3/operators/reference + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOCS_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +YARN_PROJECT_DIR="$(cd "$DOCS_ROOT/../yarn-project" && pwd)" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +echo_info() { echo -e "${GREEN}[INFO]${NC} $1"; } +echo_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +echo_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +# Default output path +OUTPUT_DIR="$DOCS_ROOT/docs-operate/operators/reference" +OUTPUT_FILE="node-api-reference.md" + +# Parse arguments +while [[ $# -gt 0 ]]; do + case "$1" in + --target-dir) + OUTPUT_DIR="$DOCS_ROOT/$2" + shift 2 + ;; + *) + echo_error "Unknown argument: $1" + echo "Usage: $0 [--target-dir ]" + exit 1 + ;; + esac +done + +OUTPUT_PATH="$OUTPUT_DIR/$OUTPUT_FILE" + +# Verify yarn-project is built +if [[ ! -d "$YARN_PROJECT_DIR/stdlib/dest" ]]; then + echo_error "yarn-project/stdlib/dest/ not found. Run 'yarn build' from yarn-project first." + exit 1 +fi + +echo_info "Generating Node JSON-RPC API reference..." +echo_info "Source: $YARN_PROJECT_DIR/stdlib/src/interfaces/" +echo_info "Output: $OUTPUT_PATH" + +# Ensure output directory exists +mkdir -p "$OUTPUT_DIR" + +# Run the TypeScript generator from within yarn-project so node_modules resolution works +cd "$YARN_PROJECT_DIR" +npx tsx "$SCRIPT_DIR/generate_node_api_reference.ts" \ + --yarn-project "$YARN_PROJECT_DIR" \ + --output "$OUTPUT_PATH" + +echo_info "Node API reference generated successfully at $OUTPUT_PATH" diff --git a/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts b/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts new file mode 100644 index 000000000000..2138d6aebd18 --- /dev/null +++ b/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts @@ -0,0 +1,852 @@ +/** + * Generates the Node JSON-RPC API reference markdown from TypeScript source. + * + * Uses the TypeScript Compiler API to parse interface files and extract: + * - JSDoc comments (descriptions, @param, @returns) + * - Method signatures (parameter names and types) + * - Schema object keys (to enumerate all RPC-exposed methods) + * + * No runtime imports of yarn-project modules — everything is extracted from source AST. + */ +import * as ts from 'typescript'; +import * as path from 'path'; +import * as fs from 'fs'; + +// --------------------------------------------------------------------------- +// CLI argument parsing +// --------------------------------------------------------------------------- + +function parseArgs(): { yarnProject: string; output: string } { + const args = process.argv.slice(2); + let yarnProject = ''; + let output = ''; + for (let i = 0; i < args.length; i++) { + if (args[i] === '--yarn-project' && args[i + 1]) { + yarnProject = args[++i]; + } else if (args[i] === '--output' && args[i + 1]) { + output = args[++i]; + } + } + if (!yarnProject || !output) { + console.error('Usage: generate_node_api_reference.ts --yarn-project --output '); + process.exit(1); + } + return { yarnProject, output }; +} + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +interface MethodJSDoc { + description: string; + params: { name: string; description: string }[]; + returns: string; + deprecated?: string; + remarks?: string; +} + +interface MethodInfo { + name: string; + namespace: string; + jsdoc: MethodJSDoc; + paramNames: string[]; + paramTypes: string[]; + returnType: string; +} + +// --------------------------------------------------------------------------- +// JSDoc extraction via TypeScript Compiler API +// --------------------------------------------------------------------------- + +function extractJSDocComment(tag: { comment?: string | ts.NodeArray }): string { + if (!tag.comment) return ''; + if (typeof tag.comment === 'string') return tag.comment; + return tag.comment.map((part: any) => part.text || '').join(''); +} + +function extractJSDocFromNode(node: ts.Node): MethodJSDoc | undefined { + const jsDocs = (node as any).jsDoc as ts.JSDoc[] | undefined; + if (!jsDocs || jsDocs.length === 0) return undefined; + + const jsDoc = jsDocs[jsDocs.length - 1]; + const description = extractJSDocComment(jsDoc); + + const params: { name: string; description: string }[] = []; + let returns = ''; + let deprecated: string | undefined; + let remarks: string | undefined; + + if (jsDoc.tags) { + for (const tag of jsDoc.tags) { + const tagComment = extractJSDocComment(tag); + + if (ts.isJSDocParameterTag(tag)) { + const paramName = tag.name?.getText() || ''; + const paramDesc = tagComment.replace(/^\s*-\s*/, '').trim(); + params.push({ name: paramName, description: paramDesc }); + } else if (tag.tagName.text === 'returns') { + returns = tagComment.replace(/^\s*-\s*/, '').trim(); + } else if (tag.tagName.text === 'deprecated') { + deprecated = tagComment.trim() || 'This method is deprecated.'; + } else if (tag.tagName.text === 'remarks') { + remarks = tagComment.trim(); + } + } + } + + return { description: description.trim(), params, returns, deprecated, remarks }; +} + +/** Extract JSDoc and parameter names from all method signatures in all interfaces in a file. */ +function parseInterfaceFile(filePath: string): { + jsdoc: Map; + paramNames: Map; +} { + const jsdoc = new Map(); + const paramNames = new Map(); + + const sourceText = fs.readFileSync(filePath, 'utf-8'); + const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true); + + function visit(node: ts.Node) { + if (ts.isInterfaceDeclaration(node)) { + for (const member of node.members) { + const name = member.name?.getText(sourceFile); + if (!name) continue; + + const doc = extractJSDocFromNode(member); + if (doc) jsdoc.set(name, doc); + + if (ts.isMethodSignature(member) && member.parameters) { + paramNames.set(name, member.parameters.map(p => p.name.getText(sourceFile))); + } + } + } + ts.forEachChild(node, visit); + } + + visit(sourceFile); + return { jsdoc, paramNames }; +} + +// --------------------------------------------------------------------------- +// Schema AST parsing — extract method names and Zod type signatures +// --------------------------------------------------------------------------- + +/** + * Parse a schema object literal (e.g., AztecNodeApiSchema = { ... }) from source, + * extracting method names and simplified type info from the Zod expressions. + */ +function parseSchemaFile( + filePath: string, + schemaName: string, +): Map { + const result = new Map(); + const sourceText = fs.readFileSync(filePath, 'utf-8'); + const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true); + + function visit(node: ts.Node) { + // Look for: export const SchemaName: ... = { ... } + if ( + ts.isVariableStatement(node) && + node.declarationList.declarations.length > 0 + ) { + for (const decl of node.declarationList.declarations) { + if ( + ts.isIdentifier(decl.name) && + decl.name.text === schemaName && + decl.initializer && + ts.isObjectLiteralExpression(decl.initializer) + ) { + parseSchemaObject(decl.initializer, sourceFile, result); + } + } + } + ts.forEachChild(node, visit); + } + + visit(sourceFile); + return result; +} + +function parseSchemaObject( + obj: ts.ObjectLiteralExpression, + sourceFile: ts.SourceFile, + result: Map, +) { + for (const prop of obj.properties) { + if (!ts.isPropertyAssignment(prop)) continue; + const name = prop.name?.getText(sourceFile); + if (!name) continue; + + // The value is a Zod expression like z.function().args(...).returns(...) + const exprText = prop.initializer.getText(sourceFile); + const info = parseZodFunctionExpr(exprText); + result.set(name, info); + } +} + +/** + * Parse a Zod function expression string to extract simplified parameter types and return type. + * + * Examples: + * "z.function().args(BlockParameterSchema, schemas.Fr).returns(schemas.Fr)" + * "z.function().returns(z.boolean())" + * "z.function().args(z.number(), optional(z.boolean())).returns(z.void())" + */ +function parseZodFunctionExpr(expr: string): { paramTypes: string[]; returnType: string } { + const paramTypes: string[] = []; + let returnType = 'void'; + + // Normalize whitespace (multi-line expressions use \n + indentation) + const normalized = expr.replace(/\s+/g, ' ').trim(); + + // Extract .args(...) content — match balanced parens for args + const argsStart = normalized.indexOf('.args('); + if (argsStart !== -1) { + const argsContentStart = argsStart + '.args('.length; + const argsEnd = findMatchingParen(normalized, argsContentStart - 1); + if (argsEnd !== -1) { + const argsContent = normalized.substring(argsContentStart, argsEnd).trim(); + if (argsContent) { + paramTypes.push(...splitTopLevelArgs(argsContent).map(simplifyZodType)); + } + } + } + + // Extract .returns(...) content — match balanced parens for returns + const returnsStart = normalized.indexOf('.returns('); + if (returnsStart !== -1) { + const returnsContentStart = returnsStart + '.returns('.length; + const returnsEnd = findMatchingParen(normalized, returnsContentStart - 1); + if (returnsEnd !== -1) { + returnType = simplifyZodType(normalized.substring(returnsContentStart, returnsEnd).trim()); + } + } + + return { paramTypes, returnType }; +} + +/** + * Find the position of the closing paren that matches the opening paren at `openPos`. + * Returns the index of the closing paren, or -1 if not found. + */ +function findMatchingParen(text: string, openPos: number): number { + let depth = 0; + for (let i = openPos; i < text.length; i++) { + if (text[i] === '(') depth++; + else if (text[i] === ')') { + depth--; + if (depth === 0) return i; + } + } + return -1; +} + +/** + * Split comma-separated arguments at the top level (respecting nested parentheses and brackets). + */ +function splitTopLevelArgs(text: string): string[] { + const args: string[] = []; + let depth = 0; + let current = ''; + + for (const char of text) { + if (char === '(' || char === '[' || char === '{') depth++; + else if (char === ')' || char === ']' || char === '}') depth--; + + if (char === ',' && depth === 0) { + const trimmed = current.trim(); + if (trimmed) args.push(trimmed); + current = ''; + } else { + current += char; + } + } + const trimmed = current.trim(); + if (trimmed) args.push(trimmed); + return args; +} + +/** + * Simplify a Zod type expression into a human-readable type string. + */ +function simplifyZodType(expr: string): string { + const e = expr.trim(); + + // Simple types + if (e === 'z.string()') return 'string'; + if (e === 'z.number()') return 'number'; + if (e === 'z.boolean()') return 'boolean'; + if (e === 'z.void()') return 'void'; + if (e === 'z.bigint()') return 'bigint'; + + // schemas.* references + if (e === 'schemas.Fr') return 'Fr'; + if (e === 'schemas.AztecAddress') return 'AztecAddress'; + if (e === 'schemas.EthAddress') return 'EthAddress'; + if (e === 'schemas.BigInt') return 'bigint'; + if (e === 'schemas.SlotNumber') return 'SlotNumber'; + + // Branded type schemas + if (e === 'BlockNumberSchema') return 'number'; + if (e === 'BlockNumberPositiveSchema') return 'number'; + if (e === 'CheckpointNumberSchema') return 'number'; + if (e === 'CheckpointNumberPositiveSchema') return 'number'; + if (e === 'EpochNumberSchema') return 'number'; + if (e === 'BlockParameterSchema') return 'number | "latest"'; + + // Known schema objects + if (e === 'L2TipsSchema') return 'L2Tips'; + if (e === 'WorldStateSyncStatusSchema') return 'WorldStateSyncStatus'; + if (e === 'NodeInfoSchema') return 'NodeInfo'; + if (e === 'L1ContractAddressesSchema') return 'L1ContractAddresses'; + if (e === 'ProtocolContractAddressesSchema') return 'ProtocolContractAddresses'; + if (e === 'ValidatorsStatsSchema') return 'ValidatorsStats'; + if (e === 'TxValidationResultSchema') return 'TxValidationResult'; + if (e === 'LogFilterSchema') return 'LogFilter'; + if (e === 'GetPublicLogsResponseSchema') return 'GetPublicLogsResponse'; + if (e === 'GetContractClassLogsResponseSchema') return 'GetContractClassLogsResponse'; + if (e === 'ContractClassPublicSchema') return 'ContractClassPublic'; + if (e === 'ContractInstanceWithAddressSchema') return 'ContractInstanceWithAddress'; + if (e === 'OffenseSchema') return 'Offense'; + if (e === 'AllowedElementSchema') return 'AllowedElement'; + if (e === 'CheckpointDataSchema') return 'CheckpointData'; + + // Class schemas: ClassName.schema + const classSchemaMatch = e.match(/^(\w+)\.schema$/); + if (classSchemaMatch) return classSchemaMatch[1]; + + // TxHash.schema, L2Block.schema, etc + const classSchemaMatch2 = e.match(/^(\w+)\.schema\b/); + if (classSchemaMatch2) return classSchemaMatch2[1]; + + // z.string().optional() / z.number().optional() + if (e.endsWith('.optional()')) { + return simplifyZodType(e.replace(/\.optional\(\)$/, '')) + ' | undefined'; + } + + // optional(X) + const optionalMatch = e.match(/^optional\(([\s\S]+)\)$/); + if (optionalMatch) return simplifyZodType(optionalMatch[1]) + ' | undefined'; + + // z.array(...) — use balanced paren matching to extract inner type + if (e.startsWith('z.array(')) { + const innerEnd = findMatchingParen(e, 8 - 1); // 8 = 'z.array('.length, -1 to point at '(' + if (innerEnd !== -1) { + const inner = e.substring(8, innerEnd); + return simplifyZodType(inner) + '[]'; + } + } + + // z.nativeEnum(X) + const nativeEnumMatch = e.match(/^z\.nativeEnum\((\w+)\)$/); + if (nativeEnumMatch) return nativeEnumMatch[1]; + + // z.literal(X) + const literalMatch = e.match(/^z\.literal\((.+)\)$/); + if (literalMatch) return literalMatch[1]; + + // z.union([...]) + const unionMatch = e.match(/^z\.union\(\[([\s\S]+)\]\)$/); + if (unionMatch) { + return splitTopLevelArgs(unionMatch[1]).map(simplifyZodType).join(' | '); + } + + // z.tuple([...]) + const tupleMatch = e.match(/^z\.tuple\(\[([\s\S]+)\]\)$/); + if (tupleMatch) { + const items = splitTopLevelArgs(tupleMatch[1]).map(simplifyZodType); + return `[${items.join(', ')}]`; + } + + // z.object({...}) + if (e.startsWith('z.object(')) return 'object'; + + // z.number().gt(X).lte(Y) etc + if (e.startsWith('z.number()')) return 'number'; + if (e.startsWith('z.string()')) return 'string'; + if (e.startsWith('z.bigint()')) return 'bigint'; + + // SiblingPath.schemaFor(X) + if (e.startsWith('SiblingPath.schemaFor(')) return 'SiblingPath'; + + // MembershipWitness.schemaFor(X) + if (e.startsWith('MembershipWitness.schemaFor(')) return 'MembershipWitness'; + + // NullifierMembershipWitness.schema + if (e.includes('NullifierMembershipWitness')) return 'NullifierMembershipWitness'; + + // PublicDataWitness.schema + if (e.includes('PublicDataWitness')) return 'PublicDataWitness'; + + // dataInBlockSchemaFor(X) + if (e.startsWith('dataInBlockSchemaFor(')) { + const innerMatch = e.match(/dataInBlockSchemaFor\(([\s\S]+)\)/); + if (innerMatch) return `DataInBlock<${simplifyZodType(innerMatch[1])}>`; + } + + // indexedTxSchema() + if (e.startsWith('indexedTxSchema(')) return 'IndexedTxEffect'; + + // Schema references ending in Schema + const schemaRefMatch = e.match(/^(\w+)Schema$/); + if (schemaRefMatch) { + // Convert FooBarSchema to FooBar + return schemaRefMatch[1]; + } + + // Chained expressions with .optional() + if (e.includes('.optional()')) { + const base = e.replace(/\.optional\(\)\s*$/, ''); + return simplifyZodType(base) + ' | undefined'; + } + + // Admin config schemas + if (e.includes('ConfigSchema')) return 'object'; + + // Fallback + return 'object'; +} + +// --------------------------------------------------------------------------- +// Markdown generation +// --------------------------------------------------------------------------- + +/** Method grouping configuration. Methods are rendered in this order. */ +const METHOD_GROUPS: { heading: string; namespace: string; methods: string[] }[] = [ + { + heading: 'Block queries', + namespace: 'node', + methods: [ + 'getBlockNumber', + 'getProvenBlockNumber', + 'getCheckpointedBlockNumber', + 'getCheckpointNumber', + 'getL2Tips', + 'getBlock', + 'getBlockByHash', + 'getBlockByArchive', + 'getBlocks', + 'getBlockHeader', + 'getBlockHeaderByArchive', + 'getCheckpoints', + 'getCheckpointedBlocks', + 'getCheckpointsDataForEpoch', + ], + }, + { + heading: 'Transaction operations', + namespace: 'node', + methods: [ + 'sendTx', + 'getTxReceipt', + 'getTxEffect', + 'getTxByHash', + 'getTxsByHash', + 'getPendingTxs', + 'getPendingTxCount', + 'isValidTx', + 'simulatePublicCalls', + ], + }, + { + heading: 'State queries', + namespace: 'node', + methods: ['getPublicStorageAt', 'getWorldStateSyncStatus'], + }, + { + heading: 'Membership witnesses', + namespace: 'node', + methods: [ + 'findLeavesIndexes', + 'getNullifierMembershipWitness', + 'getLowNullifierMembershipWitness', + 'getPublicDataWitness', + 'getBlockHashMembershipWitness', + 'getNoteHashMembershipWitness', + ], + }, + { + heading: 'L1 to L2 messages', + namespace: 'node', + methods: [ + 'getL1ToL2MessageMembershipWitness', + 'getL1ToL2MessageCheckpoint', + 'isL1ToL2MessageSynced', + 'getL2ToL1Messages', + ], + }, + { + heading: 'Log queries', + namespace: 'node', + methods: [ + 'getPublicLogs', + 'getContractClassLogs', + 'getPrivateLogsByTags', + 'getPublicLogsByTagsFromContract', + ], + }, + { + heading: 'Contract queries', + namespace: 'node', + methods: ['getContractClass', 'getContract'], + }, + { + heading: 'Fee queries', + namespace: 'node', + methods: ['getCurrentMinFees', 'getPredictedMinFees', 'getMaxPriorityFees'], + }, + { + heading: 'Node information', + namespace: 'node', + methods: [ + 'isReady', + 'getNodeInfo', + 'getNodeVersion', + 'getVersion', + 'getChainId', + 'getL1ContractAddresses', + 'getProtocolContractAddresses', + 'getEncodedEnr', + ], + }, + { + heading: 'Validator queries', + namespace: 'node', + methods: ['getValidatorsStats', 'getValidatorStats'], + }, + { + heading: 'Debug operations', + namespace: 'node', + methods: ['registerContractFunctionSignatures', 'getAllowedPublicSetup'], + }, + { + heading: 'Admin API', + namespace: 'nodeAdmin', + methods: [ + 'getConfig', + 'setConfig', + 'pauseSync', + 'resumeSync', + 'rollbackTo', + 'startSnapshotUpload', + 'getSlashPayloads', + 'getSlashOffenses', + 'reloadKeystore', + ], + }, +]; + +function generateExampleParam(paramType: string): string { + const t = paramType.replace(/\s*\|\s*undefined$/, '').trim(); + if (t === 'number') return '12345'; + if (t === 'bigint') return '"100"'; + if (t === 'string') return '"0x1234..."'; + if (t === 'boolean') return 'true'; + if (t === 'number | "latest"') return '"latest"'; + if (t.includes('"all"') || t.includes('"current"')) return '"current"'; + if (t === 'Fr' || t === 'AztecAddress' || t === 'BlockHash') return '"0x1234..."'; + if (t === 'EthAddress') return '"0x1234..."'; + if (t === 'SlotNumber') return '"100"'; + if (t === 'MerkleTreeId') return '1'; + if (t === 'ManaUsageEstimate') return '1'; + if (t.endsWith('[]')) return `[${generateExampleParam(t.slice(0, -2))}]`; + if (t === 'Tx') return '{"data":"0x..."}'; + if (t === 'TxHash') return '"0x1234..."'; + if (t === 'SiloedTag') return '"0x1234..."'; + if (t === 'Tag') return '"0x1234..."'; + if (t === 'LogFilter') return '{"fromBlock":100,"toBlock":200}'; + if (t === 'object') return '{}'; + return '"0x1234..."'; +} + +function generateMethodMarkdown(method: MethodInfo, isAdmin: boolean): string { + const lines: string[] = []; + const rpcName = `${method.namespace}_${method.name}`; + const port = isAdmin ? 8880 : 8080; + + lines.push(`### ${rpcName}`); + lines.push(''); + + if (method.jsdoc.description) { + lines.push(method.jsdoc.description); + lines.push(''); + } + + if (method.jsdoc.deprecated) { + lines.push(`**Deprecated**: ${method.jsdoc.deprecated}`); + lines.push(''); + } + + // Parameters + if (method.paramTypes.length === 0) { + lines.push('**Parameters**: None'); + } else { + lines.push('**Parameters**:'); + lines.push(''); + for (let i = 0; i < method.paramTypes.length; i++) { + const paramName = method.paramNames[i] || `param${i + 1}`; + const paramType = method.paramTypes[i]; + const jsdocParam = method.jsdoc.params.find(p => p.name === paramName); + const desc = jsdocParam?.description ? ` - ${jsdocParam.description}` : ''; + lines.push(`${i + 1}. \`${paramName}\` - \`${paramType}\`${desc}`); + } + } + lines.push(''); + + // Returns + const returnsDesc = method.jsdoc.returns ? ` - ${method.jsdoc.returns}` : ''; + lines.push(`**Returns**: \`${method.returnType}\`${returnsDesc}`); + lines.push(''); + + // Example + const exampleParams = method.paramTypes.map(t => generateExampleParam(t)).join(','); + + if (isAdmin) { + lines.push('**Example (CLI)**:'); + lines.push(''); + lines.push('```bash'); + lines.push(`curl -X POST http://localhost:${port} \\`); + lines.push(` -H 'Content-Type: application/json' \\`); + lines.push(` -d '{"jsonrpc":"2.0","method":"${rpcName}","params":[${exampleParams}],"id":1}'`); + lines.push('```'); + lines.push(''); + lines.push('**Example (Docker)**:'); + lines.push(''); + lines.push('```bash'); + lines.push(`docker exec -it aztec-node curl -X POST http://localhost:${port} \\`); + lines.push(` -H 'Content-Type: application/json' \\`); + lines.push(` -d '{"jsonrpc":"2.0","method":"${rpcName}","params":[${exampleParams}],"id":1}'`); + lines.push('```'); + } else { + lines.push('**Example**:'); + lines.push(''); + lines.push('```bash'); + lines.push(`curl -X POST http://localhost:${port} \\`); + lines.push(` -H 'Content-Type: application/json' \\`); + lines.push(` -d '{"jsonrpc":"2.0","method":"${rpcName}","params":[${exampleParams}],"id":1}'`); + lines.push('```'); + } + + return lines.join('\n'); +} + +function generateDocument(allMethods: Map, schemaMethodNames: { node: string[]; nodeAdmin: string[] }): string { + const lines: string[] = []; + + // Frontmatter + lines.push('---'); + lines.push('id: node_api_reference'); + lines.push('displayed_sidebar: operatorsSidebar'); + lines.push('title: Node JSON RPC API reference'); + lines.push('description: Complete reference for the Aztec Node JSON RPC API, including block queries, transaction submission, world state access, and administrative operations.'); + lines.push('references: ["yarn-project/stdlib/src/interfaces/aztec-node.ts", "yarn-project/stdlib/src/interfaces/aztec-node-admin.ts"]'); + lines.push('---'); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push('This document provides a complete reference for the Aztec Node JSON RPC API. All methods are exposed via JSON RPC on the node\'s configured ports.'); + lines.push(''); + lines.push('## API endpoint'); + lines.push(''); + lines.push('**Public RPC URL**: `http://localhost:8080`'); + lines.push(''); + lines.push('**Admin URL**: `http://localhost:8880`'); + lines.push(''); + lines.push('Note that the above ports are only defaults, and can be modified by setting `--port` and `--admin-port` flags upon startup.'); + lines.push(''); + lines.push('All methods use standard JSON RPC 2.0 format with methods prefixed by `node_` or `nodeAdmin_`.'); + lines.push(''); + + const rendered = new Set(); + + for (const group of METHOD_GROUPS) { + const isAdmin = group.namespace === 'nodeAdmin'; + + const groupMethods: MethodInfo[] = []; + for (const methodName of group.methods) { + const key = `${group.namespace}:${methodName}`; + const info = allMethods.get(key); + if (info) { + groupMethods.push(info); + rendered.add(key); + } + } + + if (groupMethods.length === 0) continue; + + if (isAdmin) { + lines.push('## Admin API'); + lines.push(''); + lines.push('Administrative operations are exposed on port 8880 under the `nodeAdmin_` namespace.'); + lines.push(''); + lines.push(':::warning Security: Admin API Access'); + lines.push('For security reasons, the admin port (8880) should **not be exposed** to the host machine in Docker deployments. The examples below show both CLI and Docker methods:'); + lines.push(''); + lines.push('**CLI Method** (when running with `aztec start` directly):'); + lines.push(''); + lines.push('```bash'); + lines.push('curl -X POST http://localhost:8880 ...'); + lines.push('```'); + lines.push(''); + lines.push('**Docker Method** (when running with Docker Compose):'); + lines.push(''); + lines.push('```bash'); + lines.push('docker exec -it curl -X POST http://localhost:8880 ...'); + lines.push('```'); + lines.push(''); + lines.push('Replace `` with your container name (e.g., `aztec-node`, `aztec-sequencer`, `prover-node`).'); + lines.push(':::'); + lines.push(''); + } else { + lines.push(`## ${group.heading}`); + lines.push(''); + } + + for (const method of groupMethods) { + lines.push(generateMethodMarkdown(method, isAdmin)); + lines.push(''); + } + } + + // Ungrouped methods + const allSchemaKeys = [ + ...schemaMethodNames.node.map(m => `node:${m}`), + ...schemaMethodNames.nodeAdmin.map(m => `nodeAdmin:${m}`), + ]; + const ungrouped = allSchemaKeys.filter(k => !rendered.has(k)); + if (ungrouped.length > 0) { + lines.push('## Other methods'); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push(''); + for (const key of ungrouped) { + const info = allMethods.get(key); + if (info) { + const isAdmin = key.startsWith('nodeAdmin:'); + lines.push(generateMethodMarkdown(info, isAdmin)); + lines.push(''); + } + } + } + + // Next steps + lines.push('## Next steps'); + lines.push(''); + lines.push('- [How to Run a Sequencer Node](../setup/sequencer-setup.md) - Set up a node'); + lines.push('- [Ethereum RPC Calls Reference](./ethereum-rpc-reference.md) - L1 RPC usage'); + lines.push('- [CLI Reference](./cli-reference.md) - Command-line options'); + lines.push('- [Aztec Discord](https://discord.gg/aztec) - Developer support'); + lines.push(''); + + return lines.join('\n'); +} + +// --------------------------------------------------------------------------- +// Main +// --------------------------------------------------------------------------- + +function main() { + const { yarnProject, output } = parseArgs(); + + const nodeInterfacePath = path.join(yarnProject, 'stdlib/src/interfaces/aztec-node.ts'); + const adminInterfacePath = path.join(yarnProject, 'stdlib/src/interfaces/aztec-node-admin.ts'); + const blockSourcePath = path.join(yarnProject, 'stdlib/src/block/l2_block_source.ts'); + + // Phase A: Extract JSDoc and param names from interfaces + console.log('Phase A: Extracting JSDoc comments and parameter names...'); + const nodeInterface = parseInterfaceFile(nodeInterfacePath); + const adminInterface = parseInterfaceFile(adminInterfacePath); + const blockSource = parseInterfaceFile(blockSourcePath); + + // Merge: block source JSDoc used as fallback for inherited methods + const mergedJSDoc = new Map(); + for (const [name, doc] of blockSource.jsdoc) mergedJSDoc.set(name, doc); + for (const [name, doc] of nodeInterface.jsdoc) mergedJSDoc.set(name, doc); + + const mergedParamNames = new Map(); + for (const [name, params] of blockSource.paramNames) mergedParamNames.set(name, params); + for (const [name, params] of nodeInterface.paramNames) mergedParamNames.set(name, params); + + // Phase B: Parse Zod schemas from source AST + console.log('Phase B: Parsing Zod schema definitions...'); + const nodeSchemaInfo = parseSchemaFile(nodeInterfacePath, 'AztecNodeApiSchema'); + const adminSchemaInfo = parseSchemaFile(adminInterfacePath, 'AztecNodeAdminApiSchema'); + + const nodeMethodNames = [...nodeSchemaInfo.keys()]; + const adminMethodNames = [...adminSchemaInfo.keys()]; + + console.log(` Found ${nodeMethodNames.length} node methods, ${adminMethodNames.length} admin methods`); + + // Phase C: Combine and generate + console.log('Phase C: Generating markdown...'); + + const allMethods = new Map(); + + for (const name of nodeMethodNames) { + const schema = nodeSchemaInfo.get(name)!; + const jsdoc = mergedJSDoc.get(name) || { description: '', params: [], returns: '' }; + const paramNames = mergedParamNames.get(name) || []; + + allMethods.set(`node:${name}`, { + name, + namespace: 'node', + jsdoc, + paramTypes: schema.paramTypes, + paramNames: paramNames.length > 0 ? paramNames : schema.paramTypes.map((_, i) => `param${i + 1}`), + returnType: schema.returnType, + }); + } + + for (const name of adminMethodNames) { + const schema = adminSchemaInfo.get(name)!; + const jsdoc = adminInterface.jsdoc.get(name) || { description: '', params: [], returns: '' }; + const paramNames = adminInterface.paramNames.get(name) || []; + + allMethods.set(`nodeAdmin:${name}`, { + name, + namespace: 'nodeAdmin', + jsdoc, + paramTypes: schema.paramTypes, + paramNames: paramNames.length > 0 ? paramNames : schema.paramTypes.map((_, i) => `param${i + 1}`), + returnType: schema.returnType, + }); + } + + const markdown = generateDocument(allMethods, { node: nodeMethodNames, nodeAdmin: adminMethodNames }); + fs.writeFileSync(output, markdown, 'utf-8'); + console.log(`Written to ${output}`); + + // Report ungrouped methods + const allGrouped = new Set(); + for (const group of METHOD_GROUPS) { + for (const m of group.methods) allGrouped.add(`${group.namespace}:${m}`); + } + const allKeys = [ + ...nodeMethodNames.map(m => `node:${m}`), + ...adminMethodNames.map(m => `nodeAdmin:${m}`), + ]; + const ungrouped = allKeys.filter(k => !allGrouped.has(k)); + if (ungrouped.length > 0) { + console.warn(`\nWARNING: ${ungrouped.length} ungrouped method(s) (rendered in "Other methods"):`); + for (const k of ungrouped) console.warn(` - ${k.replace(':', '_')}`); + console.warn('Update METHOD_GROUPS in generate_node_api_reference.ts to categorize them.'); + } + + // Report methods in config but missing from schema + for (const group of METHOD_GROUPS) { + for (const m of group.methods) { + if (!allMethods.has(`${group.namespace}:${m}`)) { + console.warn(`WARNING: ${group.namespace}_${m} is in METHOD_GROUPS but not in schema`); + } + } + } + + console.log(`\nTotal: ${nodeMethodNames.length} node_ + ${adminMethodNames.length} nodeAdmin_ = ${nodeMethodNames.length + adminMethodNames.length} methods`); +} + +main(); From 24b1c585aac1ddadc83979863efbe85d435c05be Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Wed, 6 May 2026 13:39:48 -0400 Subject: [PATCH 02/30] fix(aztec-up): Aztec installer does not shadow user installed binaries on PATH (#22902) Resolves [F-613](https://linear.app/aztec-labs/issue/F-613/aztec-installer-shadows-user-forge-nargo-on-path). The installer used to drop `forge`, `nargo`, `anvil`, `bb`, `pxe`, `txe`, etc. directly into `~/.aztec/current/bin` under bare names, silently shadowing user-installed tools in unrelated projects. Native binaries now live in `~/.aztec/current/internal-bin` (off `PATH`) and are exposed only via `aztec-` symlinks in `~/.aztec/current/bin`. The `aztec` entrypoint is a small wrapper that prepends `internal-bin` to its subprocess `PATH`, so `aztec test` and `aztec start --local-network` continue to resolve bundled `nargo` / `anvil` by basename without leaking them to the user's shell. `aztec-up/test/no_shadow_user_bins.sh` is a new regression test that plants user shims for every bare name, asserts the shims win on `PATH`, and asserts every entry in `current/bin` is `aztec` or `aztec-*`. Migration notes and the affected tutorials are updated to the new `aztec-*` names. The issue mentions appropriately handling binaries calling other binaries by name. I felt that was overly defensive and we should rely on tools cross-calling bins with an absolute path. Rather than defending against this with extra scaffolding in our wrappers, the correct fix is for the tools to use an absolute bundled path for internal tool calls. (cherry picked from commit 0aaf27cd01a5b8b55a2fce7067ffac8882aa99df) --- aztec-up/README.md | 11 +- aztec-up/bin/0.0.1/aztec-install | 8 +- aztec-up/bin/0.0.1/install | 117 +++- aztec-up/bootstrap.sh | 6 +- aztec-up/scripts/run_isolated_test.sh | 4 +- .../aztec-cli-acceptance-test.ts | 162 +++--- aztec-up/test/basic_install.sh | 4 +- aztec-up/test/no_shadow_user_bins.sh | 82 +++ docs/docs-developers/ai_tooling.md | 2 +- .../functions/attributes.md | 10 +- .../docs/aztec-nr/installation.md | 16 +- .../docs/resources/glossary.md | 2 + .../docs/resources/migration_notes.md | 31 ++ .../recursive_verification.md | 12 +- .../tutorials/js_tutorials/aave_bridge.md | 518 ++++++++++++++++++ .../testing_governance_rollup_upgrade.md | 12 +- .../getting_started_on_local_network.md | 10 +- 17 files changed, 883 insertions(+), 124 deletions(-) create mode 100755 aztec-up/test/no_shadow_user_bins.sh create mode 100644 docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md diff --git a/aztec-up/README.md b/aztec-up/README.md index e2f3ec2edbd8..5548356922b5 100644 --- a/aztec-up/README.md +++ b/aztec-up/README.md @@ -9,9 +9,14 @@ That is all. This will install into `~/.aztec/bin` a collection of scripts to help with running aztec containers, and will update the user's `PATH` variable in their shell startup script so they can be found. -- `aztec` - a collection of tools to compile and test contracts, to launch subsystems and interact with the aztec network." -- `aztec-up` - a tool to install and manage aztec toolchain versions." -- `aztec-wallet` - our minimalistic CLI wallet" +- `aztec` - compiles and tests contracts, launches infrastructure subsystems, interacts with the network. +- `aztec-up` - a version manager for the Aztec toolchain. +- `aztec-wallet` - a tool for interacting with the Aztec network. +- `aztec-bb` - the Barretenberg proving backend. +- `aztec-nargo` - the Noir compiler and simulator. +- `aztec-forge`, `aztec-cast`, `aztec-anvil`, `aztec-chisel` - the bundled Foundry tools. + +Foundry, Noir, and Barretenberg are bundled at the versions `aztec` needs. Your own `forge` / `nargo` / `bb` installs still work under their bare names. After installed, you can use `aztec-up` to install specific versions. diff --git a/aztec-up/bin/0.0.1/aztec-install b/aztec-up/bin/0.0.1/aztec-install index 6d0321d49b71..1a5faaa4355e 100755 --- a/aztec-up/bin/0.0.1/aztec-install +++ b/aztec-up/bin/0.0.1/aztec-install @@ -94,12 +94,14 @@ function title { echo -e "Installing version: ${bold}${o}$VERSION${r}" echo echo -e "This script installs the following and updates your PATH if necessary:" - echo -e " ${bold}${g}nargo${r} - the noir programming language compiler and simulator." - echo -e " ${bold}${g}noir-profiler${r} - a profiler for analyzing and visualizing noir programs." - echo -e " ${bold}${g}bb${r} - the barretenberg proving backend." echo -e " ${bold}${g}aztec${r} - compiles and tests contracts, interacts with the network." echo -e " ${bold}${g}aztec-up${r} - installs and manages aztec toolchain versions." echo -e " ${bold}${g}aztec-wallet${r} - a minimalistic wallet cli." + echo -e " ${bold}${g}aztec-bb${r} - the barretenberg proving backend." + echo -e " ${bold}${g}aztec-nargo${r} - the noir compiler and simulator." + echo -e " ${bold}${g}aztec-forge${r}, ${bold}${g}aztec-cast${r}, ${bold}${g}aztec-anvil${r}, ${bold}${g}aztec-chisel${r} - the bundled foundry tools." + echo + echo -e "Foundry, Noir, and Barretenberg are bundled at the versions ${bold}${g}aztec${r} needs. Your own ${bold}${g}forge${r} / ${bold}${g}nargo${r} / ${bold}${g}bb${r} installs still work under their bare names." echo read -p "Do you wish to continue? (Y/n) " -n 1 -r echo diff --git a/aztec-up/bin/0.0.1/install b/aztec-up/bin/0.0.1/install index 5f56b6ef123f..6f3dfadfedf9 100755 --- a/aztec-up/bin/0.0.1/install +++ b/aztec-up/bin/0.0.1/install @@ -37,6 +37,12 @@ export FORCE_COLOR=1 # Version-specific paths version_path="$AZTEC_HOME/versions/$VERSION" version_bin_path="$version_path/bin" +# Native binaries (forge/nargo/anvil/...) live here and are NOT on the user's PATH. +# The aztec wrapper prepends this directory to its child PATH so subprocesses +# spawned from the aztec workflow (which call sibling tools by basename) resolve +# to the bundled binaries. User-facing access is only via the aztec-* symlinks +# in version_bin_path. +version_internal_bin_path="$version_path/internal-bin" os="$(uname -s)" @@ -137,7 +143,15 @@ function install_noir { set -euo pipefail if [[ -n ${NARGO:-} ]]; then - cp "$NARGO" "$version_bin_path/nargo" + cp "$NARGO" "$version_internal_bin_path/nargo" + # noir's release build co-locates `noir-profiler` next to `nargo` + # (see noir/bootstrap.sh::build_native). Copy it too so the + # `aztec-noir-profiler` symlink in install_native_symlinks resolves. + local nargo_dir + nargo_dir=$(dirname "$NARGO") + if [ -f "$nargo_dir/noir-profiler" ]; then + cp "$nargo_dir/noir-profiler" "$version_internal_bin_path/noir-profiler" + fi else local noir_version noir_version=$(get_version "noir") @@ -150,13 +164,12 @@ function install_noir { # Always install/update noirup curl -Ls https://raw.githubusercontent.com/noir-lang/noirup/refs/heads/main/install | bash - # Install noir to temp location and move to version directory + # Install noir to temp location and move into internal-bin (off PATH). NARGO_HOME="$temp_nargo_home" "$HOME/.nargo/bin/noirup" -v "$noir_version" - # Move the nargo binary to our version bin directory - mv "$temp_nargo_home/bin/nargo" "$version_bin_path/nargo" + mv "$temp_nargo_home/bin/nargo" "$version_internal_bin_path/nargo" # Also move noir-profiler, needed by `aztec profile flamegraph` - mv "$temp_nargo_home/bin/noir-profiler" "$version_bin_path/noir-profiler" + mv "$temp_nargo_home/bin/noir-profiler" "$version_internal_bin_path/noir-profiler" # Cleanup temp directory rm -rf "$temp_nargo_home" @@ -182,10 +195,11 @@ function install_foundry { # Install foundry to temp location and move to version directory FOUNDRY_DIR="$temp_foundry_dir" timeout 30 "$foundry_home/bin/foundryup" -i "$foundry_version" - # Move the foundry binaries to our version bin directory + # Move the foundry binaries into internal-bin (off PATH); aztec-forge etc. + # symlinks in version_bin_path expose them under aztec-prefixed names. for binary in forge cast anvil chisel; do if [ -f "$temp_foundry_dir/bin/$binary" ]; then - mv "$temp_foundry_dir/bin/$binary" "$version_bin_path/$binary" + mv "$temp_foundry_dir/bin/$binary" "$version_internal_bin_path/$binary" fi done @@ -200,32 +214,88 @@ function install_aztec_packages { npm install @aztec/aztec@$VERSION @aztec/cli-wallet@$VERSION @aztec/bb.js@$VERSION --prefix "$version_path" } -function symlink_aztec_bins { +# Expose every native tool in internal-bin under an aztec- symlink in bin. +# Bare `forge`/`nargo`/etc. are intentionally NOT on PATH so they cannot shadow +# user-installed tools. +function install_native_symlinks { + set -euo pipefail + local tool + for tool in forge cast anvil chisel nargo noir-profiler; do + if [ ! -e "$version_internal_bin_path/$tool" ]; then + echo "Error: expected bundled binary '$tool' missing from $version_internal_bin_path" >&2 + exit 1 + fi + ln -sfn "../internal-bin/$tool" "$version_bin_path/aztec-$tool" + done +} + +# Npm bins are NOT mirrored into internal-bin. The contract for any TS tool +# that needs to spawn a sibling binary is to resolve an absolute bundled +# path itself (e.g. via @aztec/bb.js findBbBinary(), or a BB-style env +# var) -- never by basename + PATH lookup. If you find yourself wanting to +# add an npm bin to internal-bin so a child process can find it on PATH, +# fix the caller instead of broadening this list. +function install_npm_bin_symlinks { set -euo pipefail - # Populate version_bin_path with symlinks to @aztec-owned bins only. Adding - # node_modules/.bin wholesale to PATH would shadow user-installed tools - # (jest, tsc, semver, ...) with Aztec's transitive dependencies. local npm_bin_dir="$version_path/node_modules/.bin" [ -d "$npm_bin_dir" ] || return 0 - local bin_link bin_name target + local bin_link bin_name target link_name for bin_link in "$npm_bin_dir"/*; do [ -L "$bin_link" ] || continue target=$(readlink "$bin_link") # npm writes relative symlinks like ../@aztec/aztec/... for scoped packages. [[ "$target" == ../@aztec/* ]] || continue bin_name=$(basename "$bin_link") - if [ -e "$version_bin_path/$bin_name" ] && [ ! -L "$version_bin_path/$bin_name" ]; then - echo_yellow "refusing to overwrite non-symlink $bin_name; @aztec package bin collides with a hand-installed toolchain binary" >&2 + + # `aztec` is a wrapper, written by install_aztec_wrapper. + [[ "$bin_name" == "aztec" ]] && continue + + # Already prefixed (e.g. aztec-wallet) keeps its name; everything else gets + # renamed to aztec- so it cannot shadow a user-installed binary. + if [[ "$bin_name" == aztec-* ]]; then + link_name="$bin_name" + else + link_name="aztec-$bin_name" + fi + + if [ -e "$version_bin_path/$link_name" ] && [ ! -L "$version_bin_path/$link_name" ]; then + echo_yellow "refusing to overwrite non-symlink $link_name; @aztec package bin collides with a hand-installed toolchain binary" >&2 exit 1 fi - ln -sfn "../node_modules/.bin/$bin_name" "$version_bin_path/$bin_name" + ln -sfn "../node_modules/.bin/$bin_name" "$version_bin_path/$link_name" done } +# Wrapper for `aztec`: prepends internal-bin to PATH so the aztec workflow +# resolves bundled native tools by basename. yarn-project/aztec/scripts/aztec.sh +# (the npm bin entry of @aztec/aztec) calls bare `nargo` (line 36, in `aztec +# test`) and bare `anvil` (line 55-56, in `aztec start --local-network`); the +# TS commands it spawns also fall back to bare `forge` / `nargo` / +# `noir-profiler` when their respective env vars are unset. The wrapper is +# kept minimal -- it is the only place we maintain a PATH-based execution +# context, by design (see install_npm_bin_symlinks for the rationale). +# BASH_SOURCE[0] (not $0) so PATH-name invocation still resolves internal-bin +# from the wrapper's actual location. +function install_aztec_wrapper { + set -euo pipefail + local wrapper="$version_bin_path/aztec" + cat > "$wrapper" <<'EOF' +#!/usr/bin/env bash +# Auto-generated by aztec-up. Do not edit. +set -euo pipefail +self_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +internal_bin="$self_dir/../internal-bin" +export PATH="$internal_bin:$PATH" +exec "$self_dir/../node_modules/.bin/aztec" "$@" +EOF + chmod +x "$wrapper" +} + function main { - # Create version directory + # Create version directories. bin/ is exposed on PATH; internal-bin/ is not. mkdir -p "$version_bin_path" + mkdir -p "$version_internal_bin_path" # Download versions manifest echo -n "Installing version manifest... " @@ -250,14 +320,23 @@ function main { dump_fail retry install_foundry echo_green "done." + # Expose native tools as aztec-forge / aztec-nargo / etc. + echo -n "Linking aztec native tools... " + dump_fail install_native_symlinks + echo_green "done." + # Install aztec npm packages - echo -n "Installing aztec packages... " + echo -n "Installing aztec npm packages... " dump_fail retry install_aztec_packages echo_green "done." - # Expose only @aztec-owned bins on PATH (drops transitive npm deps). + # Expose @aztec-owned npm bins under aztec-prefixed symlinks. Bare names + # (bb, pxe, txe, ...) are intentionally NOT exposed as they would shadow + # user-installed tools. echo -n "Making aztec commands available... " - dump_fail retry symlink_aztec_bins + dump_fail install_npm_bin_symlinks + # Wrap `aztec` so its subprocesses see internal-bin on PATH. + dump_fail install_aztec_wrapper echo_green "done." } diff --git a/aztec-up/bootstrap.sh b/aztec-up/bootstrap.sh index 50eb80443394..36a7e48d0d67 100755 --- a/aztec-up/bootstrap.sh +++ b/aztec-up/bootstrap.sh @@ -104,7 +104,7 @@ EOF } function test_cmds { - for test in amm_flow bridge_and_claim basic_install counter_contract default_scaffold; do + for test in amm_flow bridge_and_claim basic_install counter_contract default_scaffold no_shadow_user_bins; do echo "$hash:TIMEOUT=15m aztec-up/scripts/run_test.sh $test" done } @@ -234,8 +234,8 @@ function install_on_mac_vm { . "\$HOME/.nvm/nvm.sh" # Verify installation. - nargo --version - bb --version + aztec-nargo --version + aztec-bb --version aztec --version REMOTE_EOF } diff --git a/aztec-up/scripts/run_isolated_test.sh b/aztec-up/scripts/run_isolated_test.sh index 970724ec1871..b6615a7aac43 100755 --- a/aztec-up/scripts/run_isolated_test.sh +++ b/aztec-up/scripts/run_isolated_test.sh @@ -98,9 +98,9 @@ EOF echo "Version information:" bash -i -c -e ' - forge --version + aztec-forge --version echo - nargo --version + aztec-nargo --version echo echo -n "aztec version: " aztec --version diff --git a/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts b/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts index adffe0dde3a6..0b59db12d893 100644 --- a/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts +++ b/aztec-up/test/aztec-cli-acceptance-test/aztec-cli-acceptance-test.ts @@ -13,7 +13,7 @@ // Every phase is wrapped in step(name, ...). The script always emits a `TEST_RESULT=pass|fail ...` line for CI // parsing; on failure it also prints a banner identifying the step that failed. -import { execFileSync, spawn } from 'node:child_process'; +import { execFileSync, spawn } from "node:child_process"; import { closeSync, copyFileSync, @@ -25,35 +25,39 @@ import { readFileSync, rmSync, symlinkSync, -} from 'node:fs'; -import { tmpdir } from 'node:os'; -import { dirname, join, resolve } from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { setTimeout as delay } from 'node:timers/promises'; +} from "node:fs"; +import { tmpdir } from "node:os"; +import { dirname, join, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { setTimeout as delay } from "node:timers/promises"; const NODE_PORT = 8080; const LOCAL_NETWORK_READY_TIMEOUT_MS = 600_000; // 10 minutes const POLL_INTERVAL_MS = 2000; // 2 seconds const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url)); -const COUNTER_TEST_TEMPLATE = join(SCRIPT_DIR, 'counter.test.ts'); +const COUNTER_TEST_TEMPLATE = join(SCRIPT_DIR, "counter.test.ts"); // Defaults to ~/.aztec/current (the symlink aztec-up maintains); fails if no package.json is found there. -const AZTEC_INSTALL_DIR = process.env.AZTEC_INSTALL_DIR ?? join(process.env.HOME ?? '', '.aztec/current'); -if (!existsSync(join(AZTEC_INSTALL_DIR, 'package.json'))) { - console.error(`FATAL: AZTEC_INSTALL_DIR does not point at an installed aztec: ${AZTEC_INSTALL_DIR}`); +const AZTEC_INSTALL_DIR = + process.env.AZTEC_INSTALL_DIR ?? + join(process.env.HOME ?? "", ".aztec/current"); +if (!existsSync(join(AZTEC_INSTALL_DIR, "package.json"))) { + console.error( + `FATAL: AZTEC_INSTALL_DIR does not point at an installed aztec: ${AZTEC_INSTALL_DIR}`, + ); process.exit(2); } -const TMP_DIR = mkdtempSync(join(tmpdir(), 'aztec-cli-acceptance-test-')); -const WORKSPACE_DIR = join(TMP_DIR, 'my_workspace'); +const TMP_DIR = mkdtempSync(join(tmpdir(), "aztec-cli-acceptance-test-")); +const WORKSPACE_DIR = join(TMP_DIR, "my_workspace"); // Exit codes follow the Unix 128+signal convention for signal terminations. -process.on('SIGINT', () => { +process.on("SIGINT", () => { leaveTmpDirForInspection(); process.exit(130); }); -process.on('SIGTERM', () => { +process.on("SIGTERM", () => { leaveTmpDirForInspection(); process.exit(143); }); @@ -76,8 +80,8 @@ if (result.ok) { async function main(): Promise { log(`Working in ${TMP_DIR}`); - let stepName = ''; - let aztecVersion = 'unknown'; + let stepName = ""; + let aztecVersion = "unknown"; async function step(name: string, fn: () => T | Promise): Promise { stepName = name; @@ -89,21 +93,36 @@ async function main(): Promise { } try { - aztecVersion = await step('Checking installed tool versions', logVersions); - await step('Scaffolding new workspace (aztec init)', scaffoldWorkspace); - await step('Verifying scaffold structure', assertScaffold); - await step('Compiling contract (aztec compile)', () => run('aztec', ['compile'], WORKSPACE_DIR)); - - const artifactPath = await step('Locating compiled artifact', locateArtifact); + aztecVersion = await step("Checking installed tool versions", logVersions); + await step("Scaffolding new workspace (aztec init)", scaffoldWorkspace); + await step("Verifying scaffold structure", assertScaffold); + await step("Compiling contract (aztec compile)", () => + run("aztec", ["compile"], WORKSPACE_DIR), + ); + + const artifactPath = await step( + "Locating compiled artifact", + locateArtifact, + ); log(` artifact at ${artifactPath}`); - await step('Running TXE tests (aztec test)', () => run('aztec', ['test'], WORKSPACE_DIR)); + await step("Running TXE tests (aztec test)", () => + run("aztec", ["test"], WORKSPACE_DIR), + ); - await step('Starting local sandbox (aztec start --local-network)', startLocalNetwork); + await step( + "Starting local sandbox (aztec start --local-network)", + startLocalNetwork, + ); - await step('Generating TypeScript bindings (aztec codegen)', () => codegen(artifactPath)); + await step("Generating TypeScript bindings (aztec codegen)", () => + codegen(artifactPath), + ); - await step('Running TypeScript end-to-end test (node --test)', runTsEndToEndTest); + await step( + "Running TypeScript end-to-end test (node --test)", + runTsEndToEndTest, + ); return { ok: true, aztecVersion }; } catch (error) { return { ok: false, stepName, aztecVersion, error }; @@ -113,16 +132,18 @@ async function main(): Promise { function scaffoldWorkspace() { // aztec init scaffolds in pwd and uses the directory name as the package name; create the dir first. mkdirSync(WORKSPACE_DIR, { recursive: true }); - run('aztec', ['init'], WORKSPACE_DIR); + run("aztec", ["init"], WORKSPACE_DIR); } function logVersions(): string { - log('Tool versions:'); - let aztecVersion = 'unknown'; - for (const cmd of ['aztec', 'nargo', 'bb', 'aztec-wallet']) { - const version = execFileSync(cmd, ['--version'], { encoding: 'utf8' }).trim().split('\n')[0]; + log("Tool versions:"); + let aztecVersion = "unknown"; + for (const cmd of ["aztec", "aztec-nargo", "aztec-bb", "aztec-wallet"]) { + const version = execFileSync(cmd, ["--version"], { encoding: "utf8" }) + .trim() + .split("\n")[0]; console.log(` ${cmd}: ${version}`); - if (cmd === 'aztec') { + if (cmd === "aztec") { aztecVersion = version; } } @@ -131,9 +152,9 @@ function logVersions(): string { function assertScaffold() { // aztec init scaffolds a workspace with `_contract/` (Counter) and `_test/` crates. - const packageName = 'my_workspace'; + const packageName = "my_workspace"; const required = [ - 'Nargo.toml', + "Nargo.toml", `${packageName}_contract/Nargo.toml`, `${packageName}_contract/src/main.nr`, `${packageName}_test/Nargo.toml`, @@ -148,32 +169,34 @@ function assertScaffold() { } function locateArtifact(): string { - const matches = globSync('**/target/*-Counter.json', { cwd: WORKSPACE_DIR }); + const matches = globSync("**/target/*-Counter.json", { cwd: WORKSPACE_DIR }); if (matches.length === 0) { - fail('compiled Counter artifact not found under target/'); + fail("compiled Counter artifact not found under target/"); } if (matches.length > 1) { - fail(`expected one Counter artifact, found ${matches.length}: ${matches.join(', ')}`); + fail( + `expected one Counter artifact, found ${matches.length}: ${matches.join(", ")}`, + ); } return resolve(WORKSPACE_DIR, matches[0]); } async function startLocalNetwork(): Promise { - const logPath = join(TMP_DIR, 'local_network.log'); - const logFd = openSync(logPath, 'a'); - const proc = spawn('aztec', ['start', '--local-network'], { + const logPath = join(TMP_DIR, "local_network.log"); + const logFd = openSync(logPath, "a"); + const proc = spawn("aztec", ["start", "--local-network"], { cwd: TMP_DIR, - stdio: ['ignore', logFd, logFd], - env: { ...process.env, LOG_LEVEL: 'silent', PXE_PROVER: 'none' }, + stdio: ["ignore", logFd, logFd], + env: { ...process.env, LOG_LEVEL: "silent", PXE_PROVER: "none" }, }); closeSync(logFd); log(` local-network pid=${proc.pid}, log=${logPath}`); // Kill the network on process exit (including SIGINT/SIGTERM via the signal handlers). - process.on('exit', () => { + process.on("exit", () => { if (proc.exitCode === null) { try { - proc.kill('SIGTERM'); + proc.kill("SIGTERM"); } catch {} } }); @@ -182,16 +205,20 @@ async function startLocalNetwork(): Promise { while (true) { if (proc.exitCode !== null) { dumpTail(logPath); - fail(`local-network exited early with code ${proc.exitCode} (see ${logPath})`); + fail( + `local-network exited early with code ${proc.exitCode} (see ${logPath})`, + ); } if (Date.now() > deadline) { dumpTail(logPath); - fail(`timed out after ${msToSecs(LOCAL_NETWORK_READY_TIMEOUT_MS)}s waiting for local-network /status (see ${logPath})`); + fail( + `timed out after ${msToSecs(LOCAL_NETWORK_READY_TIMEOUT_MS)}s waiting for local-network /status (see ${logPath})`, + ); } try { const res = await fetch(`http://localhost:${NODE_PORT}/status`); if (res.ok) { - log(' local-network ready'); + log(" local-network ready"); return; } } catch { @@ -202,11 +229,11 @@ async function startLocalNetwork(): Promise { } function codegen(artifactPath: string) { - const artifactsOutDir = join(WORKSPACE_DIR, 'artifacts'); + const artifactsOutDir = join(WORKSPACE_DIR, "artifacts"); mkdirSync(artifactsOutDir, { recursive: true }); - const targetDir = resolve(artifactPath, '..'); - run('aztec', ['codegen', targetDir, '-o', artifactsOutDir], WORKSPACE_DIR); - const codegenTs = join(artifactsOutDir, 'Counter.ts'); + const targetDir = resolve(artifactPath, ".."); + run("aztec", ["codegen", targetDir, "-o", artifactsOutDir], WORKSPACE_DIR); + const codegenTs = join(artifactsOutDir, "Counter.ts"); if (!existsSync(codegenTs)) { fail(`codegen did not emit Counter.ts (wrote to ${artifactsOutDir})`); } @@ -215,23 +242,26 @@ function codegen(artifactPath: string) { function runTsEndToEndTest() { // Point the workspace at the installed node_modules so @aztec/* imports (and transitive deps // of the codegen'd Counter.ts) resolve to the same bundle a real user would have. - const modulesLink = join(WORKSPACE_DIR, 'node_modules'); + const modulesLink = join(WORKSPACE_DIR, "node_modules"); if (!existsSync(modulesLink)) { - symlinkSync(join(AZTEC_INSTALL_DIR, 'node_modules'), modulesLink, 'dir'); + symlinkSync(join(AZTEC_INSTALL_DIR, "node_modules"), modulesLink, "dir"); } - const testDest = join(WORKSPACE_DIR, 'counter.test.ts'); + const testDest = join(WORKSPACE_DIR, "counter.test.ts"); copyFileSync(COUNTER_TEST_TEMPLATE, testDest); - run('node', ['--no-warnings', '--test', testDest], WORKSPACE_DIR); + run("node", ["--no-warnings", "--test", testDest], WORKSPACE_DIR); } function reportFailure(stepName: string, aztecVersion: string, err: unknown) { const message = err instanceof Error ? err.message : String(err); - const childExit = typeof (err as { status?: unknown })?.status === 'number' ? (err as { status: number }).status : undefined; - const banner = '='.repeat(72); + const childExit = + typeof (err as { status?: unknown })?.status === "number" + ? (err as { status: number }).status + : undefined; + const banner = "=".repeat(72); console.error(`\n${banner}`); - console.error('AZTEC CLI ACCEPTANCE TEST FAILED'); + console.error("AZTEC CLI ACCEPTANCE TEST FAILED"); console.error(banner); console.error(`Step: ${stepName}`); console.error(`Version: ${aztecVersion}`); @@ -241,13 +271,15 @@ function reportFailure(stepName: string, aztecVersion: string, err: unknown) { console.error(`Tmp dir: ${TMP_DIR}`); console.error(`Error: ${message}`); if (err instanceof Error && err.stack) { - console.error(''); + console.error(""); console.error(err.stack); } console.error(banner); - const safeStep = stepName.replace(/\s+/g, '_'); - const safeError = message.replace(/[\r\n]+/g, ' ').slice(0, 240); - console.log(`TEST_RESULT=fail step=${safeStep} version=${aztecVersion} error="${safeError}"`); + const safeStep = stepName.replace(/\s+/g, "_"); + const safeError = message.replace(/[\r\n]+/g, " ").slice(0, 240); + console.log( + `TEST_RESULT=fail step=${safeStep} version=${aztecVersion} error="${safeError}"`, + ); } function msToSecs(ms: number): string { @@ -255,7 +287,7 @@ function msToSecs(ms: number): string { } function run(cmd: string, args: string[], cwd: string) { - execFileSync(cmd, args, { cwd, stdio: 'inherit' }); + execFileSync(cmd, args, { cwd, stdio: "inherit" }); } function log(msg: string) { @@ -276,7 +308,9 @@ function dumpTail(path: string, lines = 100) { } console.error(`--- last ${lines} lines of ${path} ---`); try { - console.error(readFileSync(path, 'utf8').split('\n').slice(-lines).join('\n')); + console.error( + readFileSync(path, "utf8").split("\n").slice(-lines).join("\n"), + ); } catch { console.error(`(failed to read ${path})`); } diff --git a/aztec-up/test/basic_install.sh b/aztec-up/test/basic_install.sh index b7973431f612..497aeda2b873 100755 --- a/aztec-up/test/basic_install.sh +++ b/aztec-up/test/basic_install.sh @@ -2,8 +2,8 @@ set -euo pipefail echo -echo "nargo version: $(nargo --version | head -1 | cut -d' ' -f4)" -echo "bb version: $(bb --version)" +echo "nargo version: $(aztec-nargo --version | head -1 | cut -d' ' -f4)" +echo "bb version: $(aztec-bb --version)" echo "aztec version: $(aztec --version)" echo "aztec-wallet version: $(aztec-wallet --version)" echo diff --git a/aztec-up/test/no_shadow_user_bins.sh b/aztec-up/test/no_shadow_user_bins.sh new file mode 100755 index 000000000000..cb0bfec5273c --- /dev/null +++ b/aztec-up/test/no_shadow_user_bins.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +# Regression test: nothing the aztec installer ships is exposed under a +# bare name on PATH. Every entry in $HOME/.aztec/current/bin is `aztec` or +# `aztec-*`. Native binaries live in current/internal-bin (off PATH) and are +# reachable only via the `aztec-*` symlinks or via the `aztec` wrapper, which +# prepends internal-bin to PATH for its subprocesses. +set -euo pipefail + +aztec_bin="$HOME/.aztec/current/bin" + +# Names this test exercises. Pre-create user-installed sentinel shims that +# print known strings, then assert bare names resolve to them after install +# (i.e. NOT shadowed by aztec). The shim directory comes AFTER the aztec bin +# on PATH, mirroring a realistic user setup where the shell PATH update was +# the last step. Names cover every bare bin the installer used to expose. +shadow_targets=( + forge cast anvil chisel + nargo noir-profiler noir-codegen + bb bb-cli + pxe txe validator-client blob-client +) +user_bin="$HOME/.local/bin" +mkdir -p "$user_bin" +for tool in "${shadow_targets[@]}"; do + printf '#!/usr/bin/env bash\necho "user-%s"\n' "$tool" > "$user_bin/$tool" + chmod +x "$user_bin/$tool" +done +export PATH="$PATH:$user_bin" + +# Bins known to support --version cleanly under the new (aztec-prefixed) layout. +runs_version=(aztec aztec-forge aztec-cast aztec-anvil aztec-chisel aztec-nargo aztec-noir-profiler) + +function assert_no_shadowing { + local tool resolved + for tool in "${shadow_targets[@]}"; do + resolved=$(command -v "$tool") + if [[ "$resolved" == "$HOME/.aztec/"* ]]; then + echo "FAIL: bare '$tool' shadowed by aztec at $resolved" + exit 1 + fi + if [[ "$("$tool")" != "user-$tool" ]]; then + echo "FAIL: bare '$tool' did not invoke user shim" + exit 1 + fi + done +} + +function assert_bin_only_aztec_prefixed { + local entry name + for entry in "$aztec_bin"/*; do + [ -e "$entry" ] || continue + name=$(basename "$entry") + if [[ "$name" != "aztec" && "$name" != aztec-* ]]; then + echo "FAIL: bare-named entry in $aztec_bin: $name" + exit 1 + fi + done +} + +function assert_aztec_bins_run { + local name resolved + for name in "${runs_version[@]}"; do + if ! resolved=$(command -v "$name"); then + echo "FAIL: $name not on PATH" + exit 1 + fi + if [[ "$resolved" != "$HOME/.aztec/"* ]]; then + echo "FAIL: $name resolves outside aztec ($resolved)" + exit 1 + fi + if ! "$name" --version >/dev/null 2>&1; then + echo "FAIL: $name --version exited non-zero" + exit 1 + fi + done +} + +assert_no_shadowing +assert_bin_only_aztec_prefixed +assert_aztec_bins_run + +echo "PASS: aztec installer does not shadow user binaries" diff --git a/docs/docs-developers/ai_tooling.md b/docs/docs-developers/ai_tooling.md index 6f4c4505cf22..601c25174d19 100644 --- a/docs/docs-developers/ai_tooling.md +++ b/docs/docs-developers/ai_tooling.md @@ -28,7 +28,7 @@ This is an Aztec smart contract project. Always use the `aztec` CLI wrapper inst - **Compile**: `aztec compile` (NOT `nargo compile`). Using `nargo compile` alone produces incomplete artifacts. - **Test**: `aztec test` (NOT `nargo test`). -- **Other nargo commands** like `nargo fmt` and `nargo doc` are fine to use directly. +- **Other nargo commands** like `aztec-nargo fmt` and `aztec-nargo doc` are fine to use directly. The Aztec installer exposes the bundled `nargo` as `aztec-nargo`; bare `nargo` resolves to your own install (if any), not the bundled one. ## Error Handling diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/functions/attributes.md b/docs/docs-developers/docs/aztec-nr/framework-description/functions/attributes.md index 8e96cbc6f9e3..15581e997f04 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/functions/attributes.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/functions/attributes.md @@ -42,10 +42,10 @@ A private function operates on private information, and is executed by the user `#[external("private")]` is just syntactic sugar. At compile time, the Aztec.nr framework inserts code that allows the function to interact with the [kernel](../../../foundational-topics/advanced/circuits/private_kernel.md). -If you are interested in what exactly the macros are doing we encourage you to run `nargo expand` on your contract. +If you are interested in what exactly the macros are doing we encourage you to run `aztec-nargo expand` on your contract. This will display your contract's code after the transformations are performed. -(If you are using VSCode you can display the expanded code by pressing `CMD + Shift + P` and typing `nargo expand` and selecting `Noir: nargo expand on current package`.) +(If you are using VSCode you can display the expanded code by pressing `CMD + Shift + P` and typing `nargo expand` and selecting `Noir: nargo expand on current package`. Make sure the Noir extension's `Nargo Path` is set to `aztec-nargo` — see the [Noir VSCode extension guide](../../installation.md) for setup.) Under the hood, the macro: @@ -85,7 +85,7 @@ Under the hood, the macro: - Wraps the function body in a scope that handles context setup and return values - Marks the function as `pub` and `unconstrained`, meaning it doesn't generate proofs and is executed directly by the sequencer -To see the exact generated code, run `nargo expand` on your contract. +To see the exact generated code, run `aztec-nargo expand` on your contract. ## Constrained `view` Functions #[view] @@ -213,7 +213,7 @@ struct CustomNote { The `owner` is passed as a runtime parameter to the `compute_note_hash` and `compute_nullifier` functions, not stored as a field on the note. -To see the exact generated code, run `nargo expand` on your contract. +To see the exact generated code, run `aztec-nargo expand` on your contract. Key things to keep in mind: @@ -246,7 +246,7 @@ struct Storage { } ``` -To see the exact generated code, run `nargo expand` on your contract. Alternatively, use `#[storage_no_init]` if you need manual control over storage slot allocation. +To see the exact generated code, run `aztec-nargo expand` on your contract. Alternatively, use `#[storage_no_init]` if you need manual control over storage slot allocation. Key things to keep in mind: diff --git a/docs/docs-developers/docs/aztec-nr/installation.md b/docs/docs-developers/docs/aztec-nr/installation.md index 7aa7a90b5a02..5eb244c3c715 100644 --- a/docs/docs-developers/docs/aztec-nr/installation.md +++ b/docs/docs-developers/docs/aztec-nr/installation.md @@ -7,22 +7,24 @@ description: Learn how to install and configure the Noir Language Server for a b Install the [Noir Language Support extension](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir) to get syntax highlighting, syntax error detection, and go-to definitions for your Aztec contracts. -The extension drives its language server with `nargo`. The Aztec installer installs its own version of `nargo` and adds that directory to your `PATH`, so in most cases you do not need to configure anything else. Verify the binary is on your `PATH`: +The extension drives its language server with `nargo`. The Aztec installer ships a bundled `nargo` and exposes it as the `aztec-nargo` symlink on your `PATH`. Bare `nargo` is intentionally not provided so it does not shadow your own install (if any). Verify the symlink is on your `PATH`: ```bash -which nargo -# expected: $HOME/.aztec/ +which aztec-nargo +# expected: $HOME/.aztec/current/bin/aztec-nargo ``` If you have not installed the Aztec toolchain yet, follow [Getting Started on Local Network](../../getting_started_on_local_network.md) first. ## Configure the extension -Leave the extension's `Noir: Nargo Path` setting empty so it auto-discovers `nargo` from your `PATH`. To confirm, hover over **Nargo** in the VSCode status bar in the bottom right corner — it should show the path under the result from `which nargo`. +Set the extension's `Noir: Nargo Path` setting to the absolute path printed by `which aztec-nargo` (for example `$HOME/.aztec/current/bin/aztec-nargo`), then reload the window. `aztec-nargo` is a symlink to the bundled `nargo`, so any tool that invokes it speaks plain `nargo` (LSP included). -If auto-discovery fails, set `Noir: Nargo Path` to the absolute path printed by `which nargo`, then reload the window. +To confirm the extension is using the bundled toolchain, hover over **Nargo** in the VSCode status bar in the bottom right corner: it should show the path you set. + +If you have your own `nargo` install and want the extension to use that instead, leave `Noir: Nargo Path` empty so the extension auto-discovers `nargo` from your `PATH`. ## Troubleshooting -- **LSP reports `startFailed` after setting a custom path**: clear `Noir: Nargo Path`, reload the window, and let auto-discovery take over. -- **`which nargo` points outside `$HOME/.aztec/current/bin`**: another `nargo` earlier on your `PATH` is shadowing the Aztec-provided one. Either remove it or set `Noir: Nargo Path` explicitly to the Aztec-provided `nargo`. +- **LSP reports `startFailed` after setting a custom path**: confirm `aztec-nargo` is executable and that the path is correct, reload the window, and check the **Output** panel for the language server log. +- **Extension picks up the wrong `nargo`**: the Aztec installer no longer puts bare `nargo` on `PATH`. Set `Noir: Nargo Path` explicitly to `aztec-nargo` (for the bundled version) or to your own install (for any other version). diff --git a/docs/docs-developers/docs/resources/glossary.md b/docs/docs-developers/docs/resources/glossary.md index eb3bae3f06d8..69c58b110e41 100644 --- a/docs/docs-developers/docs/resources/glossary.md +++ b/docs/docs-developers/docs/resources/glossary.md @@ -68,6 +68,8 @@ Merkle trees in Aztec are used to store cryptographic commitments. They are used With `nargo`, you can start new projects, compile, execute, and test your Noir programs. +The Aztec installer ships its own pinned `nargo` and exposes it as the `aztec-nargo` wrapper on `PATH` (bare `nargo` is intentionally not provided so it does not shadow your own install). For Aztec contract work, prefer `aztec compile` and `aztec test`; for plain Noir commands, use `aztec-nargo` (or your own `nargo` install). + You can find more information in the nargo installation docs [here](https://noir-lang.org/docs/getting_started/quick_start#installation) and the nargo command reference [here](https://noir-lang.org/docs/reference/nargo_commands). ### Noir diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 1d4de1cb1f6d..b651a4a07534 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -9,6 +9,37 @@ Aztec is in active development. Each version may introduce breaking changes that ## TBD +### [aztec-up] Bundled binaries are no longer exposed under bare names on `PATH` + +The Aztec installer previously placed bundled binaries directly into `$HOME/.aztec/current/bin` under bare names (`forge`, `nargo`, `bb`, `pxe`, ...). Anything with the same name in your own `PATH` was silently shadowed in unrelated projects. + +Every bundled binary is now exposed only under an `aztec-` prefixed name in `$HOME/.aztec/current/bin`. Bare names are not on `PATH` at all and resolve to your own install (if any). + +| Was on `PATH` | Now | +|---|---| +| `forge` | `aztec-forge` | +| `cast` | `aztec-cast` | +| `anvil` | `aztec-anvil` | +| `chisel` | `aztec-chisel` | +| `nargo` | `aztec-nargo` | +| `noir-profiler` | `aztec-noir-profiler` | +| `bb` | `aztec-bb` | +| `bb-cli` | `aztec-bb-cli` | +| `pxe` | `aztec-pxe` | +| `txe` | `aztec-txe` | +| `validator-client` | `aztec-validator-client` | +| `blob-client` | `aztec-blob-client` | + +`aztec`, `aztec-wallet`, and `aztec-up` keep their existing names. + +If you relied on a bundled bare-name binary for general use: + +- For Aztec contract work, prefer `aztec compile` and `aztec test`. +- For other Noir / Foundry commands, invoke the `aztec-*` symlink directly (e.g. `aztec-nargo fmt`, `aztec-forge build`). +- Or install Foundry / nargo separately via `foundryup` / `noirup`. + +If you set `Noir: Nargo Path` in the VS Code Noir extension to `$HOME/.aztec/current/bin/nargo`, change it to `$HOME/.aztec/current/bin/aztec-nargo` (the symlink is a drop-in for `nargo`). See the [Noir VSCode Extension guide](../aztec-nr/installation.md) for details. + ### [PXE] `proveTx` takes an options bag `PXE.proveTx` used to accept `scopes` as a positional argument; it now takes an options bag consistent with `simulateTx` and `profileTx`, and adds an optional `senderForTags` field. Update direct callers: diff --git a/docs/docs-developers/docs/tutorials/contract_tutorials/recursive_verification.md b/docs/docs-developers/docs/tutorials/contract_tutorials/recursive_verification.md index b01dc9199eac..684e038c289c 100644 --- a/docs/docs-developers/docs/tutorials/contract_tutorials/recursive_verification.md +++ b/docs/docs-developers/docs/tutorials/contract_tutorials/recursive_verification.md @@ -51,7 +51,7 @@ This pattern transforms arbitrarily large computations into fixed-size proof ver The recursive verification pattern follows this data flow: 1. **Circuit Definition**: Write a Noir circuit that defines the computation you want to prove -2. **Compilation**: Compile the circuit with `nargo compile` to produce bytecode +2. **Compilation**: Compile the circuit with `aztec-nargo compile` (or your own `nargo compile` install) to produce bytecode 3. **Proof Generation**: Execute the circuit offchain and generate an UltraHonk proof using [Barretenberg](https://github.com/AztecProtocol/barretenberg) 4. **Onchain Verification**: Submit the proof to an Aztec contract that verifies it using the stored [verification key](../../resources/glossary.md#verification-key) hash @@ -106,10 +106,10 @@ Start by writing a simple circuit that proves two field values are not equal. Th ### Create the Circuit Project -Use `nargo new` to generate the project structure: +Use `aztec-nargo new` to generate the project structure (the Aztec installer ships `nargo` as `aztec-nargo`; substitute your own `nargo` if its version matches `aztec-nargo --version`): ```bash -nargo new circuit +aztec-nargo new circuit ``` This creates the following structure: @@ -163,7 +163,7 @@ Update `circuit/Nargo.toml` (see [Noir crates and packages](https://noir-lang.or ```bash cd circuit -nargo compile +aztec-nargo compile ``` This generates `target/hello_circuit.json` containing: @@ -176,7 +176,7 @@ The TypeScript code uses the ABI to correctly format inputs during witness gener ### Test the Circuit ```bash -nargo test +aztec-nargo test ``` Expected output: @@ -669,7 +669,7 @@ If you want to run all commands at once, or if you're starting fresh, here's the yarn install # Compile the Noir circuit -cd circuit && nargo compile && cd .. +cd circuit && aztec-nargo compile && cd .. # Compile the Aztec contract and generate TypeScript bindings yarn ccc diff --git a/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md b/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md new file mode 100644 index 000000000000..e4b4166768eb --- /dev/null +++ b/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md @@ -0,0 +1,518 @@ +--- +title: "Deposit to Aave from Aztec" +sidebar_position: 2 +description: "Build a cross-chain DeFi integration that deposits tokens into Aave from Aztec L2 and claims yield back." +tags: [defi, cross-chain, messaging, portals, advanced] +references: ["docs/examples/contracts/aave_bridge/src/main.nr", "docs/examples/solidity/aave_bridge/AavePortal.sol", "docs/examples/ts/aave_bridge/index.ts"] +--- + +## Why DeFi from Aztec? + +Imagine you hold DAI on Aztec L2. Gas is cheap, transactions are private, but your tokens are just sitting there. What if you could deposit them into Aave on Ethereum, earn yield, and then bring those yield-bearing tokens back to Aztec? + +In this tutorial, you'll build exactly that: a **cross-chain DeFi bridge** that moves tokens between Aztec and Aave's lending pool on Ethereum. By the end, you'll understand how to compose L1 DeFi protocols with Aztec's cross-chain messaging system. + +## What You'll Build + +The diagram below shows the full round-trip, starting from tokens the user already holds on L2: + +```mermaid +graph LR + subgraph Ethereum["Ethereum (L1)"] + Portal["🌉 AavePortal"] + Aave["🏦 Aave Pool"] + end + + subgraph Aztec["Aztec (L2)"] + Bridge["🔗 AaveBridge"] + Token["🪙 Token"] + end + + Bridge -->|"1. Burn tokens"| Token + Bridge -->|"2. L2→L1 Message"| Portal + Portal -->|"3. Deposit"| Aave + + Aave -.->|"4. Withdraw + Yield"| Portal + Portal -.->|"5. L1→L2 Message"| Bridge + Bridge -.->|"6. Mint (with yield)"| Token + + style Bridge fill:#4ade80,stroke:#22c55e,stroke-width:3px + style Portal fill:#4ade80,stroke:#22c55e,stroke-width:3px + style Token fill:#f0f0f0,stroke:#999,stroke-width:2px + style Aave fill:#f0f0f0,stroke:#999,stroke-width:2px +``` + +You'll create: + +- **AaveBridge (L2)** — A Noir contract that burns/mints tokens and sends/consumes cross-chain messages +- **AavePortal (L1)** — A Solidity contract that interacts with Aave and handles L1↔L2 messaging +- **Mock Aave contracts** — Simplified mocks of Aave's lending pool for local testing +- **Integration script** — A TypeScript script that deploys everything and runs the full flow + +## Prerequisites + +- [Aztec local network running at version #include_aztec_version](../../../getting_started_on_local_network.md) (includes Aztec CLI and Node.js v24+) +- [Hardhat](https://hardhat.org/getting-started) installed for Solidity compilation and deployment +- Familiarity with the [Token Bridge tutorial](./token_bridge.md) (recommended) +- Basic understanding of [cross-chain messaging](../../foundational-topics/ethereum-aztec-messaging/index.md) + +## Understanding the Flow + +The bridge has two directions: **depositing** tokens from L2 into Aave on L1, and **claiming** them back (with yield) on L2. + +### Deposit Flow (L2 → Aave) + +```mermaid +sequenceDiagram + participant User + participant Bridge as AaveBridge (L2) + participant Token as Token (L2) + participant Outbox as Outbox + participant Portal as AavePortal (L1) + participant Aave as Aave Pool (L1) + + User->>Bridge: exit_to_l1_public(amount) + Bridge->>Outbox: message_portal(content) + Bridge->>Token: burn_public(user, amount) + Note over Outbox: Wait for epoch to be submitted to L1 + User->>Portal: depositToAave(amount, proof) + Portal->>Outbox: consume(message) + Portal->>Aave: supply(underlying, amount) + Aave-->>Portal: aTokens +``` + +### Claim Flow (Aave → L2) + +```mermaid +sequenceDiagram + participant User + participant Portal as AavePortal (L1) + participant Aave as Aave Pool (L1) + participant Inbox as Inbox + participant Bridge as AaveBridge (L2) + participant Token as Token (L2) + + User->>Portal: claimFromAavePublic(aTokenAmount) + Portal->>Aave: withdraw(aTokenAmount) + Aave-->>Portal: underlying + yield + Portal->>Inbox: sendL2Message(content) + Note over Inbox: Wait for 2 L2 blocks (required for L1→L2 message availability) + User->>Bridge: claim_public(amount_with_yield) + Bridge->>Inbox: consume_l1_to_l2_message + Bridge->>Token: mint_to_public(user, amount_with_yield) +``` + +## Project Setup + +Start with the Hardhat + Aztec template. This provides a pre-configured Hardhat project with Aztec dependencies and Solidity compilation settings: + +:::note + +This template is a community-maintained starter. If the repository is unavailable, you can set up a Hardhat project manually and add the `@aztec/*` Solidity remappings from the [cross-chain messaging docs](../../foundational-topics/ethereum-aztec-messaging/index.md). + +You may need to update the `@aztec/l1-contracts` tag in the template's `package.json` to match your Aztec version, e.g.: + +```json +"@aztec/l1-contracts": "git+https://github.com/AztecProtocol/l1-contracts.git#v5.0.0-nightly.20260311" +``` + +::: + +```bash +git clone https://github.com/critesjosh/hardhat-aztec-example +cd hardhat-aztec-example +``` + +When complete, your project will have this structure: + +``` +hardhat-aztec-example/ + contracts/ # Solidity contracts (Hardhat default) + MockERC20.sol + MockAToken.sol + MockAavePool.sol + AavePortal.sol + contracts/aztec/ # Noir contracts + aave_bridge/ + contract/src/main.nr + contract/src/config.nr + contract/Nargo.toml + aave_bridge_test/ + src/Nargo.toml + src/lib.nr + scripts/ + index.ts # Integration script + artifacts/ # Generated by aztec codegen +``` + +Add the Aztec dependencies: + +```bash +yarn add @aztec/aztec.js@#include_version_without_prefix @aztec/accounts@#include_version_without_prefix @aztec/wallets@#include_version_without_prefix @aztec/stdlib@#include_version_without_prefix @aztec/foundation@#include_version_without_prefix @aztec/ethereum@#include_version_without_prefix @aztec/noir-contracts.js@#include_version_without_prefix @aztec/viem@2.38.2 tsx +``` + +Start the local network in another terminal: + +```bash +aztec start --local-network +``` + +## Part 1: The L2 Bridge Contract + +The L2 bridge is the simpler side. It doesn't know anything about Aave — it just burns/mints tokens and passes messages. All the Aave-specific logic lives on L1. + +:::note +The L2 bridge is intentionally protocol-agnostic — it just burns/mints tokens and relays messages. All Aave-specific logic lives on L1. This means you can compose with any L1 protocol without changing your L2 contract. If you've completed the [Token Bridge tutorial](./token_bridge.md), you'll recognize the pattern and can skim to [Part 2](#part-2-the-ethereum-side). +::: + +Create the bridge contract: + +```bash +aztec new contracts/aztec/aave_bridge +cd contracts/aztec/aave_bridge +``` + +The `aztec new` command creates a workspace with a `contract` crate and a `test` crate. Replace the generated test file at `test/src/lib.nr` with a basic constructor test: + +```rust +use aztec::protocol::address::{AztecAddress, EthAddress}; +use aztec::protocol::traits::FromField; +use aztec::test::helpers::test_environment::TestEnvironment; +use aave_bridge::AaveBridge; + +#[test] +unconstrained fn test_constructor() { + let mut env = TestEnvironment::new(); + let deployer = env.create_light_account(); + + let token = AztecAddress::from_field(1); + let portal = EthAddress::from_field(2); + + let initializer = AaveBridge::interface().constructor(token, portal); + let _contract_address = + env.deploy("@aave_bridge/AaveBridge").with_public_initializer(deployer, initializer); +} +``` + +The bridge reuses the existing `Token` contract and the `token_portal_content_hash_lib` for content hash functions. Add these dependencies to `contracts/aztec/aave_bridge/aave_bridge_contract/Nargo.toml`: + +```toml +[dependencies] +aztec = { git="https://github.com/AztecProtocol/aztec-packages", tag = "#include_aztec_version", directory = "noir-projects/aztec-nr/aztec" } +token_portal_content_hash_lib = { git="https://github.com/AztecProtocol/aztec-packages", tag = "#include_aztec_version", directory = "noir-projects/noir-contracts/contracts/libs/token_portal_content_hash_lib" } +token = { git="https://github.com/AztecProtocol/aztec-packages", tag = "#include_aztec_version", directory = "noir-projects/noir-contracts/contracts/app/token_contract" } +``` + +### Bridge Storage + +The bridge stores two things: the L2 token address and the L1 portal address. First, create the config module at `contracts/aztec/aave_bridge/aave_bridge_contract/src/config.nr`: + +#include_code config /docs/examples/contracts/aave_bridge/src/config.nr rust + +Then replace `contracts/aztec/aave_bridge/aave_bridge_contract/src/main.nr`: + + + +```rust +#include_code bridge_setup /docs/examples/contracts/aave_bridge/src/main.nr raw +} +``` + +:::warning Assembling the Contract +The code above shows the contract opening — imports, storage, constructor, and a getter — followed by a closing `}`. In the sections below, you'll add more functions **inside** this contract body. Place them before the final `}` so they are part of `pub contract AaveBridge { ... }`. +::: + +### Public Claim and Exit + +Add the following functions inside the `AaveBridge` contract body (before the closing `}`). `claim_public` consumes an L1→L2 message and mints tokens. `exit_to_l1_public` burns tokens and sends an L2→L1 message: + +#include_code claim_public /docs/examples/contracts/aave_bridge/src/main.nr rust + +#include_code exit_to_l1_public /docs/examples/contracts/aave_bridge/src/main.nr rust + +The `authwit_nonce` parameter supports [authentication witnesses](../../aztec-js/how_to_use_authwit.md). When the caller is the token owner (`msg.sender`), pass `0` — no authorization witness is needed. If a third party calls this function on behalf of the owner, they must provide a valid nonce from an authwit the owner previously created. + +### Private Claim and Exit + +Still inside the contract body, add the private variants. They work the same way but use private token operations. The recipient's address is hidden when claiming privately: + +#include_code claim_private /docs/examples/contracts/aave_bridge/src/main.nr rust + +#include_code exit_to_l1_private /docs/examples/contracts/aave_bridge/src/main.nr rust + +:::info Content Hash Matching + +The content hash is the critical link between L1 and L2. Both sides must produce the exact same hash for a message to be consumed. The `token_portal_content_hash_lib` handles this by encoding parameters identically to the Solidity side's `abi.encodeWithSignature`. For example, `get_mint_to_public_content_hash(to, amount)` on L2 matches `Hash.sha256ToField(abi.encodeWithSignature("mint_to_public(bytes32,uint256)", to, amount))` on L1. + +::: + +### Compile + +```bash +aztec compile +``` + +Generate TypeScript bindings: + +```bash +aztec codegen target --outdir ../artifacts +``` + +:::note Token Contract +The integration script imports `TokenContract` from `@aztec/noir-contracts.js`, which provides pre-built bindings for the standard Token contract. Only the custom `AaveBridge` contract needs codegen. +::: + +## Part 2: The Ethereum Side + +### Mock Aave Contracts + +For local testing, you'll use simplified mocks of Aave's lending pool. The mock pool accepts deposits and returns them with a configurable yield — 10% in this tutorial (1000 basis points, where 10000 bps = 100%). + +:::tip Mock vs Real Aave + +In production, replace `MockAavePool` with Aave V3's `IPool` interface at `0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2` (Ethereum mainnet). The portal contract's `IAavePool` interface already matches Aave V3's function signatures. For realistic testing, fork mainnet with `aztec-anvil --fork-url ` (the Aztec installer ships Foundry's `anvil` as `aztec-anvil`; substitute your own `anvil` if its version matches `aztec-anvil --version`). + +::: + +Create the following mock contracts in `contracts/`. + +`contracts/MockERC20.sol` — a minimal ERC20 with public minting: + +```solidity +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +#include_code mock_erc20 /docs/examples/solidity/aave_bridge/MockERC20.sol raw +``` + +`contracts/MockAToken.sol` — Aave's yield-bearing token mock: + +```solidity +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +#include_code mock_atoken /docs/examples/solidity/aave_bridge/MockAToken.sol raw +``` + +`contracts/MockAavePool.sol` — simplified Aave lending pool that returns a configurable yield: + +```solidity +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {MockERC20} from "./MockERC20.sol"; +import {MockAToken} from "./MockAToken.sol"; + +#include_code mock_aave_pool /docs/examples/solidity/aave_bridge/MockAavePool.sol raw +``` + +### AavePortal Contract + +The portal is where the magic happens. It bridges Aztec's cross-chain messages with Aave's lending pool. Create `contracts/AavePortal.sol`: + + + +```solidity +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +import {IRegistry} from "@aztec/l1-contracts/src/governance/interfaces/IRegistry.sol"; +import {IInbox} from "@aztec/l1-contracts/src/core/interfaces/messagebridge/IInbox.sol"; +import {IOutbox} from "@aztec/l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol"; +import {IRollup} from "@aztec/l1-contracts/src/core/interfaces/IRollup.sol"; +import {DataStructures} from "@aztec/l1-contracts/src/core/libraries/DataStructures.sol"; +import {Hash} from "@aztec/l1-contracts/src/core/libraries/crypto/Hash.sol"; +import {Epoch} from "@aztec/l1-contracts/src/core/libraries/TimeLib.sol"; + +#include_code portal_setup /docs/examples/solidity/aave_bridge/AavePortal.sol raw +} +``` + +:::warning Assembling the Contract +Like the L2 contract, the code above shows the contract opening — imports, state variables, and `initialize()`. The subsequent function snippets go **inside** this contract body, before the closing `}`. +::: + +The portal has three key functions. First, `depositToAave` consumes an L2→L1 message (proving the user burned tokens on L2) and deposits the underlying tokens into Aave: + +#include_code portal_deposit_to_aave /docs/examples/solidity/aave_bridge/AavePortal.sol solidity + +Then, `claimFromAavePublic` withdraws from Aave (including any yield earned) and sends an L1→L2 message so the user can mint tokens on L2: + +#include_code portal_claim_public /docs/examples/solidity/aave_bridge/AavePortal.sol solidity + +There's also a private variant that lets the user claim without revealing their L2 address: + +#include_code portal_claim_private /docs/examples/solidity/aave_bridge/AavePortal.sol solidity + +### Compile + +```bash +npx hardhat compile +``` + +:::note Solidity Artifact Paths +Hardhat compiles Solidity contracts to `artifacts/contracts/` by default. The integration script imports ABIs from this location (e.g., `../artifacts/contracts/AavePortal.sol/AavePortal.json`). +::: + +## Part 3: Deploying and Testing + +Create `scripts/index.ts` to run the full flow. This script deploys all contracts, initializes them, deposits tokens into Aave from L2, and claims them back with yield. + +### Setup + +```typescript +import { getInitialTestAccountsData } from "@aztec/accounts/testing"; +import { AztecAddress, EthAddress } from "@aztec/aztec.js/addresses"; +import { SetPublicAuthwitContractInteraction } from "@aztec/aztec.js/authorization"; +import { Fr } from "@aztec/aztec.js/fields"; +import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node"; +import { createExtendedL1Client } from "@aztec/ethereum/client"; +import { deployL1Contract } from "@aztec/ethereum/deploy-l1-contract"; +import { sha256ToField } from "@aztec/foundation/crypto/sha256"; +import { + computeL2ToL1MessageHash, + computeSecretHash, +} from "@aztec/stdlib/hash"; +import { computeL2ToL1MembershipWitness } from "@aztec/stdlib/messaging"; +import { EmbeddedWallet } from "@aztec/wallets/embedded"; +import { decodeEventLog, pad, toFunctionSelector } from "@aztec/viem"; +import { foundry } from "@aztec/viem/chains"; +import AavePortal from "../artifacts/contracts/AavePortal.sol/AavePortal.json" with { type: "json" }; +import MockERC20 from "../artifacts/contracts/MockERC20.sol/MockERC20.json" with { type: "json" }; +import MockAToken from "../artifacts/contracts/MockAToken.sol/MockAToken.json" with { type: "json" }; +import MockAavePool from "../artifacts/contracts/MockAavePool.sol/MockAavePool.json" with { type: "json" }; +import { TokenContract } from "@aztec/noir-contracts.js/Token"; +import { AaveBridgeContract } from "../contracts/aztec/artifacts/AaveBridge.js"; + +#include_code setup /docs/examples/ts/aave_bridge/index.ts raw +``` + +:::note About EmbeddedWallet +`EmbeddedWallet` is a simplified wallet for local development. It handles key management, transaction signing, and proof generation in-process. Code written against `EmbeddedWallet` works with any `Wallet` implementation, so your application logic transfers directly to production. +::: + +### Deploy L1 Contracts + +#include_code deploy_l1 /docs/examples/ts/aave_bridge/index.ts typescript + +### Deploy L2 Contracts + +#include_code deploy_l2 /docs/examples/ts/aave_bridge/index.ts typescript + +### Initialize + +#include_code initialize /docs/examples/ts/aave_bridge/index.ts typescript + +### Fund the User + +For this tutorial, you need tokens in two places: + +- **L2 tokens for the user** — The user needs tokens on L2 to burn and bridge to L1. In production, these would come from a prior bridge operation. +- **L1 underlying tokens at the portal** — When the portal calls `depositToAave`, it transfers underlying tokens to Aave. The portal must already hold these tokens. In production, the tokens would arrive via a separate bridging mechanism. + +For simplicity, mint directly to both: + +#include_code fund_user /docs/examples/ts/aave_bridge/index.ts typescript + +### Deposit to Aave (L2 → L1) + +Now for the main flow. Burn tokens on L2 and send a message to L1. + +:::info Why is the portal the recipient? +The `recipient` in `exit_to_l1_public` is the L1 address that receives the withdrawal message. Since the AavePortal contract needs to deposit the tokens into Aave, the portal itself is the recipient. Setting `caller_on_l1` to `EthAddress.ZERO` means anyone can relay the message on L1 — there's no access restriction on who calls `depositToAave`. +::: + +#include_code deposit_to_aave /docs/examples/ts/aave_bridge/index.ts typescript + +Compute the membership witness to prove the message on L1: + +#include_code get_deposit_witness /docs/examples/ts/aave_bridge/index.ts typescript + +Execute the deposit on L1: + +#include_code execute_deposit_l1 /docs/examples/ts/aave_bridge/index.ts typescript + +### Claim from Aave with Yield (L1 → L2) + +Before withdrawing from Aave, generate a random secret and compute its hash. The secret hash is included in the L1-to-L2 message — only someone who knows the pre-image (the secret) can consume the message on L2. This prevents front-running: without the secret, no one else can claim your tokens. + +Withdraw from Aave on L1 and send the message to L2. The mock pool returns 10% yield: + +#include_code claim_from_aave_l1 /docs/examples/ts/aave_bridge/index.ts typescript + +Extract the message leaf index: + +#include_code get_claim_leaf_index /docs/examples/ts/aave_bridge/index.ts typescript + +On the local network, L2 blocks are only produced when transactions are submitted. L1-to-L2 messages require 2 L2 blocks before they can be consumed on L2. This utility deploys two dummy contracts (with random salts for unique addresses) to force block production. On devnet or testnet, blocks are produced continuously and this step is unnecessary: + +#include_code mine_blocks /docs/examples/ts/aave_bridge/index.ts typescript + +Claim the tokens (with yield) on L2: + +#include_code claim_on_l2 /docs/examples/ts/aave_bridge/index.ts typescript + +### Verify + +#include_code verify /docs/examples/ts/aave_bridge/index.ts typescript + +Run the full flow: + +```bash +npx hardhat run scripts/index.ts --network localhost +``` + +You should see the user start with 1000 tokens, deposit 500 to Aave, and end up with 1050 tokens (500 remaining + 550 from Aave with 10% yield). + +## What You Built + +A complete cross-chain DeFi integration with: + +1. **L2 Bridge** (Noir) — Burns/mints tokens and handles cross-chain messages. Supports both public and private operations. +2. **L1 Portal** (Solidity) — Deposits into Aave and withdraws with yield. Handles message consumption and creation. +3. **Mock Aave** (Solidity) — Simulates yield generation for local testing. +4. **Full Flow** — Deposit tokens from L2 into Aave, earn yield, and claim back on L2. + +:::warning Production Considerations + +This tutorial uses mock contracts for simplicity. In production: + +- Replace `MockAavePool` with a real Aave V3 pool address +- Handle Aave's variable interest rates (the withdrawn amount may differ from expectations) +- Add slippage protection and error handling for failed messages +- Consider that funds are "in flight" between chains — implement recovery mechanisms +- Add proper access controls to the portal contract + +::: + +## Troubleshooting + +### Script hangs waiting for block to be published + +The deposit flow waits for the L2 block containing your exit transaction to be included in an epoch that is submitted to L1. On the local network, this typically takes 30–60 seconds. If it takes longer, check that your local network is running and producing blocks. + +### Content hash mismatch — L1 message consumption reverts + +This is the most common cross-chain debugging issue. The content hash computed on L2 (via `get_withdraw_content_hash`) must exactly match what the L1 portal reconstructs via `abi.encodeWithSignature`. Double-check that: +- The function signature string matches on both sides (e.g., `"withdraw(address,uint256,address)"`) +- Parameters are in the same order and encoded as the same types +- The `caller_on_l1` value matches: `EthAddress.ZERO` on L2 corresponds to `address(0)` on L1 + +### "Minter not set" — L2 claim fails + +If `claim_public` reverts, ensure you called `set_minter(l2Bridge.address, true)` on the Token contract **after** deploying the bridge. The bridge must be authorized as a minter before it can mint tokens on claim. + +### L1→L2 message not found — claim reverts after mining blocks + +L1-to-L2 messages need 2 L2 blocks after the L1 transaction before they become consumable. Make sure `mine2Blocks` runs before the claim. If the issue persists, verify the `messageLeafIndex` extracted from the `MessageSent` event is correct. + +## Next Steps + +- **Test with a mainnet fork**: Use `aztec-anvil --fork-url` (or your own `anvil` install) to test against real Aave +- **Add private deposits**: Use the `claim_private` and `exit_to_l1_private` functions for privacy-preserving DeFi +- **Build a frontend**: Add a web UI for easy depositing and claiming +- **Compose with other protocols**: The same pattern works for Uniswap, Compound, or any L1 DeFi protocol + +:::tip Learn More + +- [Cross-chain messaging](../../foundational-topics/ethereum-aztec-messaging/index.md) +- [Token Bridge Tutorial](./token_bridge.md) +- [State management](../../foundational-topics/state_management.md) + +::: diff --git a/docs/docs-developers/docs/tutorials/testing_governance_rollup_upgrade.md b/docs/docs-developers/docs/tutorials/testing_governance_rollup_upgrade.md index a19a4bf0e1f9..7ec7b92ca825 100644 --- a/docs/docs-developers/docs/tutorials/testing_governance_rollup_upgrade.md +++ b/docs/docs-developers/docs/tutorials/testing_governance_rollup_upgrade.md @@ -70,8 +70,10 @@ git clone --depth 1 https://github.com/foundry-rs/forge-std forge-std git clone --depth 1 https://github.com/OpenZeppelin/openzeppelin-contracts openzeppelin-contracts cd .. -# Install solc (uses forge's built-in svm) -forge build --use 0.8.30 src/core/libraries/ConstantsGen.sol +# Install solc (uses forge's built-in svm). The Aztec installer ships +# Foundry as `aztec-forge`/`aztec-cast`/`aztec-anvil` -- substitute your +# own `forge` install if you have one. +aztec-forge build --use 0.8.30 src/core/libraries/ConstantsGen.sol cp ~/.svm/0.8.30/solc-0.8.30 ./solc-0.8.30 # Copy the HonkVerifier to the generated directory (required for build) @@ -130,7 +132,7 @@ export AZTEC_INITIAL_ETH_PER_FEE_ASSET=10000000 ## Step 4: Deploy New Rollup ```bash -forge script script/deploy/DeployRollupForUpgrade.s.sol:DeployRollupForUpgrade \ +aztec-forge script script/deploy/DeployRollupForUpgrade.s.sol:DeployRollupForUpgrade \ --rpc-url $L1_RPC_URL \ --broadcast \ --private-key $PRIVATE_KEY @@ -151,7 +153,7 @@ export NEW_ROLLUP_ADDRESS=0x... ```bash cd l1-contracts -forge create \ +aztec-forge create \ --rpc-url $L1_RPC_URL \ --private-key $PRIVATE_KEY \ --broadcast \ @@ -376,7 +378,7 @@ If you just want to test the governance flow without deploying a real rollup: cd l1-contracts # Deploy empty payload (no constructor args needed) -forge create \ +aztec-forge create \ --rpc-url $L1_RPC_URL \ --private-key $PRIVATE_KEY \ --broadcast \ diff --git a/docs/docs-developers/getting_started_on_local_network.md b/docs/docs-developers/getting_started_on_local_network.md index b390b3f39838..3a4dbbdb0c55 100644 --- a/docs/docs-developers/getting_started_on_local_network.md +++ b/docs/docs-developers/getting_started_on_local_network.md @@ -39,17 +39,19 @@ import { General, Fees } from '@site/src/components/Snippets/general_snippets'; Run: ```bash -VERSION=#include_version_without_prefix bash -i <(curl -sL https://install.aztec.network/#include_version_without_prefix) +VERSION=#include_version_without_prefix bash -i <(curl -sL https://install.aztec.network) ``` This will install the following tools and add them to your `PATH`: -- **nargo** - the Noir programming language compiler and simulator -- **noir-profiler** - a profiler for analyzing and visualizing Noir programs -- **bb** - the Barretenberg proving backend - **aztec** - compiles and tests Aztec contracts and launches various infrastructure subsystems (full local network, sequencer, prover, PXE, etc.) and provides utility commands to interact with the network - **aztec-up** - a version manager for the Aztec toolchain. Use `aztec-up install ` to install a new version, `aztec-up use ` to switch between installed versions, or `aztec-up list` to see installed versions. - **aztec-wallet** - a tool for interacting with the Aztec network +- **aztec-bb** - the Barretenberg proving backend +- **aztec-nargo** - the Noir compiler and simulator +- **aztec-forge**, **aztec-cast**, **aztec-anvil**, **aztec-chisel** - the bundled Foundry tools + +Foundry, Noir, and Barretenberg are bundled at the versions `aztec` needs. Your own `forge` / `nargo` / `bb` installs still work under their bare names. For syntax highlighting and LSP support while editing contracts, see the [Noir VSCode Extension guide](./docs/aztec-nr/installation.md). From d7c6d1495fb98f603c10cb4953b4d5e0ff01ff02 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Thu, 7 May 2026 18:41:48 +0000 Subject: [PATCH 03/30] fix: resolve cherry-pick conflicts aave_bridge.md was deleted on backport-to-v4-next-staging but modified by the cherry-pick. Drop the file to match the target branch state. --- .../tutorials/js_tutorials/aave_bridge.md | 518 ------------------ 1 file changed, 518 deletions(-) delete mode 100644 docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md diff --git a/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md b/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md deleted file mode 100644 index e4b4166768eb..000000000000 --- a/docs/docs-developers/docs/tutorials/js_tutorials/aave_bridge.md +++ /dev/null @@ -1,518 +0,0 @@ ---- -title: "Deposit to Aave from Aztec" -sidebar_position: 2 -description: "Build a cross-chain DeFi integration that deposits tokens into Aave from Aztec L2 and claims yield back." -tags: [defi, cross-chain, messaging, portals, advanced] -references: ["docs/examples/contracts/aave_bridge/src/main.nr", "docs/examples/solidity/aave_bridge/AavePortal.sol", "docs/examples/ts/aave_bridge/index.ts"] ---- - -## Why DeFi from Aztec? - -Imagine you hold DAI on Aztec L2. Gas is cheap, transactions are private, but your tokens are just sitting there. What if you could deposit them into Aave on Ethereum, earn yield, and then bring those yield-bearing tokens back to Aztec? - -In this tutorial, you'll build exactly that: a **cross-chain DeFi bridge** that moves tokens between Aztec and Aave's lending pool on Ethereum. By the end, you'll understand how to compose L1 DeFi protocols with Aztec's cross-chain messaging system. - -## What You'll Build - -The diagram below shows the full round-trip, starting from tokens the user already holds on L2: - -```mermaid -graph LR - subgraph Ethereum["Ethereum (L1)"] - Portal["🌉 AavePortal"] - Aave["🏦 Aave Pool"] - end - - subgraph Aztec["Aztec (L2)"] - Bridge["🔗 AaveBridge"] - Token["🪙 Token"] - end - - Bridge -->|"1. Burn tokens"| Token - Bridge -->|"2. L2→L1 Message"| Portal - Portal -->|"3. Deposit"| Aave - - Aave -.->|"4. Withdraw + Yield"| Portal - Portal -.->|"5. L1→L2 Message"| Bridge - Bridge -.->|"6. Mint (with yield)"| Token - - style Bridge fill:#4ade80,stroke:#22c55e,stroke-width:3px - style Portal fill:#4ade80,stroke:#22c55e,stroke-width:3px - style Token fill:#f0f0f0,stroke:#999,stroke-width:2px - style Aave fill:#f0f0f0,stroke:#999,stroke-width:2px -``` - -You'll create: - -- **AaveBridge (L2)** — A Noir contract that burns/mints tokens and sends/consumes cross-chain messages -- **AavePortal (L1)** — A Solidity contract that interacts with Aave and handles L1↔L2 messaging -- **Mock Aave contracts** — Simplified mocks of Aave's lending pool for local testing -- **Integration script** — A TypeScript script that deploys everything and runs the full flow - -## Prerequisites - -- [Aztec local network running at version #include_aztec_version](../../../getting_started_on_local_network.md) (includes Aztec CLI and Node.js v24+) -- [Hardhat](https://hardhat.org/getting-started) installed for Solidity compilation and deployment -- Familiarity with the [Token Bridge tutorial](./token_bridge.md) (recommended) -- Basic understanding of [cross-chain messaging](../../foundational-topics/ethereum-aztec-messaging/index.md) - -## Understanding the Flow - -The bridge has two directions: **depositing** tokens from L2 into Aave on L1, and **claiming** them back (with yield) on L2. - -### Deposit Flow (L2 → Aave) - -```mermaid -sequenceDiagram - participant User - participant Bridge as AaveBridge (L2) - participant Token as Token (L2) - participant Outbox as Outbox - participant Portal as AavePortal (L1) - participant Aave as Aave Pool (L1) - - User->>Bridge: exit_to_l1_public(amount) - Bridge->>Outbox: message_portal(content) - Bridge->>Token: burn_public(user, amount) - Note over Outbox: Wait for epoch to be submitted to L1 - User->>Portal: depositToAave(amount, proof) - Portal->>Outbox: consume(message) - Portal->>Aave: supply(underlying, amount) - Aave-->>Portal: aTokens -``` - -### Claim Flow (Aave → L2) - -```mermaid -sequenceDiagram - participant User - participant Portal as AavePortal (L1) - participant Aave as Aave Pool (L1) - participant Inbox as Inbox - participant Bridge as AaveBridge (L2) - participant Token as Token (L2) - - User->>Portal: claimFromAavePublic(aTokenAmount) - Portal->>Aave: withdraw(aTokenAmount) - Aave-->>Portal: underlying + yield - Portal->>Inbox: sendL2Message(content) - Note over Inbox: Wait for 2 L2 blocks (required for L1→L2 message availability) - User->>Bridge: claim_public(amount_with_yield) - Bridge->>Inbox: consume_l1_to_l2_message - Bridge->>Token: mint_to_public(user, amount_with_yield) -``` - -## Project Setup - -Start with the Hardhat + Aztec template. This provides a pre-configured Hardhat project with Aztec dependencies and Solidity compilation settings: - -:::note - -This template is a community-maintained starter. If the repository is unavailable, you can set up a Hardhat project manually and add the `@aztec/*` Solidity remappings from the [cross-chain messaging docs](../../foundational-topics/ethereum-aztec-messaging/index.md). - -You may need to update the `@aztec/l1-contracts` tag in the template's `package.json` to match your Aztec version, e.g.: - -```json -"@aztec/l1-contracts": "git+https://github.com/AztecProtocol/l1-contracts.git#v5.0.0-nightly.20260311" -``` - -::: - -```bash -git clone https://github.com/critesjosh/hardhat-aztec-example -cd hardhat-aztec-example -``` - -When complete, your project will have this structure: - -``` -hardhat-aztec-example/ - contracts/ # Solidity contracts (Hardhat default) - MockERC20.sol - MockAToken.sol - MockAavePool.sol - AavePortal.sol - contracts/aztec/ # Noir contracts - aave_bridge/ - contract/src/main.nr - contract/src/config.nr - contract/Nargo.toml - aave_bridge_test/ - src/Nargo.toml - src/lib.nr - scripts/ - index.ts # Integration script - artifacts/ # Generated by aztec codegen -``` - -Add the Aztec dependencies: - -```bash -yarn add @aztec/aztec.js@#include_version_without_prefix @aztec/accounts@#include_version_without_prefix @aztec/wallets@#include_version_without_prefix @aztec/stdlib@#include_version_without_prefix @aztec/foundation@#include_version_without_prefix @aztec/ethereum@#include_version_without_prefix @aztec/noir-contracts.js@#include_version_without_prefix @aztec/viem@2.38.2 tsx -``` - -Start the local network in another terminal: - -```bash -aztec start --local-network -``` - -## Part 1: The L2 Bridge Contract - -The L2 bridge is the simpler side. It doesn't know anything about Aave — it just burns/mints tokens and passes messages. All the Aave-specific logic lives on L1. - -:::note -The L2 bridge is intentionally protocol-agnostic — it just burns/mints tokens and relays messages. All Aave-specific logic lives on L1. This means you can compose with any L1 protocol without changing your L2 contract. If you've completed the [Token Bridge tutorial](./token_bridge.md), you'll recognize the pattern and can skim to [Part 2](#part-2-the-ethereum-side). -::: - -Create the bridge contract: - -```bash -aztec new contracts/aztec/aave_bridge -cd contracts/aztec/aave_bridge -``` - -The `aztec new` command creates a workspace with a `contract` crate and a `test` crate. Replace the generated test file at `test/src/lib.nr` with a basic constructor test: - -```rust -use aztec::protocol::address::{AztecAddress, EthAddress}; -use aztec::protocol::traits::FromField; -use aztec::test::helpers::test_environment::TestEnvironment; -use aave_bridge::AaveBridge; - -#[test] -unconstrained fn test_constructor() { - let mut env = TestEnvironment::new(); - let deployer = env.create_light_account(); - - let token = AztecAddress::from_field(1); - let portal = EthAddress::from_field(2); - - let initializer = AaveBridge::interface().constructor(token, portal); - let _contract_address = - env.deploy("@aave_bridge/AaveBridge").with_public_initializer(deployer, initializer); -} -``` - -The bridge reuses the existing `Token` contract and the `token_portal_content_hash_lib` for content hash functions. Add these dependencies to `contracts/aztec/aave_bridge/aave_bridge_contract/Nargo.toml`: - -```toml -[dependencies] -aztec = { git="https://github.com/AztecProtocol/aztec-packages", tag = "#include_aztec_version", directory = "noir-projects/aztec-nr/aztec" } -token_portal_content_hash_lib = { git="https://github.com/AztecProtocol/aztec-packages", tag = "#include_aztec_version", directory = "noir-projects/noir-contracts/contracts/libs/token_portal_content_hash_lib" } -token = { git="https://github.com/AztecProtocol/aztec-packages", tag = "#include_aztec_version", directory = "noir-projects/noir-contracts/contracts/app/token_contract" } -``` - -### Bridge Storage - -The bridge stores two things: the L2 token address and the L1 portal address. First, create the config module at `contracts/aztec/aave_bridge/aave_bridge_contract/src/config.nr`: - -#include_code config /docs/examples/contracts/aave_bridge/src/config.nr rust - -Then replace `contracts/aztec/aave_bridge/aave_bridge_contract/src/main.nr`: - - - -```rust -#include_code bridge_setup /docs/examples/contracts/aave_bridge/src/main.nr raw -} -``` - -:::warning Assembling the Contract -The code above shows the contract opening — imports, storage, constructor, and a getter — followed by a closing `}`. In the sections below, you'll add more functions **inside** this contract body. Place them before the final `}` so they are part of `pub contract AaveBridge { ... }`. -::: - -### Public Claim and Exit - -Add the following functions inside the `AaveBridge` contract body (before the closing `}`). `claim_public` consumes an L1→L2 message and mints tokens. `exit_to_l1_public` burns tokens and sends an L2→L1 message: - -#include_code claim_public /docs/examples/contracts/aave_bridge/src/main.nr rust - -#include_code exit_to_l1_public /docs/examples/contracts/aave_bridge/src/main.nr rust - -The `authwit_nonce` parameter supports [authentication witnesses](../../aztec-js/how_to_use_authwit.md). When the caller is the token owner (`msg.sender`), pass `0` — no authorization witness is needed. If a third party calls this function on behalf of the owner, they must provide a valid nonce from an authwit the owner previously created. - -### Private Claim and Exit - -Still inside the contract body, add the private variants. They work the same way but use private token operations. The recipient's address is hidden when claiming privately: - -#include_code claim_private /docs/examples/contracts/aave_bridge/src/main.nr rust - -#include_code exit_to_l1_private /docs/examples/contracts/aave_bridge/src/main.nr rust - -:::info Content Hash Matching - -The content hash is the critical link between L1 and L2. Both sides must produce the exact same hash for a message to be consumed. The `token_portal_content_hash_lib` handles this by encoding parameters identically to the Solidity side's `abi.encodeWithSignature`. For example, `get_mint_to_public_content_hash(to, amount)` on L2 matches `Hash.sha256ToField(abi.encodeWithSignature("mint_to_public(bytes32,uint256)", to, amount))` on L1. - -::: - -### Compile - -```bash -aztec compile -``` - -Generate TypeScript bindings: - -```bash -aztec codegen target --outdir ../artifacts -``` - -:::note Token Contract -The integration script imports `TokenContract` from `@aztec/noir-contracts.js`, which provides pre-built bindings for the standard Token contract. Only the custom `AaveBridge` contract needs codegen. -::: - -## Part 2: The Ethereum Side - -### Mock Aave Contracts - -For local testing, you'll use simplified mocks of Aave's lending pool. The mock pool accepts deposits and returns them with a configurable yield — 10% in this tutorial (1000 basis points, where 10000 bps = 100%). - -:::tip Mock vs Real Aave - -In production, replace `MockAavePool` with Aave V3's `IPool` interface at `0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2` (Ethereum mainnet). The portal contract's `IAavePool` interface already matches Aave V3's function signatures. For realistic testing, fork mainnet with `aztec-anvil --fork-url ` (the Aztec installer ships Foundry's `anvil` as `aztec-anvil`; substitute your own `anvil` if its version matches `aztec-anvil --version`). - -::: - -Create the following mock contracts in `contracts/`. - -`contracts/MockERC20.sol` — a minimal ERC20 with public minting: - -```solidity -import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -#include_code mock_erc20 /docs/examples/solidity/aave_bridge/MockERC20.sol raw -``` - -`contracts/MockAToken.sol` — Aave's yield-bearing token mock: - -```solidity -import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -#include_code mock_atoken /docs/examples/solidity/aave_bridge/MockAToken.sol raw -``` - -`contracts/MockAavePool.sol` — simplified Aave lending pool that returns a configurable yield: - -```solidity -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {MockERC20} from "./MockERC20.sol"; -import {MockAToken} from "./MockAToken.sol"; - -#include_code mock_aave_pool /docs/examples/solidity/aave_bridge/MockAavePool.sol raw -``` - -### AavePortal Contract - -The portal is where the magic happens. It bridges Aztec's cross-chain messages with Aave's lending pool. Create `contracts/AavePortal.sol`: - - - -```solidity -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -import {IRegistry} from "@aztec/l1-contracts/src/governance/interfaces/IRegistry.sol"; -import {IInbox} from "@aztec/l1-contracts/src/core/interfaces/messagebridge/IInbox.sol"; -import {IOutbox} from "@aztec/l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol"; -import {IRollup} from "@aztec/l1-contracts/src/core/interfaces/IRollup.sol"; -import {DataStructures} from "@aztec/l1-contracts/src/core/libraries/DataStructures.sol"; -import {Hash} from "@aztec/l1-contracts/src/core/libraries/crypto/Hash.sol"; -import {Epoch} from "@aztec/l1-contracts/src/core/libraries/TimeLib.sol"; - -#include_code portal_setup /docs/examples/solidity/aave_bridge/AavePortal.sol raw -} -``` - -:::warning Assembling the Contract -Like the L2 contract, the code above shows the contract opening — imports, state variables, and `initialize()`. The subsequent function snippets go **inside** this contract body, before the closing `}`. -::: - -The portal has three key functions. First, `depositToAave` consumes an L2→L1 message (proving the user burned tokens on L2) and deposits the underlying tokens into Aave: - -#include_code portal_deposit_to_aave /docs/examples/solidity/aave_bridge/AavePortal.sol solidity - -Then, `claimFromAavePublic` withdraws from Aave (including any yield earned) and sends an L1→L2 message so the user can mint tokens on L2: - -#include_code portal_claim_public /docs/examples/solidity/aave_bridge/AavePortal.sol solidity - -There's also a private variant that lets the user claim without revealing their L2 address: - -#include_code portal_claim_private /docs/examples/solidity/aave_bridge/AavePortal.sol solidity - -### Compile - -```bash -npx hardhat compile -``` - -:::note Solidity Artifact Paths -Hardhat compiles Solidity contracts to `artifacts/contracts/` by default. The integration script imports ABIs from this location (e.g., `../artifacts/contracts/AavePortal.sol/AavePortal.json`). -::: - -## Part 3: Deploying and Testing - -Create `scripts/index.ts` to run the full flow. This script deploys all contracts, initializes them, deposits tokens into Aave from L2, and claims them back with yield. - -### Setup - -```typescript -import { getInitialTestAccountsData } from "@aztec/accounts/testing"; -import { AztecAddress, EthAddress } from "@aztec/aztec.js/addresses"; -import { SetPublicAuthwitContractInteraction } from "@aztec/aztec.js/authorization"; -import { Fr } from "@aztec/aztec.js/fields"; -import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node"; -import { createExtendedL1Client } from "@aztec/ethereum/client"; -import { deployL1Contract } from "@aztec/ethereum/deploy-l1-contract"; -import { sha256ToField } from "@aztec/foundation/crypto/sha256"; -import { - computeL2ToL1MessageHash, - computeSecretHash, -} from "@aztec/stdlib/hash"; -import { computeL2ToL1MembershipWitness } from "@aztec/stdlib/messaging"; -import { EmbeddedWallet } from "@aztec/wallets/embedded"; -import { decodeEventLog, pad, toFunctionSelector } from "@aztec/viem"; -import { foundry } from "@aztec/viem/chains"; -import AavePortal from "../artifacts/contracts/AavePortal.sol/AavePortal.json" with { type: "json" }; -import MockERC20 from "../artifacts/contracts/MockERC20.sol/MockERC20.json" with { type: "json" }; -import MockAToken from "../artifacts/contracts/MockAToken.sol/MockAToken.json" with { type: "json" }; -import MockAavePool from "../artifacts/contracts/MockAavePool.sol/MockAavePool.json" with { type: "json" }; -import { TokenContract } from "@aztec/noir-contracts.js/Token"; -import { AaveBridgeContract } from "../contracts/aztec/artifacts/AaveBridge.js"; - -#include_code setup /docs/examples/ts/aave_bridge/index.ts raw -``` - -:::note About EmbeddedWallet -`EmbeddedWallet` is a simplified wallet for local development. It handles key management, transaction signing, and proof generation in-process. Code written against `EmbeddedWallet` works with any `Wallet` implementation, so your application logic transfers directly to production. -::: - -### Deploy L1 Contracts - -#include_code deploy_l1 /docs/examples/ts/aave_bridge/index.ts typescript - -### Deploy L2 Contracts - -#include_code deploy_l2 /docs/examples/ts/aave_bridge/index.ts typescript - -### Initialize - -#include_code initialize /docs/examples/ts/aave_bridge/index.ts typescript - -### Fund the User - -For this tutorial, you need tokens in two places: - -- **L2 tokens for the user** — The user needs tokens on L2 to burn and bridge to L1. In production, these would come from a prior bridge operation. -- **L1 underlying tokens at the portal** — When the portal calls `depositToAave`, it transfers underlying tokens to Aave. The portal must already hold these tokens. In production, the tokens would arrive via a separate bridging mechanism. - -For simplicity, mint directly to both: - -#include_code fund_user /docs/examples/ts/aave_bridge/index.ts typescript - -### Deposit to Aave (L2 → L1) - -Now for the main flow. Burn tokens on L2 and send a message to L1. - -:::info Why is the portal the recipient? -The `recipient` in `exit_to_l1_public` is the L1 address that receives the withdrawal message. Since the AavePortal contract needs to deposit the tokens into Aave, the portal itself is the recipient. Setting `caller_on_l1` to `EthAddress.ZERO` means anyone can relay the message on L1 — there's no access restriction on who calls `depositToAave`. -::: - -#include_code deposit_to_aave /docs/examples/ts/aave_bridge/index.ts typescript - -Compute the membership witness to prove the message on L1: - -#include_code get_deposit_witness /docs/examples/ts/aave_bridge/index.ts typescript - -Execute the deposit on L1: - -#include_code execute_deposit_l1 /docs/examples/ts/aave_bridge/index.ts typescript - -### Claim from Aave with Yield (L1 → L2) - -Before withdrawing from Aave, generate a random secret and compute its hash. The secret hash is included in the L1-to-L2 message — only someone who knows the pre-image (the secret) can consume the message on L2. This prevents front-running: without the secret, no one else can claim your tokens. - -Withdraw from Aave on L1 and send the message to L2. The mock pool returns 10% yield: - -#include_code claim_from_aave_l1 /docs/examples/ts/aave_bridge/index.ts typescript - -Extract the message leaf index: - -#include_code get_claim_leaf_index /docs/examples/ts/aave_bridge/index.ts typescript - -On the local network, L2 blocks are only produced when transactions are submitted. L1-to-L2 messages require 2 L2 blocks before they can be consumed on L2. This utility deploys two dummy contracts (with random salts for unique addresses) to force block production. On devnet or testnet, blocks are produced continuously and this step is unnecessary: - -#include_code mine_blocks /docs/examples/ts/aave_bridge/index.ts typescript - -Claim the tokens (with yield) on L2: - -#include_code claim_on_l2 /docs/examples/ts/aave_bridge/index.ts typescript - -### Verify - -#include_code verify /docs/examples/ts/aave_bridge/index.ts typescript - -Run the full flow: - -```bash -npx hardhat run scripts/index.ts --network localhost -``` - -You should see the user start with 1000 tokens, deposit 500 to Aave, and end up with 1050 tokens (500 remaining + 550 from Aave with 10% yield). - -## What You Built - -A complete cross-chain DeFi integration with: - -1. **L2 Bridge** (Noir) — Burns/mints tokens and handles cross-chain messages. Supports both public and private operations. -2. **L1 Portal** (Solidity) — Deposits into Aave and withdraws with yield. Handles message consumption and creation. -3. **Mock Aave** (Solidity) — Simulates yield generation for local testing. -4. **Full Flow** — Deposit tokens from L2 into Aave, earn yield, and claim back on L2. - -:::warning Production Considerations - -This tutorial uses mock contracts for simplicity. In production: - -- Replace `MockAavePool` with a real Aave V3 pool address -- Handle Aave's variable interest rates (the withdrawn amount may differ from expectations) -- Add slippage protection and error handling for failed messages -- Consider that funds are "in flight" between chains — implement recovery mechanisms -- Add proper access controls to the portal contract - -::: - -## Troubleshooting - -### Script hangs waiting for block to be published - -The deposit flow waits for the L2 block containing your exit transaction to be included in an epoch that is submitted to L1. On the local network, this typically takes 30–60 seconds. If it takes longer, check that your local network is running and producing blocks. - -### Content hash mismatch — L1 message consumption reverts - -This is the most common cross-chain debugging issue. The content hash computed on L2 (via `get_withdraw_content_hash`) must exactly match what the L1 portal reconstructs via `abi.encodeWithSignature`. Double-check that: -- The function signature string matches on both sides (e.g., `"withdraw(address,uint256,address)"`) -- Parameters are in the same order and encoded as the same types -- The `caller_on_l1` value matches: `EthAddress.ZERO` on L2 corresponds to `address(0)` on L1 - -### "Minter not set" — L2 claim fails - -If `claim_public` reverts, ensure you called `set_minter(l2Bridge.address, true)` on the Token contract **after** deploying the bridge. The bridge must be authorized as a minter before it can mint tokens on claim. - -### L1→L2 message not found — claim reverts after mining blocks - -L1-to-L2 messages need 2 L2 blocks after the L1 transaction before they become consumable. Make sure `mine2Blocks` runs before the claim. If the issue persists, verify the `messageLeafIndex` extracted from the `MessageSent` event is correct. - -## Next Steps - -- **Test with a mainnet fork**: Use `aztec-anvil --fork-url` (or your own `anvil` install) to test against real Aave -- **Add private deposits**: Use the `claim_private` and `exit_to_l1_private` functions for privacy-preserving DeFi -- **Build a frontend**: Add a web UI for easy depositing and claiming -- **Compose with other protocols**: The same pattern works for Uniswap, Compound, or any L1 DeFi protocol - -:::tip Learn More - -- [Cross-chain messaging](../../foundational-topics/ethereum-aztec-messaging/index.md) -- [Token Bridge Tutorial](./token_bridge.md) -- [State management](../../foundational-topics/state_management.md) - -::: From 99115f48d986e30e4fee25ec342451de46d73b84 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Thu, 7 May 2026 20:20:31 +0000 Subject: [PATCH 04/30] fix: nargo fmt --- .../aztec/src/test/helpers/txe_oracles.nr | 16 ++++------------ .../test_log_contract/src/test/tx_effects.nr | 9 +-------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr index c35e2a23de45..a888e1e8d87c 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr @@ -7,8 +7,8 @@ use crate::protocol::{ abis::function_selector::FunctionSelector, address::AztecAddress, constants::{ - CONTRACT_INSTANCE_LENGTH, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, - MAX_PRIVATE_LOGS_PER_TX, NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_SIZE_IN_FIELDS, + CONTRACT_INSTANCE_LENGTH, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_LOGS_PER_TX, + NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_SIZE_IN_FIELDS, }, contract_instance::ContractInstance, traits::{Deserialize, ToField}, @@ -109,8 +109,7 @@ pub struct TxEffects { /// Returns the effects of the last transaction included by the TXE. pub unconstrained fn get_last_tx_effects() -> TxEffects { - let (tx_hash, note_hashes, nullifiers, raw_log_storage, log_lengths, log_count) = - get_last_tx_effects_oracle(); + let (tx_hash, note_hashes, nullifiers, raw_log_storage, log_lengths, log_count) = get_last_tx_effects_oracle(); let mut private_logs = BoundedVec::new(); for i in 0..log_count { @@ -121,14 +120,7 @@ pub unconstrained fn get_last_tx_effects() -> TxEffects { } #[oracle(aztec_txe_getLastTxEffects)] -unconstrained fn get_last_tx_effects_oracle() -> ( - Field, - TxNoteHashes, - TxNullifiers, - [[Field; PRIVATE_LOG_SIZE_IN_FIELDS]; MAX_PRIVATE_LOGS_PER_TX], - [u32; MAX_PRIVATE_LOGS_PER_TX], - u32, -) {} +unconstrained fn get_last_tx_effects_oracle() -> (Field, TxNoteHashes, TxNullifiers, [[Field; PRIVATE_LOG_SIZE_IN_FIELDS]; MAX_PRIVATE_LOGS_PER_TX], [u32; MAX_PRIVATE_LOGS_PER_TX], u32) {} /// Returns the raw offchain effect payloads emitted by the last top-level call into TXE. /// Each effect is a variable-length field array (e.g. offchain messages have a different size diff --git a/noir-projects/noir-contracts/contracts/test/test_log_contract/src/test/tx_effects.nr b/noir-projects/noir-contracts/contracts/test/test_log_contract/src/test/tx_effects.nr index 416f0f82de7d..a652f538a64b 100644 --- a/noir-projects/noir-contracts/contracts/test/test_log_contract/src/test/tx_effects.nr +++ b/noir-projects/noir-contracts/contracts/test/test_log_contract/src/test/tx_effects.nr @@ -59,14 +59,7 @@ unconstrained fn multiple_private_logs_with_varying_lengths() { env.call_private( sender, - test_log.emit_three_raw_private_logs_diff_lengths( - tag1, - payload1, - tag2, - payload2, - tag3, - payload3, - ), + test_log.emit_three_raw_private_logs_diff_lengths(tag1, payload1, tag2, payload2, tag3, payload3), ); let private_logs = txe_oracles::get_last_tx_effects().private_logs; From 03f867bb5d700217eb754122831c08f135af0685 Mon Sep 17 00:00:00 2001 From: Martin Verzilli Date: Fri, 8 May 2026 09:25:03 +0200 Subject: [PATCH 05/30] fix: include sqlite binary in its npm package (#23039) We correctly .gitignore prebuilt sqlite artifacts since we fetch and verify them on build, however, this is inconvenient for users of our packages, since it leaves the burden of re-vendoring up to them. This PR introduces an .npmignore file to the sqlite npm package, which by convention overshadows the .gitignore file when npm produces the package tarball. It also includes a verification script to make sure there's no loose ends in the process --- yarn-project/sqlite3mc-wasm/package.json | 3 +- yarn-project/sqlite3mc-wasm/scripts/vendor.sh | 12 +++ .../sqlite3mc-wasm/scripts/verify-pack.sh | 91 +++++++++++++++++++ .../sqlite3mc-wasm/vendor/jswasm/.gitignore | 6 +- .../sqlite3mc-wasm/vendor/jswasm/.npmignore | 18 ++++ 5 files changed, 127 insertions(+), 3 deletions(-) create mode 100755 yarn-project/sqlite3mc-wasm/scripts/verify-pack.sh create mode 100644 yarn-project/sqlite3mc-wasm/vendor/jswasm/.npmignore diff --git a/yarn-project/sqlite3mc-wasm/package.json b/yarn-project/sqlite3mc-wasm/package.json index a7644570650b..5f25ccd6b535 100644 --- a/yarn-project/sqlite3mc-wasm/package.json +++ b/yarn-project/sqlite3mc-wasm/package.json @@ -18,7 +18,8 @@ "build": "yarn clean && ../scripts/tsc.sh", "clean": "rm -rf ./dest .tsbuildinfo", "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}", - "build:dev": "../scripts/tsc.sh --watch" + "build:dev": "../scripts/tsc.sh --watch", + "prepublishOnly": "./scripts/verify-pack.sh" }, "devDependencies": { "@jest/globals": "^30.0.0", diff --git a/yarn-project/sqlite3mc-wasm/scripts/vendor.sh b/yarn-project/sqlite3mc-wasm/scripts/vendor.sh index f8da2b46f383..c4abb0a2ae28 100755 --- a/yarn-project/sqlite3mc-wasm/scripts/vendor.sh +++ b/yarn-project/sqlite3mc-wasm/scripts/vendor.sh @@ -29,6 +29,7 @@ PKG_ROOT=$(cd "$SCRIPT_DIR/.." && pwd) LOCAL_DMTS="$PKG_ROOT/vendor/jswasm/sqlite3-bundler-friendly.d.mts" LOCAL_GITIGNORE="$PKG_ROOT/vendor/jswasm/.gitignore" +LOCAL_NPMIGNORE="$PKG_ROOT/vendor/jswasm/.npmignore" SHA256SUMS="$PKG_ROOT/vendor/jswasm/SHA256SUMS" PIN_FILE="$SCRIPT_DIR/vendor.pin" @@ -100,6 +101,7 @@ fi # Preserve files that aren't part of the upstream release across re-vendoring: # - sqlite3-bundler-friendly.d.mts: locally-authored TypeScript declaration # - .gitignore: allowlist that keeps upstream artifacts untracked +# - .npmignore: shadows .gitignore so npm publish keeps the artifacts DMTS_BACKUP="" if [[ -f "$LOCAL_DMTS" ]]; then DMTS_BACKUP=$(mktemp) @@ -110,6 +112,11 @@ if [[ -f "$LOCAL_GITIGNORE" ]]; then GITIGNORE_BACKUP=$(mktemp) cp "$LOCAL_GITIGNORE" "$GITIGNORE_BACKUP" fi +NPMIGNORE_BACKUP="" +if [[ -f "$LOCAL_NPMIGNORE" ]]; then + NPMIGNORE_BACKUP=$(mktemp) + cp "$LOCAL_NPMIGNORE" "$NPMIGNORE_BACKUP" +fi echo "==> Replacing vendor/jswasm/ with pristine upstream files" rm -rf "$PKG_ROOT/vendor/jswasm" @@ -127,6 +134,11 @@ if [[ -n "$GITIGNORE_BACKUP" ]]; then rm "$GITIGNORE_BACKUP" echo "==> Restored .gitignore" fi +if [[ -n "$NPMIGNORE_BACKUP" ]]; then + cp "$NPMIGNORE_BACKUP" "$LOCAL_NPMIGNORE" + rm "$NPMIGNORE_BACKUP" + echo "==> Restored .npmignore" +fi echo "==> Generating vendor/jswasm/SHA256SUMS" (cd "$PKG_ROOT/vendor/jswasm" && sha256sum -- * 2>/dev/null | sort -k2 > SHA256SUMS) diff --git a/yarn-project/sqlite3mc-wasm/scripts/verify-pack.sh b/yarn-project/sqlite3mc-wasm/scripts/verify-pack.sh new file mode 100755 index 000000000000..692d0b5bc1fd --- /dev/null +++ b/yarn-project/sqlite3mc-wasm/scripts/verify-pack.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# Verify that the npm tarball this package would publish includes every +# vendored sqlite3mc artifact listed in vendor/jswasm/SHA256SUMS. +# +# Background: npm honors any `.gitignore` it finds inside directories listed +# in the `files` allowlist. The `.gitignore` in vendor/jswasm/ excludes +# everything except an allowlist (SHA256SUMS, the locally-authored .d.mts, +# and itself), which inadvertently strips the WASM/MJS artifacts from the +# published tarball even though they're present on disk after vendor.sh ran. +# +# vendor/jswasm/.npmignore shadows that .gitignore for npm pack purposes. +# This script is the guard that catches any future regression. For example: +# someone deletes the .npmignore, or a new vendored file is added but not +# captured by whatever inclusion mechanism is in place. Wired into +# `prepublishOnly` so a broken tarball aborts publish before upload. +# +# Exit codes: 0 = all expected files present, 1 = missing files, 2 = setup +# error (no SHA256SUMS, npm pack failed, etc.). + +set -euo pipefail + +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +PKG_ROOT=$(cd "$SCRIPT_DIR/.." && pwd) +SHA256SUMS="$PKG_ROOT/vendor/jswasm/SHA256SUMS" + +if [[ ! -f "$SHA256SUMS" ]]; then + echo "verify-pack: SHA256SUMS not found at $SHA256SUMS" >&2 + echo " Run scripts/vendor.sh first to populate vendor/jswasm/." >&2 + exit 2 +fi + +# Parse SHA256SUMS for the list of files that MUST appear in the tarball. +# Each line is " ". We want the filename, prefixed with +# the package-relative path that npm uses inside the tarball. +expected=() +while IFS= read -r line; do + fname=$(awk '{print $2}' <<<"$line") + [[ -n "$fname" ]] || continue + expected+=("vendor/jswasm/$fname") +done < "$SHA256SUMS" + +if [[ ${#expected[@]} -eq 0 ]]; then + echo "verify-pack: SHA256SUMS contained no entries, nothing to verify" >&2 + exit 2 +fi + +WORK_DIR=$(mktemp -d) +trap 'rm -rf "$WORK_DIR"' EXIT + +# Build the same tarball `npm publish` would upload, then list its contents. +# `--dry-run --json` output format varies across npm versions; running real +# `npm pack` and untarring is stable across npm 7+. +echo "==> Running npm pack to build a candidate tarball" +(cd "$PKG_ROOT" && npm pack --pack-destination "$WORK_DIR" >/dev/null) +TARBALL=$(find "$WORK_DIR" -maxdepth 1 -name '*.tgz' | head -n 1) +if [[ -z "$TARBALL" ]]; then + echo "verify-pack: npm pack produced no tarball in $WORK_DIR" >&2 + exit 2 +fi + +# Tarball entries are prefixed with "package/" — strip for comparison. +tar tzf "$TARBALL" | sed 's|^package/||' > "$WORK_DIR/listing" + +missing=0 +for f in "${expected[@]}"; do + if ! grep -Fxq "$f" "$WORK_DIR/listing"; then + echo "verify-pack: missing from tarball: $f" >&2 + missing=1 + fi +done + +if [[ "$missing" -eq 1 ]]; then + cat >&2 <&1 | grep vendor/jswasm + + Tarball file listing (for reference): $WORK_DIR/listing +EOF + # Don't auto-clean WORK_DIR on failure so the operator can inspect. + trap - EXIT + echo "verify-pack: leaving $WORK_DIR for inspection" >&2 + exit 1 +fi + +echo "verify-pack: all ${#expected[@]} vendored files present in tarball" diff --git a/yarn-project/sqlite3mc-wasm/vendor/jswasm/.gitignore b/yarn-project/sqlite3mc-wasm/vendor/jswasm/.gitignore index 915a8050440b..732bd806851d 100644 --- a/yarn-project/sqlite3mc-wasm/vendor/jswasm/.gitignore +++ b/yarn-project/sqlite3mc-wasm/vendor/jswasm/.gitignore @@ -1,9 +1,11 @@ # Upstream sqlite3mc-wasm release artifacts are fetched at build time by # scripts/vendor.sh (driven by scripts/vendor.pin). Don't commit them. # -# Allowlist: keep this .gitignore, the integrity manifest, and our -# locally-authored TypeScript declaration tracked in git. +# Allowlist: keep this .gitignore, the .npmignore that shadows it for npm +# pack, the integrity manifest, and our locally-authored TypeScript +# declaration tracked in git. * !.gitignore +!.npmignore !SHA256SUMS !sqlite3-bundler-friendly.d.mts diff --git a/yarn-project/sqlite3mc-wasm/vendor/jswasm/.npmignore b/yarn-project/sqlite3mc-wasm/vendor/jswasm/.npmignore new file mode 100644 index 000000000000..bd143d02c3f3 --- /dev/null +++ b/yarn-project/sqlite3mc-wasm/vendor/jswasm/.npmignore @@ -0,0 +1,18 @@ +# Empty allowlist override for `npm publish`. +# +# The sibling .gitignore is structured to keep upstream-fetched binary +# artifacts (sqlite3mc WASM/MJS files) out of git: they're regenerated by +# scripts/vendor.sh on every checkout/build. +# +# But: when `files` in package.json lists `vendor/`, npm's tarball builder +# also honors any nested .gitignore, and would strip those same artifacts +# from the published tarball, leaving downstream consumers with an +# unbuildable package (`dest/index.js` re-exports from +# `../vendor/jswasm/sqlite3-bundler-friendly.mjs`). +# +# An .npmignore in a directory shadows the sibling .gitignore for npm pack. +# Empty contents = "include everything in this directory." +# +# Guard: scripts/verify-pack.sh runs at prepublishOnly and asserts every +# file in SHA256SUMS appears in the produced tarball. If this file gets +# deleted by accident, that check fires before the broken tarball ships. From dccbead5647555ad6ed6e1a0621e9dc8dde066b0 Mon Sep 17 00:00:00 2001 From: mverzilli Date: Thu, 7 May 2026 14:11:36 +0000 Subject: [PATCH 06/30] add sendMessagesAs to wallet api schemas --- .../aztec.js/src/wallet/wallet.test.ts | 24 +++++++++++++++++-- yarn-project/aztec.js/src/wallet/wallet.ts | 2 ++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/yarn-project/aztec.js/src/wallet/wallet.test.ts b/yarn-project/aztec.js/src/wallet/wallet.test.ts index f5aa0164bc2b..04edfb332e12 100644 --- a/yarn-project/aztec.js/src/wallet/wallet.test.ts +++ b/yarn-project/aztec.js/src/wallet/wallet.test.ts @@ -165,11 +165,15 @@ describe('WalletSchema', () => { extraHashedArgs: [], feePayer: undefined, }; + const sendMessagesAs = await AztecAddress.random(); const opts: SimulateOptions = { from: await AztecAddress.random(), + sendMessagesAs, }; const result = await context.client.simulateTx(exec, opts); expect(result).toBeInstanceOf(TxSimulationResultWithAppOffset); + expect(handler.lastSimulateOpts?.sendMessagesAs).toBeInstanceOf(AztecAddress); + expect(handler.lastSimulateOpts?.sendMessagesAs?.equals(sendMessagesAs)).toBe(true); }); it('executeUtility', async () => { @@ -198,12 +202,16 @@ describe('WalletSchema', () => { extraHashedArgs: [], feePayer: undefined, }; + const sendMessagesAs = await AztecAddress.random(); const opts: ProfileOptions = { from: await AztecAddress.random(), profileMode: 'gates', + sendMessagesAs, }; const result = await context.client.profileTx(exec, opts); expect(result).toBeInstanceOf(TxProfileResult); + expect(handler.lastProfileOpts?.sendMessagesAs).toBeInstanceOf(AztecAddress); + expect(handler.lastProfileOpts?.sendMessagesAs?.equals(sendMessagesAs)).toBe(true); }); it('sendTx', async () => { @@ -215,11 +223,16 @@ describe('WalletSchema', () => { feePayer: undefined, }; + const sendMessagesAs = await AztecAddress.random(); const resultWithWait = await context.client.sendTx(exec, { from: await AztecAddress.random(), + sendMessagesAs, }); expect(resultWithWait.receipt).toBeInstanceOf(TxReceipt); expect(resultWithWait.offchainEffects).toEqual([]); + expect(handler.lastSendOpts?.sendMessagesAs).toBeInstanceOf(AztecAddress); + expect(handler.lastSendOpts?.sendMessagesAs?.equals(sendMessagesAs)).toBe(true); + const resultWithoutWait = await context.client.sendTx(exec, { from: await AztecAddress.random(), wait: NO_WAIT, @@ -384,6 +397,10 @@ describe('WalletSchema', () => { }); class MockWallet implements Wallet { + lastSimulateOpts?: SimulateOptions; + lastProfileOpts?: ProfileOptions; + lastSendOpts?: SendOptions; + getChainInfo(): Promise { return Promise.resolve({ chainId: Fr.random(), @@ -451,7 +468,8 @@ class MockWallet implements Wallet { }; } - async simulateTx(_exec: ExecutionPayload, _opts: SimulateOptions): Promise { + async simulateTx(_exec: ExecutionPayload, opts: SimulateOptions): Promise { + this.lastSimulateOpts = opts; return TxSimulationResultWithAppOffset.fromResultAndOffset(await TxSimulationResult.random(), 0); } @@ -462,7 +480,8 @@ class MockWallet implements Wallet { return Promise.resolve(UtilityExecutionResult.random()); } - profileTx(_exec: ExecutionPayload, _opts: ProfileOptions): Promise { + profileTx(_exec: ExecutionPayload, opts: ProfileOptions): Promise { + this.lastProfileOpts = opts; return Promise.resolve(TxProfileResult.random()); } @@ -470,6 +489,7 @@ class MockWallet implements Wallet { _exec: ExecutionPayload, opts: SendOptions, ): Promise> { + this.lastSendOpts = opts as SendOptions; if (opts.wait === NO_WAIT) { return Promise.resolve({ txHash: TxHash.random(), diff --git a/yarn-project/aztec.js/src/wallet/wallet.ts b/yarn-project/aztec.js/src/wallet/wallet.ts index fa2c7bd297a2..9360a8863f0d 100644 --- a/yarn-project/aztec.js/src/wallet/wallet.ts +++ b/yarn-project/aztec.js/src/wallet/wallet.ts @@ -323,6 +323,7 @@ export const SendOptionsSchema = z.object({ fee: optional(GasSettingsOptionSchema), wait: optional(z.union([z.literal(NO_WAIT), WaitOptsSchema])), additionalScopes: optional(z.array(schemas.AztecAddress)), + sendMessagesAs: optional(schemas.AztecAddress), }); export const SimulateOptionsSchema = z.object({ @@ -334,6 +335,7 @@ export const SimulateOptionsSchema = z.object({ skipFeeEnforcement: optional(z.boolean()), includeMetadata: optional(z.boolean()), additionalScopes: optional(z.array(schemas.AztecAddress)), + sendMessagesAs: optional(schemas.AztecAddress), }); export const ProfileOptionsSchema = SimulateOptionsSchema.extend({ From ec544e9fef6f05ee53ae104be598f3bf2d224673 Mon Sep 17 00:00:00 2001 From: Gregorio Juliana Date: Thu, 7 May 2026 11:47:17 +0200 Subject: [PATCH 07/30] chore: cherry-pick #22985 (better DeployMethod) with conflicts Records the raw cherry-pick state (including conflict markers) so reviewers can see exactly what conflicted before resolution. Original PR: https://github.com/AztecProtocol/aztec-packages/pull/22985 --- boxes/boxes/react/src/hooks/useContract.tsx | 2 - boxes/boxes/vanilla/scripts/deploy.ts | 8 +- boxes/boxes/vite/src/hooks/useContract.tsx | 2 - .../docs/resources/migration_notes.md | 250 ++++++++ docs/examples/ts/aave_bridge/index.ts | 419 ++++++++++++ docs/examples/ts/aztecjs_advanced/index.ts | 90 ++- docs/examples/ts/example_swap/index.ts | 594 ++++++++++++++++++ docs/examples/ts/token_bridge/index.ts | 21 +- .../aztec/src/test/helpers/txe_oracles.nr | 4 + .../crates/types/src/constants.nr | 7 + .../crates/types/src/constants_tests.nr | 20 + .../components/CreateContractDialog.tsx | 14 +- yarn-project/aztec.js/src/api/contract.ts | 4 + .../aztec.js/src/contract/contract.test.ts | 24 +- .../aztec.js/src/contract/contract.ts | 26 +- .../src/contract/deploy_method.test.ts | 155 ++++- .../aztec.js/src/contract/deploy_method.ts | 262 ++++++-- .../src/deployment/contract_deployer.ts | 26 +- yarn-project/aztec.js/src/test/fixtures.ts | 131 ++++ .../src/wallet/deploy_account_method.ts | 73 +-- .../aztec/src/local-network/banana_fpc.ts | 11 +- yarn-project/bot/src/factory.ts | 106 +++- .../src/contract-interface-gen/typescript.ts | 26 +- yarn-project/cli-wallet/src/cmds/deploy.ts | 32 +- .../src/composed/ha/e2e_ha_full.test.ts | 92 ++- ...e2e_multi_validator_node_key_store.test.ts | 5 +- .../end-to-end/src/e2e_block_building.test.ts | 18 +- .../src/e2e_contract_updates.test.ts | 5 + .../src/e2e_crowdfunding_and_claim.test.ts | 8 +- .../e2e_deploy_contract/deploy_method.test.ts | 78 +-- .../src/e2e_deploy_contract/legacy.test.ts | 34 +- .../e2e_epochs/epochs_mbps.parallel.test.ts | 2 +- .../src/e2e_escrow_contract.test.ts | 2 +- .../src/e2e_fees/account_init.test.ts | 8 +- .../end-to-end/src/e2e_multi_eoa.test.ts | 8 +- .../e2e_multi_validator_node.test.ts | 12 + .../end-to-end/src/e2e_phase_check.test.ts | 7 +- .../e2e_public_testnet_transfer.test.ts | 11 +- .../src/e2e_sequencer/reload_keystore.test.ts | 16 +- .../end-to-end/src/e2e_simple.test.ts | 6 + yarn-project/end-to-end/src/fixtures/setup.ts | 9 + .../end-to-end/src/test-wallet/utils.ts | 7 +- 42 files changed, 2255 insertions(+), 380 deletions(-) create mode 100644 docs/examples/ts/aave_bridge/index.ts create mode 100644 docs/examples/ts/example_swap/index.ts create mode 100644 yarn-project/aztec.js/src/test/fixtures.ts diff --git a/boxes/boxes/react/src/hooks/useContract.tsx b/boxes/boxes/react/src/hooks/useContract.tsx index ff180dfa5b59..d74eb9ed9458 100644 --- a/boxes/boxes/react/src/hooks/useContract.tsx +++ b/boxes/boxes/react/src/hooks/useContract.tsx @@ -15,13 +15,11 @@ export function useContract() { setWait(true); const wallet = await deployerEnv.getWallet(); const defaultAccountAddress = deployerEnv.getDefaultAccountAddress(); - const salt = Fr.random(); const { BoxReactContract } = await import('../../artifacts/BoxReact'); const deploymentPromise = BoxReactContract.deploy(wallet, Fr.random(), defaultAccountAddress).send({ from: defaultAccountAddress, - contractAddressSalt: salt, }); const { contract } = await toast.promise(deploymentPromise, { diff --git a/boxes/boxes/vanilla/scripts/deploy.ts b/boxes/boxes/vanilla/scripts/deploy.ts index 83a24cc3f913..9699dd35bebf 100644 --- a/boxes/boxes/vanilla/scripts/deploy.ts +++ b/boxes/boxes/vanilla/scripts/deploy.ts @@ -72,12 +72,10 @@ async function deployContract(wallet: Wallet, deployer: AztecAddress) { const sponsoredPFCContract = await getSponsoredPFCContract(); - const { contract } = await PrivateVotingContract.deploy( - wallet, - deployer - ).send({ + const { contract } = await PrivateVotingContract.deploy(wallet, deployer, { + salt, + }).send({ from: deployer, - contractAddressSalt: salt, fee: { paymentMethod: new SponsoredFeePaymentMethod( sponsoredPFCContract.address diff --git a/boxes/boxes/vite/src/hooks/useContract.tsx b/boxes/boxes/vite/src/hooks/useContract.tsx index ff180dfa5b59..d74eb9ed9458 100644 --- a/boxes/boxes/vite/src/hooks/useContract.tsx +++ b/boxes/boxes/vite/src/hooks/useContract.tsx @@ -15,13 +15,11 @@ export function useContract() { setWait(true); const wallet = await deployerEnv.getWallet(); const defaultAccountAddress = deployerEnv.getDefaultAccountAddress(); - const salt = Fr.random(); const { BoxReactContract } = await import('../../artifacts/BoxReact'); const deploymentPromise = BoxReactContract.deploy(wallet, Fr.random(), defaultAccountAddress).send({ from: defaultAccountAddress, - contractAddressSalt: salt, }); const { contract } = await toast.promise(deploymentPromise, { diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 3d211bd10911..2cf7da2d33e7 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -9,7 +9,102 @@ Aztec is in active development. Each version may introduce breaking changes that ## TBD +<<<<<<< HEAD ### [Aztec.nr] TXE `call_public_incognito` no longer takes a `from` parameter +======= +### [Aztec.js] `DeployMethod` address-affecting parameters move to construction time + +Salt, deployer, and public keys are now passed when the `DeployMethod` is constructed, not on every call to `send` / `simulate` / `request` / `getInstance`. This locks the contract address once it is determined and prevents the silent salt-cache poisoning bug where the address could change between calls. + +`contractAddressSalt`, `deployer`, and `universalDeploy` have been removed from `DeployOptions`, `RequestDeployOptions`, and `SimulateDeployOptions`. They now live on a new `DeployInstantiationOptions` argument passed at construction. `deployer` and `universalDeploy` are mutually exclusive; passing both throws. `Contract.deployWithPublicKeys` and the generated `MyContract.deployWithPublicKeys(...)` factories have been removed; pass `publicKeys` via the `instantiation` argument of `deploy(...)` instead. The buggy synchronous `address` and `partialAddress` getters have been removed and replaced with `getAddress()` and `getPartialAddress()` (both `async`). + +The compact form keeps working: `MyContract.deploy(wallet, ...args).send({ from: alice })` deploys with `deployer = alice` and `salt = random()`, exactly as before. The deployer is locked the first time `send` / `simulate` / `profile` is called (from `options.from`, with `NO_FROM` or undefined → universal) and cannot change after that: + +- Subsequent `send` / `simulate` / `profile` calls with a `from` that would imply a different deployer throw, instead of silently producing a different address. +- A lock to universal (`AztecAddress.ZERO`) is the only one compatible with any sender, since the universal address does not depend on `from`. +- A lock to a concrete address only accepts that exact `from` on subsequent calls. + +**Migration:** + +Universal deployment with a fixed salt: + +```diff +- const deploy = MyContract.deploy(wallet, ...args); +- await deploy.send({ +- from: alice, +- contractAddressSalt: salt, +- universalDeploy: true, +- }); ++ const deploy = MyContract.deploy(wallet, ...args, { salt, universalDeploy: true }); ++ await deploy.send({ from: alice }); +``` + +Non-universal deploy where `from` doubles as the deployer: + +```diff +- const deploy = MyContract.deploy(wallet, ...args); +- await deploy.send({ from: alice, contractAddressSalt: salt }); ++ const deploy = MyContract.deploy(wallet, ...args, { salt }); ++ await deploy.send({ from: alice }); +``` + +If you need to read the address before sending, lock the deployer at construction: + +```typescript +const deploy = MyContract.deploy(wallet, ...args, { salt, deployer: alice }); +const address = await deploy.getAddress(); // resolves; deployer was locked at construction +await deploy.send({ from: alice }); // deploys at the address `getAddress` returned +``` + +Universal deploys can be sent by any account, since the universal address does not depend on `from`: + +```typescript +const deploy = MyContract.deploy(wallet, ...args, { universalDeploy: true }); +await deploy.send({ from: bob }); // OK, universal accepts any sender +``` + +A lock to a concrete deployer rejects sending from a different account, instead of silently deploying at a different address: + +```typescript +const deploy = MyContract.deploy(wallet, ...args, { deployer: alice }); +await deploy.send({ from: bob }); // throws: deployer is locked to alice +``` + +`deployWithPublicKeys` is gone; pass `publicKeys` in the instantiation options instead: + +```diff +- const deploy = MyContract.deployWithPublicKeys(publicKeys, wallet, ...args); ++ const deploy = MyContract.deploy(wallet, ...args, { publicKeys }); +``` + +`ContractDeployer.deploy(...)` now takes the instantiation argument as its first parameter (pass `{}` to use defaults and rely on lazy locking from `from`): + +```diff +- const cd = new ContractDeployer(artifact, wallet); +- await cd.deploy(...ctorArgs).send({ from: alice, contractAddressSalt: salt }); ++ const cd = new ContractDeployer(artifact, wallet); ++ await cd.deploy(ctorArgs, { salt }).send({ from: alice }); +``` + +The synchronous `address` / `partialAddress` getters are gone: + +```diff +- const address = deploy.address; // sync, possibly undefined +- const partial = await deploy.partialAddress; // sync getter wrapping async value ++ const address = await deploy.getAddress(); // requires the deployer to be locked ++ const partial = await deploy.getPartialAddress(); // requires the deployer to be locked +``` + +`getInstance()` no longer takes options; use the construction-time instantiation instead: + +```diff +- const instance = await deploy.getInstance({ contractAddressSalt: salt }); ++ const deploy = MyContract.deploy(wallet, ...args, { salt, deployer: alice }); ++ const instance = await deploy.getInstance(); +``` + +### [aztec-up] Bundled binaries are no longer exposed under bare names on `PATH` +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) `TestEnvironment::call_public_incognito` previously accepted a `from` address that was silently ignored (the function always uses a null `msg_sender`). The `from` parameter has been removed. @@ -18,7 +113,24 @@ Aztec is in active development. Each version may introduce breaking changes that + env.call_public_incognito(SampleContract::at(addr).some_function()); ``` +<<<<<<< HEAD If you need to call a public function *with* a sender, use `call_public` instead. +======= +| Was on `PATH` | Now | +| ------------------ | ------------------------ | +| `forge` | `aztec-forge` | +| `cast` | `aztec-cast` | +| `anvil` | `aztec-anvil` | +| `chisel` | `aztec-chisel` | +| `nargo` | `aztec-nargo` | +| `noir-profiler` | `aztec-noir-profiler` | +| `bb` | `aztec-bb` | +| `bb-cli` | `aztec-bb-cli` | +| `pxe` | `aztec-pxe` | +| `txe` | `aztec-txe` | +| `validator-client` | `aztec-validator-client` | +| `blob-client` | `aztec-blob-client` | +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) ### [Aztec.nr] TXE `view_public_incognito` is deprecated @@ -56,6 +168,61 @@ The wallet SDK now supplies the default sender-for-tags from the transaction's ` The save/restore idiom previously used in account-contract constructors (`get` → `set(self.address)` → work → `set(prev)`) is also no longer needed and has been removed: the override never leaks out of the constructor, so there is nothing to restore. +<<<<<<< HEAD +======= +### [Aztec Node] Unified `getBlock` / `getCheckpoint` RPC API + +The Aztec Node JSON-RPC surface for fetching blocks and checkpoints has been consolidated. The unified `getBlock` and `getCheckpoint` methods return uniform `BlockResponse` / `CheckpointResponse` shapes. The extra fields a caller cares about (tx bodies, L1 publish info, committee attestations, nested blocks) are now controlled by an `options` argument rather than by picking the right method. `getBlocks` and `getCheckpoints` retain their names but now return the new response shapes. + +**Removed methods:** + +| Removed | Replacement | +| ---------------------------------- | -------------------------------------------- | +| `getBlockByHash(hash)` | `getBlock(hash)` or `getBlock({ hash })` | +| `getBlockByArchive(archive)` | `getBlock({ archive })` | +| `getBlockHeaderByArchive(archive)` | `getBlock({ archive }).then(r => r?.header)` | +| `getProvenBlockNumber()` | `getBlockNumber('proven')` | +| `getCheckpointedBlockNumber()` | `getBlockNumber('checkpointed')` | + +**Deprecated but still present** (scheduled for removal once internal consumers of the archiver shape are rewired): `getL2Tips` (use `getChainTips`), `getBlockHeader` (use `getBlock(param).then(r => r?.header)`), `getCheckpointedBlocks` (use `getBlocks(from, limit, { includeL1PublishInfo: true, includeAttestations: true })`), `getCheckpointsDataForEpoch` (use `getCheckpoints(from, limit)` over the epoch's checkpoint range). Do not adopt these in new code. + +**New response shapes:** `BlockResponse` always carries `header`, `archive`, `hash`, `number`, `checkpointNumber`, and `indexWithinCheckpoint`. `body`, `l1` (an `L1PublishInfo` discriminated union), and `attestations` are present only when the matching include option is set. `CheckpointResponse` mirrors this for checkpoints, with `blocks` gated on `includeBlocks`, and always carries `feeAssetPriceModifier` as a base field. The response types are generic over the options object, so passing a literal `{ includeTransactions: true }` narrows the return type and `response.body` becomes non-optional. + +**Nested blocks on `getCheckpoint`:** only `includeTransactions` is forwarded to the blocks embedded by `includeBlocks: true`. `includeL1PublishInfo` and `includeAttestations` on a checkpoint request attach L1 / attestation data to the checkpoint itself, not to its nested blocks. + +**Return type changes for `getBlocks` / `getCheckpoints`:** the return type is now `BlockResponse[]` / `CheckpointResponse[]` instead of `L2Block[]` / `PublishedCheckpoint[]`. Callers that previously consumed fields of `L2Block` (e.g. `.body`) must now opt in via `{ includeTransactions: true }`; callers that consumed `PublishedCheckpoint.checkpoint.blocks` must opt in via `{ includeBlocks: true }`. + +**Migration for wallet/SDK consumers (`@aztec/aztec.js`, `@aztec/wallet-sdk`):** + +```diff +- const block = await node.getBlockByHash(hash); ++ const block = await node.getBlock(hash, { includeTransactions: true }); + +- const archiveBlock = await node.getBlockByArchive(archive); ++ const archiveBlock = await node.getBlock({ archive }, { includeTransactions: true }); + +- const provenNumber = await node.getProvenBlockNumber(); ++ const provenNumber = await node.getBlockNumber('proven'); + +- const checkpointedNumber = await node.getCheckpointedBlockNumber(); ++ const checkpointedNumber = await node.getBlockNumber('checkpointed'); + +- const tips = await node.getL2Tips(); ++ const tips = await node.getChainTips(); +``` + +`getBlockHeader`, `getCheckpointedBlocks`, `getCheckpointsDataForEpoch`, and `getL2Tips` continue to work in this release but are deprecated; migrate to the replacements above. + +**Chain-tip selectors:** `getBlockNumber` and `getCheckpointNumber` now accept an optional `ChainTip` argument (`'proposed' | 'checkpointed' | 'proven' | 'finalized'`). Note the semantic difference: on the block side `'proposed'` means the latest proposed block (chain head), whereas on the checkpoint side `'proposed'` resolves to the latest L1-confirmed checkpoint. Pre-L1-confirmation checkpoints are not exposed over RPC. + +**Block parameter variants:** `BlockParameter` now also accepts a block hash, an archive root, and chain-tip names. The existing `number | 'latest'` forms continue to work — `'latest'` is an alias for `'proposed'`. + +**Impact**: Source changes are required anywhere the removed methods are called. Type changes are required anywhere `L2Block` / `BlockHeader` / `CheckpointedL2Block` were consumed from the RPC — those call sites now receive `BlockResponse` / `CheckpointResponse` and must request the fields they need via `options`. Production nodes will reject JSON-RPC calls to the removed method names. + +### [Aztec Node] `feeAssetPriceModifier` now correctly populated on confirmed checkpoints + +Confirmed checkpoints previously reported `feeAssetPriceModifier = 0n` regardless of the value observed on L1, because the archiver dropped the field on checkpoint confirmation. The field is now persisted and returned correctly on `CheckpointResponse`. Any wallet or indexer logic that special-cased `0n` as a sentinel for "no modifier" will need to be updated; it is now a valid value in its own right. +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) ### [CLI] `aztec-up` no longer exposes transitive npm bins on PATH @@ -75,6 +242,47 @@ echo $PATH `$HOME/.aztec/current/node_modules/.bin` should no longer appear in the output. You'll also see your own `jest`, `tsc`, etc. again instead of the ones bundled with the Aztec toolchain. +<<<<<<< HEAD +======= +### [Protocol] Domain separators introduced for merkle-node, block-headers, and blob hashes + +Several protocol hashes that previously used bare `poseidon2_hash` are now domain-separated via `poseidon2_hash_with_separator`. This is a security hardening change — it prevents a value produced by one hash context from being reinterpreted in another (e.g. a sibling path from one tree being transported to another). + +**New domain separators:** + +- `DOM_SEP__MERKLE_HASH` — sibling-pair hash for append-only trees (note-hash, L1→L2, archive, VK tree, and the balanced/unbalanced tree hash helpers in `@aztec/foundation/trees`). +- `DOM_SEP__NULLIFIER_MERKLE`, `DOM_SEP__PUBLIC_DATA_MERKLE`, `DOM_SEP__WRITTEN_SLOTS_MERKLE`, `DOM_SEP__RETRIEVED_BYTECODES_MERKLE` — per-tree sibling-pair hash for each indexed tree. Each tree uses its own separator so sibling paths are non-transportable across trees. +- `DOM_SEP__BLOCK_HEADERS_HASH` — used when accumulating block headers into `blockHeadersHash`. +- `DOM_SEP__BLOB_HASHED_Y_LIMBS`, `DOM_SEP__BLOB_CHALLENGE_Z`, `DOM_SEP__BLOB_Z_ACC`, `DOM_SEP__BLOB_GAMMA_ACC`, `DOM_SEP__BLOB_GAMMA_FINAL` — blob accumulator and challenge derivations. + +**:warning: Hard-coded test constants will no longer match.** Every value derived from any of the hashes above is new in this release. This includes (non-exhaustively): + +- **All merkle tree roots** — note-hash, nullifier, public-data, L1→L2 message, archive, VK, and the AVM-internal written-slots and retrieved-bytecodes (class-ids) trees. +- **Genesis constants** — `GENESIS_BLOCK_HEADER_HASH`, `GENESIS_ARCHIVE_ROOT`, `AVM_WRITTEN_PUBLIC_DATA_SLOTS_TREE_INITIAL_ROOT`, `AVM_RETRIEVED_BYTECODES_TREE_INITIAL_ROOT`. +- **Every block hash and archive root** — they commit to tree roots and the new block-headers-hash. +- **Protocol contract addresses** — their derivation depends on the private-function tree root. +- **Blob commitments / challenges** — any test that pins `z`, `gamma`, or the accumulator outputs. + +Regenerate these values from a fresh build of this release — do not copy them from previous release fixtures. + +**If you re-implement any of these hashes off-circuit** (e.g. a wallet that computes nullifier low-leaf membership, or an indexer that derives block hashes / tree roots), update the call sites: + +```diff + // Merkle sibling-pair hash (append-only trees) +- poseidon2Hash([left, right]) ++ poseidon2HashWithSeparator([left, right], DomainSeparator.MERKLE_HASH) + + // Indexed-tree sibling-pair hash — pick the matching tree separator +- poseidon2Hash([left, right]) ++ poseidon2HashWithSeparator([left, right], DomainSeparator.NULLIFIER_MERKLE) ++ // or PUBLIC_DATA_MERKLE, WRITTEN_SLOTS_MERKLE, RETRIEVED_BYTECODES_MERKLE +``` + +`poseidon2HashWithSeparator` is exported from `@aztec/foundation/crypto/poseidon`; the `DomainSeparator` enum and the matching `DOM_SEP__*` constants are defined in `@aztec/constants`. The new entries listed above are additions — existing separator names are unchanged. + +For TypeScript consumers, `@aztec/stdlib/hash` exports ready-made helpers that wrap the right separator: `computeMerkleHash` (append-only), `computeNullifierMerkleHash`, and `computePublicDataMerkleHash`. Prefer these over calling `poseidon2HashWithSeparator` directly so the separator choice stays colocated with the tree. + +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) ### [Aztec.nr] `emit_private_log_unsafe` / `emit_raw_note_log_unsafe` are deprecated `emit_private_log_unsafe` and `emit_raw_note_log_unsafe` are deprecated and will be removed in a future release. Migrate to the new `emit_private_log_vec_unsafe` / `emit_raw_note_log_vec_unsafe` functions, which take a `BoundedVec` instead of the `(log: [Field; PRIVATE_LOG_CIPHERTEXT_LEN], length: u32)` pair. @@ -128,7 +336,49 @@ This has been done because this is the format expected by the functionality in p The old `DEFAULT_GAS_LIMIT` and `DEFAULT_TEARDOWN_GAS_LIMIT` constants have been removed. Gas limits are now derived from protocol-level maximums (`MAX_PROCESSABLE_L2_GAS`, `MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT`) rather than arbitrary fixed values. +<<<<<<< HEAD A new `GasSettings.forEstimation()` method provides intentionally high gas limits for use during simulation. These limits exceed protocol maximums so the simulation doesn't hit gas caps — you must pass `skipTxValidation: true` when simulating with them, then use the results to set accurate gas limits on the actual transaction. `EmbeddedWallet` does this by default. +======= +**L1 contract changes:** + +- `SlasherFlavor` enum removed from `ISlasher.sol` +- `RollupConfigInput.slasherFlavor` (enum) replaced with `slasherEnabled` (bool) +- `TallySlashingProposer` contract renamed to `SlashingProposer` +- `TallySlasherDeploymentExtLib` library renamed to `SlasherDeploymentExtLib` +- `SlashFactory` periphery contract removed +- `SLASHING_PROPOSER_TYPE` constant removed from `SlashingProposer` +- All `TallySlashingProposer__` error prefixes renamed to `SlashingProposer__` + +**Environment variable changes:** + +```diff +- AZTEC_SLASHER_FLAVOR=tally # was: "tally" | "empire" | "none" ++ AZTEC_SLASHER_ENABLED=true # now a boolean +``` + +**Removed environment variables:** `SLASH_MIN_PENALTY_PERCENTAGE`, `SLASH_MAX_PENALTY_PERCENTAGE` + +**Removed from deploy outputs:** `slashFactoryAddress` + +**Node admin API:** `getSlashPayloads()` method removed. + +**TypeScript config changes:** + +```diff +- slasherFlavor: 'tally' | 'none' ++ slasherEnabled: boolean +``` + +`slashMinPenaltyPercentage` and `slashMaxPenaltyPercentage` removed from `SlasherConfig`. + +## Unreleased (v5) + +### [aztec.js] `DeployMethod.send()` always returns `{ contract, receipt, instance }` + +The `returnReceipt` option in deploy wait options has been removed. `DeployMethod.send()` now always returns an object with `contract`, `receipt`, and `instance` at the top level, provided the user waits for the transaction to be included. + +The `DeployTxReceipt` and `DeployWaitOptions` types have been removed. +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) **Migration:** diff --git a/docs/examples/ts/aave_bridge/index.ts b/docs/examples/ts/aave_bridge/index.ts new file mode 100644 index 000000000000..01f618b05d67 --- /dev/null +++ b/docs/examples/ts/aave_bridge/index.ts @@ -0,0 +1,419 @@ +import { getInitialTestAccountsData } from "@aztec/accounts/testing"; +import { AztecAddress, EthAddress } from "@aztec/aztec.js/addresses"; +import { SetPublicAuthwitContractInteraction } from "@aztec/aztec.js/authorization"; +import { Fr } from "@aztec/aztec.js/fields"; +import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node"; +import { createExtendedL1Client } from "@aztec/ethereum/client"; +import { deployL1Contract } from "@aztec/ethereum/deploy-l1-contract"; +import { sha256ToField } from "@aztec/foundation/crypto/sha256"; +import { + computeL2ToL1MessageHash, + computeSecretHash, +} from "@aztec/stdlib/hash"; +import { computeL2ToL1MembershipWitness } from "@aztec/stdlib/messaging"; +import { EmbeddedWallet } from "@aztec/wallets/embedded"; +import { decodeEventLog, pad, toFunctionSelector } from "@aztec/viem"; +import { foundry } from "@aztec/viem/chains"; +import AavePortal from "../../../target/solidity/aave_bridge/AavePortal.sol/AavePortal.json" with { type: "json" }; +import MockERC20 from "../../../target/solidity/aave_bridge/MockERC20.sol/MockERC20.json" with { type: "json" }; +import MockAToken from "../../../target/solidity/aave_bridge/MockAToken.sol/MockAToken.json" with { type: "json" }; +import MockAavePool from "../../../target/solidity/aave_bridge/MockAavePool.sol/MockAavePool.json" with { type: "json" }; +import { TokenContract } from "@aztec/noir-contracts.js/Token"; +import { AaveBridgeContract } from "./artifacts/AaveBridge.js"; + +// docs:start:setup +// Setup L1 client using anvil's default mnemonic +const MNEMONIC = "test test test test test test test test test test test junk"; +const l1Client = createExtendedL1Client( + [process.env.ETHEREUM_HOST ?? "http://localhost:8545"], + MNEMONIC, +); + +// Setup L2 using Aztec's local network +console.log("Setting up L2...\n"); +const node = createAztecNodeClient( + process.env.AZTEC_NODE_URL ?? "http://localhost:8080", +); +await waitForNode(node); +const aztecWallet = await EmbeddedWallet.create(node, { ephemeral: true }); +const [accData] = await getInitialTestAccountsData(); +const account = await aztecWallet.createSchnorrAccount( + accData.secret, + accData.salt, + accData.signingKey, +); +console.log(`Account: ${account.address.toString()}\n`); + +// Get node info +const nodeInfo = await node.getNodeInfo(); +const registryAddress = nodeInfo.l1ContractAddresses.registryAddress.toString(); +const inboxAddress = nodeInfo.l1ContractAddresses.inboxAddress.toString(); +// docs:end:setup + +// docs:start:deploy_l1 +console.log("Deploying L1 contracts...\n"); + +// Deploy MockERC20 (underlying token, e.g. DAI) +const { address: underlyingAddress } = await deployL1Contract( + l1Client, + MockERC20.abi, + MockERC20.bytecode.object as `0x${string}`, + ["Mock DAI", "mDAI"], +); + +// Deploy MockAToken (Aave's yield-bearing token) +const { address: aTokenAddress } = await deployL1Contract( + l1Client, + MockAToken.abi, + MockAToken.bytecode.object as `0x${string}`, + ["Aave Mock DAI", "amDAI"], +); + +// Deploy MockAavePool with 10% yield (1000 basis points) +const { address: poolAddress } = await deployL1Contract( + l1Client, + MockAavePool.abi, + MockAavePool.bytecode.object as `0x${string}`, + [underlyingAddress.toString(), aTokenAddress.toString(), 1000n], +); + +// Deploy AavePortal +const { address: portalAddress } = await deployL1Contract( + l1Client, + AavePortal.abi, + AavePortal.bytecode.object as `0x${string}`, +); + +console.log(`MockERC20 (DAI): ${underlyingAddress}`); +console.log(`MockAToken (aDAI): ${aTokenAddress}`); +console.log(`MockAavePool: ${poolAddress}`); +console.log(`AavePortal: ${portalAddress}\n`); +// docs:end:deploy_l1 + +// docs:start:deploy_l2 +console.log("Deploying L2 contracts...\n"); + +// Deploy the Token contract on L2 (this is the standard Aztec token) +const { contract: l2Token } = await TokenContract.deploy( + aztecWallet, + account.address, // admin + "Bridged DAI", + "bDAI", + 18, +).send({ from: account.address }); + +// Deploy the AaveBridge on L2 +const { contract: l2Bridge } = await AaveBridgeContract.deploy( + aztecWallet, + l2Token.address, + EthAddress.fromString(portalAddress.toString()), +).send({ from: account.address }); + +console.log(`L2 Token: ${l2Token.address.toString()}`); +console.log(`L2 Bridge: ${l2Bridge.address.toString()}\n`); +// docs:end:deploy_l2 + +// docs:start:initialize +console.log("Initializing contracts..."); + +// Initialize the L1 portal +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const initHash = await l1Client.writeContract({ + address: portalAddress.toString() as `0x${string}`, + abi: AavePortal.abi, + functionName: "initialize", + args: [ + registryAddress, + underlyingAddress.toString(), + aTokenAddress.toString(), + poolAddress.toString(), + l2Bridge.address.toString(), + ], +}); +await l1Client.waitForTransactionReceipt({ hash: initHash }); + +// Set the bridge as a minter on the L2 token so it can mint when claiming +await l2Token.methods + .set_minter(l2Bridge.address, true) + .send({ from: account.address }); + +console.log("All contracts initialized\n"); +// docs:end:initialize + +// docs:start:fund_user +// Pre-fund the portal with L1 tokens and mint L2 tokens to the user +// In a real scenario, tokens would already exist on L2 from a prior bridge +console.log("Funding user with tokens on L2..."); + +const depositAmount = 1000n * 10n ** 18n; // 1000 DAI + +// Mint underlying tokens on L1 +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const mintHash = await l1Client.writeContract({ + address: underlyingAddress.toString() as `0x${string}`, + abi: MockERC20.abi, + functionName: "mint", + args: [portalAddress.toString(), depositAmount], +}); +await l1Client.waitForTransactionReceipt({ hash: mintHash }); + +// Also mint tokens directly to the user on L2 (admin mints for simplicity) +await l2Token.methods + .mint_to_public(account.address, depositAmount) + .send({ from: account.address }); + +console.log(`User funded with ${depositAmount / 10n ** 18n} tokens on L2\n`); +// docs:end:fund_user + +// docs:start:mine_blocks +// On the local network, L2 blocks are only produced when transactions are submitted. +// L1-to-L2 messages require 2 L2 blocks before they can be consumed, so we deploy +// two dummy contracts (with random salts for unique addresses) to force block production. +async function mine2Blocks( + aztecWallet: EmbeddedWallet, + accountAddress: AztecAddress, +) { + await AaveBridgeContract.deploy( + aztecWallet, + accountAddress, + EthAddress.ZERO, + ).send({ + from: accountAddress, + }); + await AaveBridgeContract.deploy( + aztecWallet, + accountAddress, + EthAddress.ZERO, + ).send({ + from: accountAddress, + }); +} +// docs:end:mine_blocks + +// docs:start:deposit_to_aave +// ============================================================ +// STEP 1: Deposit to Aave (L2 -> L1 flow) +// ============================================================ +console.log("=== Depositing to Aave ===\n"); + +const amountToDeposit = 500n * 10n ** 18n; // 500 DAI + +// Create authwit for the bridge to burn tokens on our behalf. +// The bridge calls Token::burn_public(user, amount, nonce), where msg_sender +// is the bridge, so the token contract requires a public authwit. +const burnNonce = Fr.random(); +const burnAuthwit = await SetPublicAuthwitContractInteraction.create( + aztecWallet, + account.address, + { + caller: l2Bridge.address, + action: l2Token.methods.burn_public( + account.address, + amountToDeposit, + burnNonce, + ), + }, + true, +); +await burnAuthwit.send(); + +// On L2: burn tokens and send L2->L1 message. +// exit_to_l1_public sends tokens to the portal as the L1 recipient, +// and caller_on_l1 is set to ZERO so anyone can relay the message. +const { receipt: exitReceipt } = await l2Bridge.methods + .exit_to_l1_public( + EthAddress.fromString(portalAddress.toString()), // recipient on L1 (the portal itself) + amountToDeposit, + EthAddress.ZERO, // caller_on_l1: anyone can relay + burnNonce, // authwit nonce authorizing the bridge to burn on our behalf + ) + .send({ from: account.address }); + +console.log(`Exit sent (block: ${exitReceipt.blockNumber})`); +// docs:end:deposit_to_aave + +// docs:start:get_deposit_witness +// Compute the L2->L1 content hash for the withdrawal witness. +// This must match what the L1 portal reconstructs via abi.encodeWithSignature. +// toFunctionSelector computes keccak256 of the signature and takes the first 4 bytes. +const portalEthAddress = EthAddress.fromString(portalAddress.toString()); +const withdrawContent = sha256ToField([ + Buffer.from( + toFunctionSelector("withdraw(address,uint256,address)").substring(2), + "hex", + ), + portalEthAddress.toBuffer32(), + new Fr(amountToDeposit).toBuffer(), + EthAddress.ZERO.toBuffer32(), +]); + +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const version = (await l1Client.readContract({ + address: portalAddress.toString() as `0x${string}`, + abi: AavePortal.abi, + functionName: "rollupVersion", +})) as bigint; + +const msgLeaf = computeL2ToL1MessageHash({ + l2Sender: l2Bridge.address, + l1Recipient: portalEthAddress, + content: withdrawContent, + rollupVersion: new Fr(version), + chainId: new Fr(foundry.id), +}); + +// Wait for the block to be proven +if (!exitReceipt.blockNumber) { + throw new Error("Exit transaction was not included in a block"); +} +const exitBlockNumber = exitReceipt.blockNumber; +console.log("Waiting for block to be proven..."); +let provenBlockNumber = await node.getBlockNumber("proven"); +while (provenBlockNumber < exitBlockNumber) { + console.log( + ` Waiting... (proven: ${provenBlockNumber}, needed: ${exitBlockNumber})`, + ); + await new Promise((resolve) => setTimeout(resolve, 10000)); + provenBlockNumber = await node.getBlockNumber("proven"); +} +console.log("Block proven!\n"); + +// Compute the membership witness using the message hash and the L2 tx hash +const witness = await computeL2ToL1MembershipWitness( + node, + msgLeaf, + exitReceipt.txHash, +); +const epoch = witness!.epochNumber; + +const siblingPathHex = witness!.siblingPath + .toBufferArray() + .map((buf: Buffer) => `0x${buf.toString("hex")}` as `0x${string}`); +// docs:end:get_deposit_witness + +// docs:start:execute_deposit_l1 +// On L1: consume the outbox message and deposit into Aave +console.log("Depositing into Aave on L1..."); +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const depositToAaveHash = await l1Client.writeContract({ + address: portalAddress.toString() as `0x${string}`, + abi: AavePortal.abi, + functionName: "depositToAave", + args: [ + portalAddress.toString(), // recipient (matches L2 exit) + amountToDeposit, + false, // withCaller = false (matches caller_on_l1 = address(0)) + BigInt(epoch), + BigInt(witness!.leafIndex), + siblingPathHex, + ], +}); +await l1Client.waitForTransactionReceipt({ hash: depositToAaveHash }); +console.log("Tokens deposited into Aave!\n"); +// docs:end:execute_deposit_l1 + +// docs:start:claim_from_aave_l1 +// ============================================================ +// STEP 2: Claim from Aave with yield (L1 -> L2 flow) +// ============================================================ +console.log("=== Claiming from Aave (with yield) ===\n"); + +const secret = Fr.random(); +const secretHash = await computeSecretHash(secret); + +// On L1: withdraw from Aave and send L1->L2 message +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const claimHash = await l1Client.writeContract({ + address: portalAddress.toString() as `0x${string}`, + abi: AavePortal.abi, + functionName: "claimFromAavePublic", + args: [ + amountToDeposit, // aToken amount to withdraw + pad(account.address.toString() as `0x${string}`, { dir: "left", size: 32 }), // L2 recipient + pad(secretHash.toString() as `0x${string}`, { dir: "left", size: 32 }), + ], +}); +const claimReceipt = await l1Client.waitForTransactionReceipt({ + hash: claimHash, +}); +console.log("Aave withdrawal complete, L1->L2 message sent"); +// docs:end:claim_from_aave_l1 + +// docs:start:get_claim_leaf_index +// Extract the message leaf index from the MessageSent event +const INBOX_ABI = [ + { + type: "event", + name: "MessageSent", + inputs: [ + { name: "checkpointNumber", type: "uint256", indexed: true }, + { name: "index", type: "uint256", indexed: false }, + { name: "hash", type: "bytes32", indexed: true }, + { name: "rollingHash", type: "bytes16", indexed: false }, + ], + }, +] as const; + +const messageSentLogs = claimReceipt.logs + .filter((log) => log.address.toLowerCase() === inboxAddress.toLowerCase()) + .map((log: any) => { + try { + const decoded = decodeEventLog({ + abi: INBOX_ABI, + data: log.data, + topics: log.topics, + }); + return { log, decoded }; + } catch { + return null; + } + }) + .filter( + (item): item is { log: any; decoded: any } => + item !== null && (item.decoded as any).eventName === "MessageSent", + ); + +const messageLeafIndex = new Fr(messageSentLogs[0].decoded.args.index); +console.log(`Message leaf index: ${messageLeafIndex}\n`); +// docs:end:get_claim_leaf_index + +// docs:start:claim_on_l2 +// Mine blocks so the L1->L2 message is available +await mine2Blocks(aztecWallet, account.address); + +// The mock Aave pool returns 10% yield, so 500 DAI becomes 550 DAI +const expectedWithYield = amountToDeposit + (amountToDeposit * 1000n) / 10000n; +console.log( + `Expected amount with yield: ${expectedWithYield / 10n ** 18n} tokens`, +); + +// On L2: consume the L1->L2 message and mint tokens (with yield) +console.log("Claiming tokens on L2..."); +await l2Bridge.methods + .claim_public(account.address, expectedWithYield, secret, messageLeafIndex) + .send({ from: account.address }); +console.log("Tokens claimed on L2!\n"); +// docs:end:claim_on_l2 + +// docs:start:verify +// Verify the user's balance includes yield +console.log("=== Verifying balances ===\n"); + +const { result: finalBalance } = await l2Token.methods + .balance_of_public(account.address) + .simulate({ from: account.address }); + +const initialRemaining = depositAmount - amountToDeposit; // 500 DAI not deposited +const expectedFinal = initialRemaining + expectedWithYield; // 500 + 550 = 1050 DAI + +console.log(`Initial deposit: ${depositAmount / 10n ** 18n} tokens`); +console.log(`Deposited to Aave: ${amountToDeposit / 10n ** 18n} tokens`); +console.log( + `Yield earned (10%): ${(expectedWithYield - amountToDeposit) / 10n ** 18n} tokens`, +); +console.log(`Expected balance: ${expectedFinal / 10n ** 18n} tokens`); +console.log(`Actual balance: ${finalBalance / 10n ** 18n} tokens`); +console.log( + `\nYield earned successfully: ${finalBalance >= expectedFinal ? "YES" : "NO"}`, +); +// docs:end:verify diff --git a/docs/examples/ts/aztecjs_advanced/index.ts b/docs/examples/ts/aztecjs_advanced/index.ts index 7d22adf120c4..90f60cc5c675 100644 --- a/docs/examples/ts/aztecjs_advanced/index.ts +++ b/docs/examples/ts/aztecjs_advanced/index.ts @@ -16,14 +16,22 @@ import { getPublicEvents } from "@aztec/aztec.js/events"; import { GasSettings } from "@aztec/stdlib/gas"; // Setup: connect to network -const node = createAztecNodeClient(process.env.AZTEC_NODE_URL ?? "http://localhost:8080"); +const node = createAztecNodeClient( + process.env.AZTEC_NODE_URL ?? "http://localhost:8080", +); await waitForNode(node); const wallet = await EmbeddedWallet.create(node, { ephemeral: true }); const testAccounts = await getInitialTestAccountsData(); const [aliceAddress, bobAddress] = await Promise.all( testAccounts.slice(0, 2).map(async (account) => { - return (await wallet.createSchnorrAccount(account.secret, account.salt, account.signingKey)).address; + return ( + await wallet.createSchnorrAccount( + account.secret, + account.salt, + account.signingKey, + ) + ).address; }), ); @@ -45,8 +53,13 @@ const sponsoredFPCInstance = await getContractInstanceFromInstantiationParams( SponsoredFPCContract.artifact, { salt: new Fr(0) }, ); -await wallet.registerContract(sponsoredFPCInstance, SponsoredFPCContract.artifact); -const sponsoredPaymentMethod = new SponsoredFeePaymentMethod(sponsoredFPCInstance.address); +await wallet.registerContract( + sponsoredFPCInstance, + SponsoredFPCContract.artifact, +); +const sponsoredPaymentMethod = new SponsoredFeePaymentMethod( + sponsoredFPCInstance.address, +); // wallet is from the connection guide; sponsoredPaymentMethod is from the fees guide const { contract: sponsoredContract } = await TokenContract.deploy( @@ -68,9 +81,9 @@ const { contract: saltedContract } = await TokenContract.deploy( "SaltedToken", "SALT", 18, + { salt: customSalt }, ).send({ from: aliceAddress, - contractAddressSalt: customSalt, }); // docs:end:deploy_custom_salt @@ -84,8 +97,9 @@ const deployMethod = TokenContract.deploy( "PredictedToken", "PRED", 18, + { salt: deploymentSalt, deployer: aliceAddress }, ); -const instance = await deployMethod.getInstance({ contractAddressSalt: deploymentSalt }); +const instance = await deployMethod.getInstance(); const predictedAddress = instance.address; console.log(`Contract will deploy at: ${predictedAddress}`); @@ -235,15 +249,21 @@ console.log(`Derived token at: ${derivedToken.address.toString()}`); // docs:start:parallel_deploy // Deploy contracts in parallel using Promise.all const contracts = await Promise.all([ - TokenContract.deploy(wallet, aliceAddress, "Token1", "T1", 18).send({ - from: aliceAddress, - }).then(({ contract }) => contract), - TokenContract.deploy(wallet, aliceAddress, "Token2", "T2", 18).send({ - from: aliceAddress, - }).then(({ contract }) => contract), - TokenContract.deploy(wallet, aliceAddress, "Token3", "T3", 18).send({ - from: aliceAddress, - }).then(({ contract }) => contract), + TokenContract.deploy(wallet, aliceAddress, "Token1", "T1", 18) + .send({ + from: aliceAddress, + }) + .then(({ contract }) => contract), + TokenContract.deploy(wallet, aliceAddress, "Token2", "T2", 18) + .send({ + from: aliceAddress, + }) + .then(({ contract }) => contract), + TokenContract.deploy(wallet, aliceAddress, "Token3", "T3", 18) + .send({ + from: aliceAddress, + }) + .then(({ contract }) => contract), ]); console.log(`Contract 1 at: ${contracts[0].address}`); @@ -293,8 +313,12 @@ async function pollForTransferEvents() { for (const { event, metadata } of events) { // Process each transfer event - console.log(`Transfer: ${event.amount} from ${event.from} to ${event.to}`); - console.log(` in block ${metadata.l2BlockNumber}, tx ${metadata.txHash}`); + console.log( + `Transfer: ${event.amount} from ${event.from} to ${event.to}`, + ); + console.log( + ` in block ${metadata.l2BlockNumber}, tx ${metadata.txHash}`, + ); } lastProcessedBlock = currentBlock; @@ -307,7 +331,11 @@ await pollForTransferEvents(); // docs:start:connect_to_contract // wallet is from the connection guide; token is the contract deployed in the deploy guide -const contract = await Contract.at(token.address, TokenContract.artifact, wallet); +const contract = await Contract.at( + token.address, + TokenContract.artifact, + wallet, +); // docs:end:connect_to_contract // docs:start:basic_send_transaction @@ -333,7 +361,10 @@ console.log("DA gas limit:", metaResult.estimatedGas.gasLimits.daGas); // docs:end:simulate_with_metadata // docs:start:read_public_logs -const publicLogs = await node.getPublicLogs({ fromBlock: 1, toBlock: await node.getBlockNumber() + 1 }); +const publicLogs = await node.getPublicLogs({ + fromBlock: 1, + toBlock: (await node.getBlockNumber()) + 1, +}); if (publicLogs.logs.length > 0) { const rawFields = publicLogs.logs[0].log.getEmittedFields(); // Fr[] console.log("Raw log fields:", rawFields.length); @@ -385,16 +416,21 @@ const networkFees = await node.getCurrentMinFees(); const gasSettings = GasSettings.from({ gasLimits: { daGas: 100_000, l2Gas: 2_000_000 }, teardownGasLimits: { daGas: 100_000, l2Gas: 2_000_000 }, - maxFeesPerGas: { feePerDaGas: networkFees.feePerDaGas * 2n, feePerL2Gas: networkFees.feePerL2Gas * 2n }, + maxFeesPerGas: { + feePerDaGas: networkFees.feePerDaGas * 2n, + feePerL2Gas: networkFees.feePerL2Gas * 2n, + }, maxPriorityFeesPerGas: { feePerDaGas: 0n, feePerL2Gas: 0n }, }); // docs:end:custom_gas_settings // docs:start:send_with_gas_settings -const { receipt: gsReceipt } = await token.methods.mint_to_public(aliceAddress, 1n).send({ - from: aliceAddress, - fee: { gasSettings }, -}); +const { receipt: gsReceipt } = await token.methods + .mint_to_public(aliceAddress, 1n) + .send({ + from: aliceAddress, + fee: { gasSettings }, + }); // docs:end:send_with_gas_settings // docs:start:read_logs_by_filter @@ -402,7 +438,10 @@ const { receipt: gsReceipt } = await token.methods.mint_to_public(aliceAddress, const txLogs = await node.getPublicLogs({ txHash: gsReceipt.txHash }); // Get logs for a block range -const rangeLogs = await node.getPublicLogs({ fromBlock: 1, toBlock: await node.getBlockNumber() + 1 }); +const rangeLogs = await node.getPublicLogs({ + fromBlock: 1, + toBlock: (await node.getBlockNumber()) + 1, +}); // docs:end:read_logs_by_filter // docs:start:auto_gas_estimation @@ -435,5 +474,4 @@ const { result: privateBalance } = await token.methods .simulate({ from: aliceAddress }); // docs:end:simulate_private_access - console.log("All advanced examples completed successfully"); diff --git a/docs/examples/ts/example_swap/index.ts b/docs/examples/ts/example_swap/index.ts new file mode 100644 index 000000000000..883c120c5bad --- /dev/null +++ b/docs/examples/ts/example_swap/index.ts @@ -0,0 +1,594 @@ +// docs:start:setup +import { getInitialTestAccountsData } from "@aztec/accounts/testing"; +import { AztecAddress, EthAddress } from "@aztec/aztec.js/addresses"; +import { SetPublicAuthwitContractInteraction } from "@aztec/aztec.js/authorization"; +import { Fr } from "@aztec/aztec.js/fields"; +import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node"; +import { createExtendedL1Client } from "@aztec/ethereum/client"; +import { deployL1Contract } from "@aztec/ethereum/deploy-l1-contract"; +import { sha256ToField } from "@aztec/foundation/crypto/sha256"; +import { TokenContract } from "@aztec/noir-contracts.js/Token"; +import { TokenBridgeContract } from "@aztec/noir-contracts.js/TokenBridge"; +import { + computeL2ToL1MessageHash, + computeSecretHash, +} from "@aztec/stdlib/hash"; +import { computeL2ToL1MembershipWitness } from "@aztec/stdlib/messaging"; +import { decodeEventLog, encodeFunctionData, pad } from "@aztec/viem"; +import { EmbeddedWallet } from "@aztec/wallets/embedded"; +import { foundry } from "@aztec/viem/chains"; +import ExampleERC20 from "../../../target/solidity/example_swap/ExampleERC20.sol/ExampleERC20.json" with { type: "json" }; +import ExampleTokenPortal from "../../../target/solidity/example_swap/ExampleTokenPortal.sol/ExampleTokenPortal.json" with { type: "json" }; +import ExampleUniswapPortal from "../../../target/solidity/example_swap/ExampleUniswapPortal.sol/ExampleUniswapPortal.json" with { type: "json" }; +import { ExampleUniswapContract } from "./artifacts/ExampleUniswap.js"; + +// Setup L1 client +const MNEMONIC = "test test test test test test test test test test test junk"; +const l1RpcUrl = process.env.ETHEREUM_HOST ?? "http://localhost:8545"; +const l1Client = createExtendedL1Client([l1RpcUrl], MNEMONIC); +const ownerEthAddress = l1Client.account.address; + +// Setup L2 client +console.log("Setting up L2...\n"); +const nodeUrl = process.env.AZTEC_NODE_URL ?? "http://localhost:8080"; +const node = createAztecNodeClient(nodeUrl); +await waitForNode(node); +const wallet = await EmbeddedWallet.create(node, { ephemeral: true }); +const [accData] = await getInitialTestAccountsData(); +const account = await wallet.createSchnorrAccount( + accData.secret, + accData.salt, + accData.signingKey, +); +console.log(`Account: ${account.address.toString()}\n`); + +const nodeInfo = await node.getNodeInfo(); +const registryAddress = nodeInfo.l1ContractAddresses.registryAddress.toString(); +const inboxAddress = nodeInfo.l1ContractAddresses.inboxAddress.toString(); +// docs:end:setup + +// docs:start:deploy_l1 +console.log("Deploying L1 contracts...\n"); + +// Deploy two ERC20 tokens: WETH (input) and DAI (output) +const { address: wethAddress } = await deployL1Contract( + l1Client, + ExampleERC20.abi, + ExampleERC20.bytecode.object as `0x${string}`, + ["Wrapped Ether", "WETH"], +); + +const { address: daiAddress } = await deployL1Contract( + l1Client, + ExampleERC20.abi, + ExampleERC20.bytecode.object as `0x${string}`, + ["Dai Stablecoin", "DAI"], +); + +// Deploy two token portals (one per token) +const { address: wethPortalAddress } = await deployL1Contract( + l1Client, + ExampleTokenPortal.abi, + ExampleTokenPortal.bytecode.object as `0x${string}`, +); + +const { address: daiPortalAddress } = await deployL1Contract( + l1Client, + ExampleTokenPortal.abi, + ExampleTokenPortal.bytecode.object as `0x${string}`, +); + +// Deploy the uniswap portal +const { address: uniswapPortalAddress } = await deployL1Contract( + l1Client, + ExampleUniswapPortal.abi, + ExampleUniswapPortal.bytecode.object as `0x${string}`, +); + +console.log(`WETH: ${wethAddress}`); +console.log(`DAI: ${daiAddress}`); +console.log(`WETH Portal: ${wethPortalAddress}`); +console.log(`DAI Portal: ${daiPortalAddress}`); +console.log(`Uniswap Portal: ${uniswapPortalAddress}\n`); +// docs:end:deploy_l1 + +// docs:start:deploy_l2 +console.log("Deploying L2 contracts...\n"); + +// Deploy L2 tokens (using the standard TokenContract from @aztec/noir-contracts.js) +const { contract: l2Weth } = await TokenContract.deploy( + wallet, + account.address, + "Wrapped Ether", + "WETH", + 18, +).send({ from: account.address }); + +const { contract: l2Dai } = await TokenContract.deploy( + wallet, + account.address, + "Dai Stablecoin", + "DAI", + 18, +).send({ from: account.address }); + +// Deploy L2 token bridges +const { contract: l2WethBridge } = await TokenBridgeContract.deploy( + wallet, + l2Weth.address, + wethPortalAddress, +).send({ from: account.address }); + +const { contract: l2DaiBridge } = await TokenBridgeContract.deploy( + wallet, + l2Dai.address, + daiPortalAddress, +).send({ from: account.address }); + +// Deploy L2 uniswap contract +const { contract: l2Uniswap } = await ExampleUniswapContract.deploy( + wallet, + EthAddress.fromString(uniswapPortalAddress.toString()), +).send({ from: account.address }); + +console.log(`L2 WETH: ${l2Weth.address}`); +console.log(`L2 DAI: ${l2Dai.address}`); +console.log(`L2 WETH Bridge: ${l2WethBridge.address}`); +console.log(`L2 DAI Bridge: ${l2DaiBridge.address}`); +console.log(`L2 Uniswap: ${l2Uniswap.address}\n`); +// docs:end:deploy_l2 + +// docs:start:initialize +console.log("Initializing contracts...\n"); + +// Make bridges minters on their respective tokens +await l2Weth.methods + .set_minter(l2WethBridge.address, true) + .send({ from: account.address }); +await l2Dai.methods + .set_minter(l2DaiBridge.address, true) + .send({ from: account.address }); + +// Initialize L1 portals with registry, underlying token, and L2 bridge addresses +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const initWethPortal = await l1Client.writeContract({ + address: wethPortalAddress.toString() as `0x${string}`, + abi: ExampleTokenPortal.abi, + functionName: "initialize", + args: [ + registryAddress, + wethAddress.toString(), + l2WethBridge.address.toString(), + ], +}); +await l1Client.waitForTransactionReceipt({ hash: initWethPortal }); + +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const initDaiPortal = await l1Client.writeContract({ + address: daiPortalAddress.toString() as `0x${string}`, + abi: ExampleTokenPortal.abi, + functionName: "initialize", + args: [ + registryAddress, + daiAddress.toString(), + l2DaiBridge.address.toString(), + ], +}); +await l1Client.waitForTransactionReceipt({ hash: initDaiPortal }); + +// Initialize uniswap portal +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const initUniswapPortal = await l1Client.writeContract({ + address: uniswapPortalAddress.toString() as `0x${string}`, + abi: ExampleUniswapPortal.abi, + functionName: "initialize", + args: [registryAddress, l2Uniswap.address.toString()], +}); +await l1Client.waitForTransactionReceipt({ hash: initUniswapPortal }); + +console.log("All contracts initialized\n"); +// docs:end:initialize + +// docs:start:fund +console.log("Funding accounts...\n"); + +const SWAP_AMOUNT = 100n * 10n ** 18n; // 100 tokens + +// Mint WETH on L1 for the user +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const mintWethHash = await l1Client.writeContract({ + address: wethAddress.toString() as `0x${string}`, + abi: ExampleERC20.abi, + functionName: "mint", + args: [ownerEthAddress, SWAP_AMOUNT], +}); +await l1Client.waitForTransactionReceipt({ hash: mintWethHash }); + +// Pre-fund the uniswap portal with DAI (for the mock 1:1 swap) +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const mintDaiHash = await l1Client.writeContract({ + address: daiAddress.toString() as `0x${string}`, + abi: ExampleERC20.abi, + functionName: "mint", + args: [uniswapPortalAddress.toString(), SWAP_AMOUNT * 2n], +}); +await l1Client.waitForTransactionReceipt({ hash: mintDaiHash }); + +console.log(`Minted ${SWAP_AMOUNT} WETH to user`); +console.log(`Pre-funded uniswap portal with ${SWAP_AMOUNT * 2n} DAI\n`); +// docs:end:fund + +// docs:start:deposit_to_l2 +console.log("Depositing WETH to Aztec (L1 -> L2)...\n"); + +const depositSecret = Fr.random(); +const depositSecretHash = await computeSecretHash(depositSecret); + +// Approve WETH portal to take tokens +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const approveHash = await l1Client.writeContract({ + address: wethAddress.toString() as `0x${string}`, + abi: ExampleERC20.abi, + functionName: "approve", + args: [wethPortalAddress.toString(), SWAP_AMOUNT], +}); +await l1Client.waitForTransactionReceipt({ hash: approveHash }); + +// Deposit to Aztec publicly +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const depositHash = await l1Client.writeContract({ + address: wethPortalAddress.toString() as `0x${string}`, + abi: ExampleTokenPortal.abi, + functionName: "depositToAztecPublic", + args: [ + account.address.toString(), + SWAP_AMOUNT, + pad(depositSecretHash.toString() as `0x${string}`, { + dir: "left", + size: 32, + }), + ], +}); +const depositReceipt = await l1Client.waitForTransactionReceipt({ + hash: depositHash, +}); + +// Extract message leaf index from Inbox event +const INBOX_ABI = [ + { + type: "event", + name: "MessageSent", + inputs: [ + { name: "checkpointNumber", type: "uint256", indexed: true }, + { name: "index", type: "uint256", indexed: false }, + { name: "hash", type: "bytes32", indexed: true }, + { name: "rollingHash", type: "bytes16", indexed: false }, + ], + }, +] as const; + +const messageSentLogs = depositReceipt.logs + .filter((log) => log.address.toLowerCase() === inboxAddress.toLowerCase()) + .map((log: any) => { + try { + const decoded = decodeEventLog({ + abi: INBOX_ABI, + data: log.data, + topics: log.topics, + }); + return { log, decoded }; + } catch { + return null; + } + }) + .filter( + (item): item is { log: any; decoded: any } => + item !== null && (item.decoded as any).eventName === "MessageSent", + ); + +if (messageSentLogs.length === 0) { + throw new Error("No MessageSent events found in deposit transaction"); +} +const depositLeafIndex = new Fr(messageSentLogs[0].decoded.args.index); +console.log(`Deposit message leaf index: ${depositLeafIndex}\n`); +// docs:end:deposit_to_l2 + +// docs:start:mine_blocks +// Utility: mine 2 blocks (required before L1->L2 messages can be consumed) +async function mine2Blocks( + wallet: EmbeddedWallet, + accountAddress: AztecAddress, +) { + await TokenContract.deploy(wallet, accountAddress, "T", "T", 18).send({ + from: accountAddress, + }); + await TokenContract.deploy(wallet, accountAddress, "T", "T", 18).send({ + from: accountAddress, + }); +} +// docs:end:mine_blocks + +// docs:start:claim_on_l2 +console.log("Claiming WETH on L2...\n"); + +await mine2Blocks(wallet, account.address); + +await l2WethBridge.methods + .claim_public(account.address, SWAP_AMOUNT, depositSecret, depositLeafIndex) + .send({ from: account.address }); + +const { result: wethBalanceBefore } = await l2Weth.methods + .balance_of_public(account.address) + .simulate({ from: account.address }); +console.log(`L2 WETH balance after claim: ${wethBalanceBefore}\n`); +if (wethBalanceBefore !== SWAP_AMOUNT) { + throw new Error( + `Expected WETH balance ${SWAP_AMOUNT}, got ${wethBalanceBefore}`, + ); +} +console.log("✓ WETH claimed successfully on L2\n"); +// docs:end:claim_on_l2 + +// docs:start:public_swap +console.log("=== PUBLIC SWAP FLOW ===\n"); +console.log("Initiating public swap on L2 (WETH -> DAI)...\n"); + +// Force L2 block production so the claim message is included in a block before the swap +await mine2Blocks(wallet, account.address); + +const swapSecret = Fr.random(); +const swapSecretHash = await computeSecretHash(swapSecret); + +// Create authwit for the uniswap contract to transfer WETH on our behalf +const transferAction = l2Weth.methods.transfer_in_public( + account.address, + l2Uniswap.address, + SWAP_AMOUNT, + 0xdeadbeefn, +); +const authwit = await SetPublicAuthwitContractInteraction.create( + wallet, + account.address, + { caller: l2Uniswap.address, action: transferAction }, + true, +); +await authwit.send(); + +// Call swap_public on the L2 uniswap contract +const { receipt: swapReceipt } = await l2Uniswap.methods + .swap_public( + account.address, + l2WethBridge.address, + SWAP_AMOUNT, + l2DaiBridge.address, + 3000n, // fee tier + 0n, // minimum output + account.address, // recipient + swapSecretHash, + ) + .send({ from: account.address }); + +console.log(`Swap tx sent (block: ${swapReceipt.blockNumber})\n`); + +// Verify WETH was spent (balance should be 0 after swap) +const { result: wethAfterSwap } = await l2Weth.methods + .balance_of_public(account.address) + .simulate({ from: account.address }); +if (wethAfterSwap !== 0n) { + throw new Error(`Expected WETH balance 0 after swap, got ${wethAfterSwap}`); +} +console.log("✓ WETH transferred to bridge for swap\n"); +// docs:end:public_swap + +// docs:start:wait_for_proof +console.log("Waiting for block to be proven...\n"); + +let provenBlockNumber = await node.getBlockNumber("proven"); +while (provenBlockNumber < swapReceipt.blockNumber!) { + console.log( + ` Waiting... (proven: ${provenBlockNumber}, needed: ${swapReceipt.blockNumber})`, + ); + await new Promise((resolve) => setTimeout(resolve, 10000)); + provenBlockNumber = await node.getBlockNumber("proven"); +} + +console.log("Block proven!\n"); +// docs:end:wait_for_proof + +// docs:start:consume_l1_messages_setup +console.log("Consuming L2->L1 messages on L1...\n"); + +// The swap generates 2 L2->L1 messages: +// 1. Token bridge exit (withdraw WETH to uniswap portal) +// 2. Uniswap swap intent + +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const portalRollupVersion = (await l1Client.readContract({ + address: wethPortalAddress.toString() as `0x${string}`, + abi: ExampleTokenPortal.abi, + functionName: "rollupVersion", +})) as bigint; + +// Compute message 1: token bridge exit +// Encode using the same approach as Solidity's abi.encodeWithSignature("withdraw(address,uint256,address)", ...) +const withdrawContentEncoded = encodeFunctionData({ + abi: [ + { + name: "withdraw", + type: "function", + inputs: [ + { name: "", type: "address" }, + { name: "", type: "uint256" }, + { name: "", type: "address" }, + ], + outputs: [], + }, + ], + args: [ + uniswapPortalAddress.toString() as `0x${string}`, + SWAP_AMOUNT, + uniswapPortalAddress.toString() as `0x${string}`, + ], +}); +const withdrawContentHash = sha256ToField([ + Buffer.from(withdrawContentEncoded.slice(2), "hex"), +]); + +// Message 1: Token bridge exit message +const exitMsgLeaf = computeL2ToL1MessageHash({ + l2Sender: l2WethBridge.address, + l1Recipient: wethPortalAddress, + content: withdrawContentHash, + rollupVersion: new Fr(portalRollupVersion), + chainId: new Fr(foundry.id), +}); +// docs:end:consume_l1_messages_setup + +// docs:start:consume_l1_messages_witnesses +const exitWitness = await computeL2ToL1MembershipWitness( + node, + exitMsgLeaf, + swapReceipt.txHash, +); +const exitSiblingPath = exitWitness!.siblingPath + .toBufferArray() + .map((buf: Buffer) => `0x${buf.toString("hex")}` as `0x${string}`); + +// Message 2: Uniswap swap intent message +// Compute using the same encoding as ExampleUniswapPortal.sol +const swapContentEncoded = encodeFunctionData({ + abi: [ + { + name: "swap_public", + type: "function", + inputs: [ + { name: "", type: "address" }, + { name: "", type: "uint256" }, + { name: "", type: "uint24" }, + { name: "", type: "address" }, + { name: "", type: "uint256" }, + { name: "", type: "bytes32" }, + { name: "", type: "bytes32" }, + ], + outputs: [], + }, + ], + args: [ + wethPortalAddress.toString() as `0x${string}`, + SWAP_AMOUNT, + 3000, + daiPortalAddress.toString() as `0x${string}`, + 0n, + account.address.toString() as `0x${string}`, + pad(swapSecretHash.toString() as `0x${string}`, { + dir: "left", + size: 32, + }), + ], +}); + +const swapContentHash = sha256ToField([ + Buffer.from(swapContentEncoded.slice(2), "hex"), +]); + +const swapMsgLeaf = computeL2ToL1MessageHash({ + l2Sender: l2Uniswap.address, + l1Recipient: uniswapPortalAddress, + content: swapContentHash, + rollupVersion: new Fr(portalRollupVersion), + chainId: new Fr(foundry.id), +}); + +const swapWitness = await computeL2ToL1MembershipWitness( + node, + swapMsgLeaf, + swapReceipt.txHash, +); +const swapSiblingPath = swapWitness!.siblingPath + .toBufferArray() + .map((buf: Buffer) => `0x${buf.toString("hex")}` as `0x${string}`); +// docs:end:consume_l1_messages_witnesses + +// docs:start:consume_l1_messages_execute +// Execute the swap on L1 (consumes both messages) +// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs +const l1SwapHash = await l1Client.writeContract({ + address: uniswapPortalAddress.toString() as `0x${string}`, + abi: ExampleUniswapPortal.abi, + functionName: "swapPublic", + args: [ + wethPortalAddress.toString(), + SWAP_AMOUNT, + 3000, + daiPortalAddress.toString(), + 0n, + account.address.toString(), + pad(swapSecretHash.toString() as `0x${string}`, { + dir: "left", + size: 32, + }), + [BigInt(exitWitness!.epochNumber), BigInt(swapWitness!.epochNumber)], + [BigInt(exitWitness!.leafIndex), BigInt(swapWitness!.leafIndex)], + [exitSiblingPath, swapSiblingPath], + ], +}); +const l1SwapReceipt = await l1Client.waitForTransactionReceipt({ + hash: l1SwapHash, +}); +console.log(`L1 swap executed! Tx: ${l1SwapHash}\n`); +// docs:end:consume_l1_messages_execute + +// docs:start:claim_output +console.log("Claiming DAI output on L2...\n"); + +// Extract the deposit message leaf index from the L1 swap receipt +const daiDepositLogs = l1SwapReceipt.logs + .filter((log) => log.address.toLowerCase() === inboxAddress.toLowerCase()) + .map((log: any) => { + try { + const decoded = decodeEventLog({ + abi: INBOX_ABI, + data: log.data, + topics: log.topics, + }); + return { log, decoded }; + } catch { + return null; + } + }) + .filter( + (item): item is { log: any; decoded: any } => + item !== null && (item.decoded as any).eventName === "MessageSent", + ); + +if (daiDepositLogs.length === 0) { + throw new Error("No MessageSent events found in L1 swap transaction"); +} +const daiDepositLeafIndex = new Fr(daiDepositLogs[0].decoded.args.index); + +// Mine blocks and claim +await mine2Blocks(wallet, account.address); + +await l2DaiBridge.methods + .claim_public(account.address, SWAP_AMOUNT, swapSecret, daiDepositLeafIndex) + .send({ from: account.address }); + +const { result: daiBalance } = await l2Dai.methods + .balance_of_public(account.address) + .simulate({ from: account.address }); + +const { result: wethBalanceAfter } = await l2Weth.methods + .balance_of_public(account.address) + .simulate({ from: account.address }); + +console.log(`L2 WETH balance: ${wethBalanceAfter}`); +console.log(`L2 DAI balance: ${daiBalance}`); + +if (wethBalanceAfter !== 0n) { + throw new Error(`Expected final WETH balance 0, got ${wethBalanceAfter}`); +} +if (daiBalance !== SWAP_AMOUNT) { + throw new Error(`Expected DAI balance ${SWAP_AMOUNT}, got ${daiBalance}`); +} +console.log("\n✓ All checks passed — public swap complete!\n"); +// docs:end:claim_output diff --git a/docs/examples/ts/token_bridge/index.ts b/docs/examples/ts/token_bridge/index.ts index 728f285164bc..afefee3bfa44 100644 --- a/docs/examples/ts/token_bridge/index.ts +++ b/docs/examples/ts/token_bridge/index.ts @@ -63,7 +63,10 @@ console.log(`NFTPortal: ${portalAddress}\n`); // docs:start:deploy_l2_contracts console.log("Deploying L2 contracts...\n"); -const { contract: l2Nft } = await NFTPunkContract.deploy(aztecWallet, account.address).send({ +const { contract: l2Nft } = await NFTPunkContract.deploy( + aztecWallet, + account.address, +).send({ from: account.address, }); @@ -201,11 +204,9 @@ async function mine2Blocks( ) { await NFTPunkContract.deploy(aztecWallet, accountAddress).send({ from: accountAddress, - contractAddressSalt: Fr.random(), }); await NFTPunkContract.deploy(aztecWallet, accountAddress).send({ from: accountAddress, - contractAddressSalt: Fr.random(), }); } // docs:end:mine_blocks @@ -289,7 +290,11 @@ const msgLeaf = computeL2ToL1MessageHash({ console.log("Waiting for block to be proven..."); console.log(` Exit block number: ${exitReceipt.blockNumber}`); +<<<<<<< HEAD let provenBlockNumber = await node.getProvenBlockNumber(); +======= +let provenBlockNumber = await node.getBlockNumber("proven"); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) console.log(` Current proven block: ${provenBlockNumber}`); while (provenBlockNumber < exitReceipt.blockNumber!) { @@ -297,13 +302,21 @@ while (provenBlockNumber < exitReceipt.blockNumber!) { ` Waiting... (proven: ${provenBlockNumber}, needed: ${exitReceipt.blockNumber})`, ); await new Promise((resolve) => setTimeout(resolve, 10000)); // Wait 10 seconds +<<<<<<< HEAD provenBlockNumber = await node.getProvenBlockNumber(); +======= + provenBlockNumber = await node.getBlockNumber("proven"); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) } console.log("Block proven!\n"); // Compute the membership witness using the message hash and the L2 tx hash -const witness = await computeL2ToL1MembershipWitness(node, msgLeaf, exitReceipt.txHash); +const witness = await computeL2ToL1MembershipWitness( + node, + msgLeaf, + exitReceipt.txHash, +); const epoch = witness!.epochNumber; console.log(` Epoch for block ${exitReceipt.blockNumber}: ${epoch}`); diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr index 8ab6ecb42db4..17d9b9f14746 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr @@ -8,7 +8,11 @@ use crate::protocol::{ address::AztecAddress, constants::{ CONTRACT_INSTANCE_LENGTH, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_LOGS_PER_TX, +<<<<<<< HEAD PRIVATE_LOG_SIZE_IN_FIELDS, +======= + NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_SIZE_IN_FIELDS, +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }, contract_instance::ContractInstance, traits::{Deserialize, ToField}, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 16fd271a96b6..4c39ceaa468f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -762,6 +762,13 @@ pub global DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER: u32 = 3990889078; /// Domain separator for L1 to L2 message secret hashes. pub global DOM_SEP__SECRET_HASH: u32 = 4199652938; +<<<<<<< HEAD +======= +/// Domain separator for the secret hash stored in handshake notes produced by the handshake registry contract. +/// Kept distinct from [`DOM_SEP__SECRET_HASH`] (which is specifically for L1 to L2 messages). +pub global DOM_SEP__HANDSHAKE_SECRET_HASH: u32 = 3596796143; + +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) /// Domain separator for transaction nullifiers. /// /// Used to produce cancellable (replaceable) transactions. diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr index 8ade1f4e9cbb..c19267aa3fe1 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr @@ -10,6 +10,7 @@ use crate::{ DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__CONTRACT_ADDRESS_V1, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY, DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FUNCTION_ARGS, +<<<<<<< HEAD DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, DOM_SEP__IVSK_M, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, DOM_SEP__OVSK_M, @@ -17,6 +18,17 @@ use crate::{ DOM_SEP__PRIVATE_FUNCTION_LEAF, DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, DOM_SEP__PRIVATE_LOG_FIRST_FIELD, DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, DOM_SEP__PUBLIC_BYTECODE, DOM_SEP__PUBLIC_CALLDATA, +======= + DOM_SEP__HANDSHAKE_SECRET_HASH, DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, + DOM_SEP__IVSK_M, DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_COMPLETION_LOG_TAG, + DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, + DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS, + DOM_SEP__PARTIAL_NOTE_COMMITMENT, DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, + DOM_SEP__PRIVATE_FUNCTION_LEAF, DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, + DOM_SEP__PRIVATE_LOG_FIRST_FIELD, DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, + DOM_SEP__PUBLIC_BYTECODE, DOM_SEP__PUBLIC_CALLDATA, DOM_SEP__PUBLIC_DATA_MERKLE, +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) DOM_SEP__PUBLIC_INITIALIZATION_NULLIFIER, DOM_SEP__PUBLIC_KEYS_HASH, DOM_SEP__PUBLIC_LEAF_SLOT, DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, DOM_SEP__PUBLIC_TX_HASH, DOM_SEP__SECRET_HASH, DOM_SEP__SIGNATURE_PAYLOAD, DOM_SEP__SILOED_NOTE_HASH, @@ -166,6 +178,14 @@ fn hashed_values_match_derived() { DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, "unconstrained_msg_log_tag", ); +<<<<<<< HEAD +======= + tester.assert_dom_sep_matches_derived( + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + "non_interactive_handshake_log_tag", + ); + tester.assert_dom_sep_matches_derived(DOM_SEP__HANDSHAKE_SECRET_HASH, "handshake_secret_hash"); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) tester.assert_dom_sep_matches_derived(DOM_SEP__MESSAGE_NULLIFIER, "message_nullifier"); tester.assert_dom_sep_matches_derived(DOM_SEP__PRIVATE_FUNCTION_LEAF, "private_function_leaf"); tester.assert_dom_sep_matches_derived(DOM_SEP__PUBLIC_BYTECODE, "public_bytecode"); diff --git a/playground/src/components/contract/components/CreateContractDialog.tsx b/playground/src/components/contract/components/CreateContractDialog.tsx index df62af0305a2..0b2ac8d34a6f 100644 --- a/playground/src/components/contract/components/CreateContractDialog.tsx +++ b/playground/src/components/contract/components/CreateContractDialog.tsx @@ -115,17 +115,13 @@ export function CreateContractDialog({ if (publiclyDeploy) { const postDeployCtor = (instance: ContractInstanceWithAddress, wallet: Wallet) => Contract.at(instance.address, contractArtifact, wallet); - deployMethod = new DeployMethod( - contract.publicKeys, - wallet, - contractArtifact, - postDeployCtor, - parameters, - initializer?.name, - ); + deployMethod = new DeployMethod(wallet, contractArtifact, postDeployCtor, parameters, initializer?.name, { + publicKeys: contract.publicKeys, + salt: contract.salt, + deployer: from, + }); opts = { from, - contractAddressSalt: salt, fee: { paymentMethod: feePaymentMethod }, }; onClose(contract, publiclyDeploy, deployMethod, opts); diff --git a/yarn-project/aztec.js/src/api/contract.ts b/yarn-project/aztec.js/src/api/contract.ts index 4443cae6d60c..67e458b4263d 100644 --- a/yarn-project/aztec.js/src/api/contract.ts +++ b/yarn-project/aztec.js/src/api/contract.ts @@ -71,12 +71,16 @@ export { DefaultWaitOpts, type WaitOpts } from '../contract/wait_opts.js'; export { ContractBase, type ContractMethod, type ContractStorageLayout } from '../contract/contract_base.js'; export { BatchCall } from '../contract/batch_call.js'; export { + type DeployInstantiationOptions, type DeployOptions, type DeployResultMined, type DeployReturn, +<<<<<<< HEAD type DeployTxReceipt, type DeployWaitOptions, type DeployInteractionWaitOptions, +======= +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) DeployMethod, type RequestDeployOptions, type SimulateDeployOptions, diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index eb93891a361c..7243f73eb362 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -1,5 +1,4 @@ import { Fr } from '@aztec/foundation/curves/bn254'; -import { type ContractArtifact, FunctionType } from '@aztec/stdlib/abi'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import { CompleteAddress, @@ -8,11 +7,11 @@ import { } from '@aztec/stdlib/contract'; import type { TxExecutionRequest, TxReceipt, UtilityExecutionResult } from '@aztec/stdlib/tx'; import { OFFCHAIN_MESSAGE_IDENTIFIER } from '@aztec/stdlib/tx'; -import { DEV_VERSION } from '@aztec/stdlib/update-checker'; import { type MockProxy, mock } from 'jest-mock-extended'; import type { Account } from '../account/account.js'; +import { testContractArtifact } from '../test/fixtures.js'; import type { TxSimulationResultWithAppOffset } from '../wallet/tx_simulation_result_with_app_offset.js'; import type { Wallet } from '../wallet/wallet.js'; import { Contract } from './contract.js'; @@ -36,6 +35,7 @@ describe('Contract Class', () => { anchorBlockTimestamp: 0n, } as any as UtilityExecutionResult; +<<<<<<< HEAD const defaultArtifact: ContractArtifact = { name: 'FooContract', aztecVersion: DEV_VERSION, @@ -191,12 +191,14 @@ describe('Contract Class', () => { storageLayout: {}, }; +======= +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) beforeEach(async () => { contractAddress = await AztecAddress.random(); account = mock(); accountAddress = await CompleteAddress.random(); account.getCompleteAddress.mockReturnValue(accountAddress); - const contractClass = await getContractClassFromArtifact(defaultArtifact); + const contractClass = await getContractClassFromArtifact(testContractArtifact); contractInstance = { address: contractAddress, currentContractClassId: contractClass.id, @@ -212,7 +214,7 @@ describe('Contract Class', () => { }); it('should create and send a contract method tx', async () => { - const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); + const fooContract = Contract.at(contractAddress, testContractArtifact, wallet); const param0 = 12; const param1 = 345n; const { receipt } = await fooContract.methods.bar(param0, param1).send({ from: account.getAddress() }); @@ -222,7 +224,7 @@ describe('Contract Class', () => { }); it('should call view on a utility function', async () => { - const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); + const fooContract = Contract.at(contractAddress, testContractArtifact, wallet); const { result } = await fooContract.methods.qux(123n).simulate({ from: account.getAddress() }); expect(wallet.executeUtility).toHaveBeenCalledTimes(1); expect(wallet.executeUtility).toHaveBeenCalledWith( @@ -255,7 +257,7 @@ describe('Contract Class', () => { wallet.simulateTx.mockResolvedValue(txSimResult); - const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); + const fooContract = Contract.at(contractAddress, testContractArtifact, wallet); const result = await fooContract.methods.bar(1, 2).simulate({ from: account.getAddress() }); expect(result.offchainMessages).toHaveLength(1); @@ -289,7 +291,7 @@ describe('Contract Class', () => { anchorBlockTimestamp, } as any); - const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); + const fooContract = Contract.at(contractAddress, testContractArtifact, wallet); const result = await fooContract.methods.qux(123n).simulate({ from: account.getAddress() }); expect(result.offchainMessages).toHaveLength(1); @@ -304,14 +306,14 @@ describe('Contract Class', () => { }); it('allows nullish values for Option parameters', () => { - const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); + const fooContract = Contract.at(contractAddress, testContractArtifact, wallet); expect(() => fooContract.methods.optionEcho(undefined)).not.toThrow(); expect(() => fooContract.methods.optionEcho(null)).not.toThrow(); }); it('still rejects nullish values for non-Option parameters', () => { - const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); + const fooContract = Contract.at(contractAddress, testContractArtifact, wallet); expect(() => fooContract.methods.bar(undefined, 123n)).toThrow( 'Null or undefined arguments are only allowed for Option parameters in bar(value: Field, value: Field). Received: (undefined, 123n).', @@ -322,7 +324,7 @@ describe('Contract Class', () => { }); it('rejects nullish non-Option param even when Option param is valid', () => { - const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); + const fooContract = Contract.at(contractAddress, testContractArtifact, wallet); expect(() => fooContract.methods.mixedParams({ w: 1n }, undefined)).toThrow( 'Null or undefined arguments are only allowed for Option parameters in mixedParams(optValue: Option, aField: Field). Received: ({ w: 1n }, undefined).', @@ -341,7 +343,7 @@ describe('Contract Class', () => { ['object', { a: 1n, b: 'x' }, '{ a: 1n, b: x }'], ['array', [1n, 2n], '[1n, 2n]'], ])('formats %s argument in error message', (_label, value, expectedFormatted) => { - const fooContract = Contract.at(contractAddress, defaultArtifact, wallet); + const fooContract = Contract.at(contractAddress, testContractArtifact, wallet); // pass the test value first and undefined second to trigger the error whose message we want to test for expect(() => fooContract.methods.bar(value, undefined)).toThrow(`Received: (${expectedFormatted}, undefined).`); diff --git a/yarn-project/aztec.js/src/contract/contract.ts b/yarn-project/aztec.js/src/contract/contract.ts index 01c13e31e28e..8f1c526667fb 100644 --- a/yarn-project/aztec.js/src/contract/contract.ts +++ b/yarn-project/aztec.js/src/contract/contract.ts @@ -1,11 +1,10 @@ import type { ContractArtifact } from '@aztec/stdlib/abi'; import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract'; -import { PublicKeys } from '@aztec/stdlib/keys'; import type { Wallet } from '../wallet/wallet.js'; import { ContractBase } from './contract_base.js'; -import { DeployMethod } from './deploy_method.js'; +import { type DeployInstantiationOptions, DeployMethod } from './deploy_method.js'; /** * The Contract class represents a contract and provides utility methods for interacting with it. @@ -28,35 +27,22 @@ export class Contract extends ContractBase { /** * Creates a tx to deploy (initialize and/or publish) a new instance of a contract. + * * @param wallet - The wallet for executing the deployment. * @param artifact - Build artifact of the contract to deploy * @param args - Arguments for the constructor. * @param constructorName - The name of the constructor function to call. + * @param instantiation - Other address-affecting parameters (salt, deployer / universalDeploy, publicKeys). */ - public static deploy(wallet: Wallet, artifact: ContractArtifact, args: any[], constructorName?: string) { - const postDeployCtor = (instance: ContractInstanceWithAddress, wallet: Wallet) => - Contract.at(instance.address, artifact, wallet); - return new DeployMethod(PublicKeys.default(), wallet, artifact, postDeployCtor, args, constructorName); - } - - /** - * Creates a tx to deploy (initialize and/or publish) a new instance of a contract - * using the specified public keys hash to derive the address. - * @param publicKeys - Hash of public keys to use for deriving the address. - * @param wallet - The wallet for executing the deployment. - * @param artifact - Build artifact of the contract. - * @param args - Arguments for the constructor. - * @param constructorName - The name of the constructor function to call. - */ - public static deployWithPublicKeys( - publicKeys: PublicKeys, + public static deploy( wallet: Wallet, artifact: ContractArtifact, args: any[], constructorName?: string, + instantiation?: DeployInstantiationOptions, ) { const postDeployCtor = (instance: ContractInstanceWithAddress, wallet: Wallet) => Contract.at(instance.address, artifact, wallet); - return new DeployMethod(publicKeys, wallet, artifact, postDeployCtor, args, constructorName); + return new DeployMethod(wallet, artifact, postDeployCtor, args, constructorName, instantiation); } } diff --git a/yarn-project/aztec.js/src/contract/deploy_method.test.ts b/yarn-project/aztec.js/src/contract/deploy_method.test.ts index 2f1115bda7a9..60b958ce2d0e 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.test.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.test.ts @@ -1,22 +1,21 @@ import { Fr } from '@aztec/foundation/curves/bn254'; -import { type ContractArtifact, FunctionType } from '@aztec/stdlib/abi'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; -import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract'; +import { type ContractInstanceWithAddress, getContractInstanceFromInstantiationParams } from '@aztec/stdlib/contract'; import { Gas } from '@aztec/stdlib/gas'; -import { PublicKeys } from '@aztec/stdlib/keys'; import { OFFCHAIN_MESSAGE_IDENTIFIER, type OffchainEffect } from '@aztec/stdlib/tx'; -import { DEV_VERSION } from '@aztec/stdlib/update-checker'; import { type MockProxy, mock } from 'jest-mock-extended'; +import { testContractArtifact } from '../test/fixtures.js'; import type { TxSimulationResultWithAppOffset } from '../wallet/tx_simulation_result_with_app_offset.js'; import type { Wallet } from '../wallet/wallet.js'; -import type { ContractBase } from './contract_base.js'; -import { DeployMethod } from './deploy_method.js'; +import { Contract } from './contract.js'; +import { NO_FROM } from './interaction_options.js'; describe('DeployMethod', () => { let wallet: MockProxy; +<<<<<<< HEAD const artifact: ContractArtifact = { name: 'TestContract', aztecVersion: DEV_VERSION, @@ -53,6 +52,8 @@ describe('DeployMethod', () => { storageLayout: {}, }; +======= +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) beforeEach(() => { wallet = mock(); wallet.registerContract.mockResolvedValue({} as ContractInstanceWithAddress); @@ -60,19 +61,8 @@ describe('DeployMethod', () => { wallet.getContractMetadata.mockResolvedValue({ isContractPubliclyDeployed: true } as any); }); - it('should extract offchain messages with anchor block timestamp on simulate', async () => { - const recipient = await AztecAddress.random(); - const contractAddress = await AztecAddress.random(); - const msgPayload = [Fr.random(), Fr.random()]; - const anchorBlockTimestamp = 42000n; - - const offchainEffects: OffchainEffect[] = [ - { - data: [OFFCHAIN_MESSAGE_IDENTIFIER, recipient.toField(), ...msgPayload], - contractAddress, - }, - ]; - + /** Builds a `TxSimulationResultWithAppOffset` mock that satisfies what `DeployMethod.simulate` reads. */ + const makeSimulateResult = (offchainEffects: OffchainEffect[] = [], anchorBlockTimestamp = 0n) => { const txSimResult = mock(); Object.defineProperty(txSimResult, 'offchainEffects', { value: offchainEffects }); Object.defineProperty(txSimResult, 'publicInputs', { @@ -84,18 +74,26 @@ describe('DeployMethod', () => { Object.defineProperty(txSimResult, 'gasUsed', { value: { totalGas: Gas.empty(), teardownGas: Gas.empty() }, }); + return txSimResult; + }; - wallet.simulateTx.mockResolvedValue(txSimResult); + it('should extract offchain messages with anchor block timestamp on simulate', async () => { + const recipient = await AztecAddress.random(); + const contractAddress = await AztecAddress.random(); + const msgPayload = [Fr.random(), Fr.random()]; + const anchorBlockTimestamp = 42000n; - const deployMethod = new DeployMethod( - PublicKeys.default(), - wallet, - artifact, - (instance, w) => ({ instance, wallet: w }) as unknown as ContractBase, - [], - ); + const offchainEffects: OffchainEffect[] = [ + { + data: [OFFCHAIN_MESSAGE_IDENTIFIER, recipient.toField(), ...msgPayload], + contractAddress, + }, + ]; + + wallet.simulateTx.mockResolvedValue(makeSimulateResult(offchainEffects, anchorBlockTimestamp)); - const result = await deployMethod.simulate({ from: await AztecAddress.random() }); + const deploy = Contract.deploy(wallet, testContractArtifact, []); + const result = await deploy.simulate({ from: await AztecAddress.random() }); expect(result.offchainMessages).toHaveLength(1); expect(result.offchainMessages[0]).toEqual({ @@ -106,4 +104,105 @@ describe('DeployMethod', () => { }); expect(result.offchainEffects).toEqual([]); }); + + describe('deployer locking and address stability', () => { + let alice: AztecAddress; + let bob: AztecAddress; + const salt = new Fr(0x1234n); + + beforeEach(async () => { + alice = await AztecAddress.random(); + bob = await AztecAddress.random(); + wallet.simulateTx.mockResolvedValue(makeSimulateResult()); + wallet.sendTx.mockResolvedValue({ + txHash: { hash: 'tx-hash' }, + offchainEffects: [], + receipt: { txHash: { hash: 'tx-hash' } }, + } as any); + }); + + /** + * Computes the expected address for our test artifact under the given deployer/salt, using + * the same protocol-level helper that `DeployMethod` calls internally. Tests assert against + * this value to confirm `DeployMethod` produces the canonical address. + */ + const expectedAddress = async (deployer: AztecAddress) => + ( + await getContractInstanceFromInstantiationParams(testContractArtifact, { + constructorArgs: [], + salt, + deployer, + publicKeys: undefined, + constructorArtifact: undefined, + }) + ).address; + + it('matches the standalone instantiation helper when locked at construction with deployer', async () => { + const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt, deployer: alice }); + const expected = await expectedAddress(alice); + expect(await deploy.getAddress()).toEqual(expected); + }); + + it('matches the standalone instantiation helper when locked at construction with universalDeploy', async () => { + const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt, universalDeploy: true }); + const expected = await expectedAddress(AztecAddress.ZERO); + expect(await deploy.getAddress()).toEqual(expected); + }); + + it('keeps the address stable across simulate then send when lazy-locking from `from`', async () => { + const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt }); + + const expected = await expectedAddress(alice); + + await deploy.simulate({ from: alice }); + const afterSimulate = await deploy.getAddress(); + + await deploy.send({ from: alice }); + const afterSend = await deploy.getAddress(); + + expect(afterSimulate).toEqual(afterSend); + expect(afterSimulate).toEqual(expected); + }); + + it('throws on getInstance / getAddress / getPartialAddress before any send-side call when nothing is locked', async () => { + const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt }); + // `getInstance` throws synchronously; `getAddress` / `getPartialAddress` are async and reject. + expect(() => deploy.getInstance()).toThrow(/deployer is not yet locked/); + await expect(deploy.getAddress()).rejects.toThrow(/deployer is not yet locked/); + await expect(deploy.getPartialAddress()).rejects.toThrow(/deployer is not yet locked/); + }); + + it('rejects mutually exclusive `deployer` and `universalDeploy` at construction', () => { + expect(() => + Contract.deploy(wallet, testContractArtifact, [], undefined, { salt, deployer: alice, universalDeploy: true }), + ).toThrow(/mutually exclusive/); + }); + + it('throws when send-time `from` would imply a different deployer than the one locked at construction', async () => { + const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt, deployer: alice }); + await expect(deploy.send({ from: bob })).rejects.toThrow(/Deployer for this DeployMethod is locked/); + }); + + it('allows any sender when locked to universal at construction, and the address is stable', async () => { + const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt, universalDeploy: true }); + const expected = await expectedAddress(AztecAddress.ZERO); + + await expect(deploy.send({ from: alice })).resolves.toBeDefined(); + expect(await deploy.getAddress()).toEqual(expected); + await expect(deploy.send({ from: bob })).resolves.toBeDefined(); + expect(await deploy.getAddress()).toEqual(expected); + }); + + it('throws on a second lock `from` after lazy-locking from the first', async () => { + const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt }); + await deploy.simulate({ from: alice }); + await expect(deploy.send({ from: bob })).rejects.toThrow(/Deployer for this DeployMethod is locked/); + }); + + it('locks to universal when `from` is NO_FROM', async () => { + const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt }); + await deploy.send({ from: NO_FROM }); + expect(await deploy.getAddress()).toEqual(await expectedAddress(AztecAddress.ZERO)); + }); + }); }); diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index 35d3317bf8a1..27ae05f8ce5e 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -8,7 +8,7 @@ import { getContractClassFromArtifact, getContractInstanceFromInstantiationParams, } from '@aztec/stdlib/contract'; -import type { PublicKeys } from '@aztec/stdlib/keys'; +import { PublicKeys } from '@aztec/stdlib/keys'; import { type Capsule, HashedValues, type TxProfileResult, type TxReceipt } from '@aztec/stdlib/tx'; import { ExecutionPayload, mergeExecutionPayloads } from '@aztec/stdlib/tx'; @@ -20,6 +20,7 @@ import type { ContractBase } from './contract_base.js'; import { ContractFunctionInteraction } from './contract_function_interaction.js'; import { getGasLimits } from './get_gas_limits.js'; import { + type InteractionWaitOptions, NO_FROM, NO_WAIT, type NoWait, @@ -39,6 +40,7 @@ import { import type { WaitOpts } from './wait_opts.js'; /** +<<<<<<< HEAD * Wait options specific to deployment transactions. * Extends WaitOpts with a flag to return the full receipt instead of just the contract. */ @@ -54,20 +56,44 @@ export type DeployWaitOptions = WaitOpts & { * - undefined: Wait with default options */ export type DeployInteractionWaitOptions = NoWait | DeployWaitOptions | undefined; +======= + * Inputs that determine the contract's deployment address. + * + * `salt` and `publicKeys` are optional and default to a random Fr and `PublicKeys.default()` respectively. + * + * `deployer` and `universalDeploy` are mutually exclusive and both optional: + * - If neither is supplied, the deployer is locked lazily on the first `send` / `simulate` / + * `profile` call from `options.from` (NO_FROM/undefined → universal). This preserves the + * ergonomics of `MyContract.deploy(wallet, ...args).send({ from: alice })`. + * - If `deployer` or `universalDeploy: true` is supplied, the deployer is locked at construction. + * + * Once locked, the deployer cannot change. Subsequent calls with a `from` that would imply a different + * deployer throw — except when locked to `AztecAddress.ZERO` (universal), which is compatible with any + * sender. + */ +export type DeployInstantiationOptions = { + /** Salt used to derive the contract address. Defaults to a random Fr. */ + salt?: Fr; + /** + * Deployer address mixed into the address preimage. Mutually exclusive with `universalDeploy`. + */ + deployer?: AztecAddress; + /** + * If true, the contract is deployed universally (deployer = AztecAddress.ZERO in the address preimage). + * Mutually exclusive with `deployer`. + */ + universalDeploy?: boolean; + /** Public keys mixed into the address. Defaults to PublicKeys.default(). */ + publicKeys?: PublicKeys; +}; +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) /** * Options for deploying a contract on the Aztec network. - * Allows specifying a contract address salt and different options to tweak contract publication - * and initialization + * Controls publication and registration policy for this deployment. Address-affecting parameters + * (salt, deployer, publicKeys, constructor and args) are passed at construction time. */ export type RequestDeployOptions = RequestInteractionOptions & { - /** An optional salt value used to deterministically calculate the contract address. */ - contractAddressSalt?: Fr; - /** - * Deployer address that will be used for the deployed contract's address computation. - * If set to 0, the sender's address won't be mixed in - */ - deployer?: AztecAddress; /** Skip contract class publication. */ skipClassPublication?: boolean; /** Skip publication, instead just privately initialize the contract. */ @@ -81,18 +107,13 @@ export type RequestDeployOptions = RequestInteractionOptions & { /** * Base deployment options without wait parameter. */ -export type DeployOptionsWithoutWait = Omit & { - /** - * Set to true to *not* include the sender in the address computation. This option - * is mutually exclusive with "deployer" - */ - universalDeploy?: boolean; -} & Pick; +export type DeployOptionsWithoutWait = RequestDeployOptions & + Pick; /** * Extends the deployment options with the required parameters to send the transaction. */ -export type DeployOptions = DeployOptionsWithoutWait & { +export type DeployOptions = DeployOptionsWithoutWait & { /** * Options for waiting for the transaction to be mined. * - undefined (default): wait with default options and return the contract instance @@ -149,7 +170,7 @@ export type DeployResultMined = { } & OffchainOutput; /** Conditional return type for deploy based on wait options. */ -export type DeployReturn = W extends NoWait +export type DeployReturn = W extends NoWait ? TxSendResultImmediate : W extends WaitWithReturnReceipt ? TxSendResultMined> @@ -159,6 +180,18 @@ export type DeployReturn extends BaseContractInteraction { - /** The contract instance to be deployed. */ - private instance?: ContractInstanceWithAddress = undefined; + /** Salt used in the address preimage. */ + protected readonly salt: Fr; + /** + * Deployer mixed into the address preimage. `undefined` until locked, either by `deployer` / + * `universalDeploy: true` at construction, or by the first call to `request` / `send` / + * `simulate` / `profile` which locks it from `options.from` (NO_FROM/undefined → ZERO, + * AztecAddress → that address). `AztecAddress.ZERO` indicates a universal deployment. Once + * locked, never changes; subsequent calls with an incompatible `from` throw. + */ + protected deployer: AztecAddress | undefined; + /** Public keys mixed into the address preimage. */ + protected readonly publicKeys: PublicKeys; + + /** Cached instance promise; resolved once after the deployer is locked. */ + private instancePromise?: Promise; + /** Resolved value of `instancePromise`, populated synchronously once the promise settles. */ + private resolvedInstance?: ContractInstanceWithAddress; /** Constructor function to call. */ protected constructorArtifact: FunctionAbi | undefined; constructor( - protected publicKeys: PublicKeys, wallet: Wallet, protected artifact: ContractArtifact, protected postDeployCtor: (instance: ContractInstanceWithAddress, wallet: Wallet) => TContract, protected args: any[] = [], constructorNameOrArtifact?: string | FunctionArtifact, + instantiation: DeployInstantiationOptions = {}, authWitnesses: AuthWitness[] = [], capsules: Capsule[] = [], protected extraHashedArgs: HashedValues[] = [], ) { super(wallet, authWitnesses, capsules); this.constructorArtifact = getInitializer(artifact, constructorNameOrArtifact); + this.salt = instantiation.salt ?? Fr.random(); + this.publicKeys = instantiation.publicKeys ?? PublicKeys.default(); + if (instantiation.deployer !== undefined && instantiation.universalDeploy) { + throw new Error('DeployInstantiationOptions: `deployer` and `universalDeploy` are mutually exclusive.'); + } + if (instantiation.universalDeploy) { + this.deployer = AztecAddress.ZERO; + } else if (instantiation.deployer !== undefined) { + this.deployer = instantiation.deployer; + } + } + + /** + * Locks the deployer from a send-time `from` value. If the deployer is already locked, this + * verifies that `from` is compatible with the locked value and throws otherwise. A locked + * universal deployer (`AztecAddress.ZERO`) is compatible with any `from`, since "universal" + * means the address does not depend on the sender. + * + * @param from - The send-time `from` value (AztecAddress, NO_FROM, or undefined). + */ + protected lockDeployerFromSendOptions(from: SendInteractionOptionsWithoutWait['from'] | undefined): void { + const fromAsDeployer: AztecAddress = from === undefined || from === NO_FROM ? AztecAddress.ZERO : from; + if (this.deployer === undefined) { + this.deployer = fromAsDeployer; + return; + } + if (this.deployer.equals(AztecAddress.ZERO)) { + return; + } + if (!this.deployer.equals(fromAsDeployer)) { + throw new Error( + `Deployer for this DeployMethod is locked to ${this.deployer.toString()}; cannot send from ${fromAsDeployer.toString()} ` + + `because that would imply a different deployer than the one used to derive the address. ` + + `Pass \`deployer: ${this.deployer.toString()}\` at construction if you need a different sender.`, + ); + } } /** * Returns the execution payload that allows this operation to happen on chain. + * + * Requires the deployer to be locked already (either at construction via `deployer` / + * `universalDeploy: true`, or as a side effect of a prior `send` / `simulate` / `profile` call, + * which lock from `options.from`). Throws otherwise — `request` is purely about payload + * construction and does not look at sender information. + * * @param options - Configuration options. * @returns The execution payload for this operation */ public async request(options: RequestDeployOptions = {}): Promise { + if (this.deployer === undefined) { + throw new Error( + 'Cannot build deploy execution payload: deployer is not yet locked. Pass `deployer:
` ' + + 'or `universalDeploy: true` as the instantiation option when constructing the deploy ' + + '(e.g. `MyContract.deploy(wallet, ...args, { deployer: alice })`), or call `.send` / ' + + '`.simulate` / `.profile` first to lock the deployer from the sender. When wrapping a ' + + 'DeployMethod inside a BatchCall, lock the deployer at construction since BatchCall ' + + 'invokes `request()` directly.', + ); + } const publication = await this.getPublicationExecutionPayload(options); if (!options?.skipRegistration) { - await this.wallet.registerContract(await this.getInstance(options), this.artifact); + await this.wallet.registerContract(await this.getInstance(), this.artifact); } const { authWitnesses, capsules } = options; @@ -222,23 +322,12 @@ export class DeployMethod extends return finalExecutionPayload; } - convertDeployOptionsToRequestOptions(options: DeployOptionsWithoutWait): RequestDeployOptions { - const { from } = options; - let deployer: AztecAddress | undefined; - if (options?.universalDeploy) { - deployer = undefined; - } else { - deployer = from === NO_FROM ? AztecAddress.ZERO : from; - } - return { ...options, deployer }; - } - /** * Converts DeployOptions to SendOptions, stripping out the returnReceipt flag if present. * @param options - Deploy options with wait parameter * @returns Send options with wait parameter */ - protected convertDeployOptionsToSendOptions( + protected convertDeployOptionsToSendOptions( options: DeployOptions, // eslint-disable-next-line jsdoc/require-jsdoc ): SendOptions { @@ -270,10 +359,9 @@ export class DeployMethod extends /** * Adds this contract to the wallet and returns the Contract object. - * @param options - Deployment options. */ - public async register(options?: RequestDeployOptions): Promise { - const instance = await this.getInstance(options); + public async register(): Promise { + const instance = await this.getInstance(); await this.wallet.registerContract(instance, this.artifact); return this.postDeployCtor(instance, this.wallet); } @@ -290,7 +378,7 @@ export class DeployMethod extends const calls: ExecutionPayload[] = []; // Set contract instance object so it's available for populating the DeploySendTx object - const instance = await this.getInstance(options); + const instance = await this.getInstance(); // Obtain contract class from artifact and check it matches the reported one by the instance. // TODO(@spalladino): We're unnecessarily calculating the contract class multiple times here. @@ -337,7 +425,7 @@ export class DeployMethod extends protected async getInitializationExecutionPayload(options?: RequestDeployOptions): Promise { const executionsPayloads: ExecutionPayload[] = []; if (this.constructorArtifact && !options?.skipInitialization) { - const { address } = await this.getInstance(options); + const { address } = await this.getInstance(); const constructorCall = new ContractFunctionInteraction( this.wallet, address, @@ -353,18 +441,24 @@ export class DeployMethod extends * Send a contract deployment transaction (initialize and/or publish) using the provided options. * By default, waits for the transaction to be mined and returns the deployed contract instance. * +<<<<<<< HEAD * @param options - An object containing various deployment options such as contractAddressSalt and from. * @returns TxHash (if wait is NO_WAIT), TContract (if wait is undefined or doesn't have returnReceipt), or DeployTxReceipt (if wait.returnReceipt is true) +======= + * @param options - An object containing various deployment options such as `from` and `fee`. + * @returns TxHash (if wait is NO_WAIT), or DeployResultMined with contract, receipt, and instance (otherwise) +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) */ // Overload for when wait is not specified at all - returns the contract public override send(options: DeployOptionsWithoutWait): Promise>; // eslint-disable-next-line jsdoc/require-jsdoc - public override send( + public override send( options: DeployOptions, ): Promise>; // eslint-disable-next-line jsdoc/require-jsdoc - public override async send(options: DeployOptions): Promise { - const executionPayload = await this.request(this.convertDeployOptionsToRequestOptions(options)); + public override async send(options: DeployOptions): Promise { + this.lockDeployerFromSendOptions(options.from); + const executionPayload = await this.request(options); const sendOptions = this.convertDeployOptionsToSendOptions(options); if (options.wait === NO_WAIT) { @@ -380,7 +474,7 @@ export class DeployMethod extends this.log.debug(`Deployed ${this.artifact.name} contract in tx ${receipt.txHash}`); // Attach contract instance - const instance = await this.getInstance(options); + const instance = await this.getInstance(); const contract = this.postDeployCtor(instance, this.wallet) as TContract; // Return full receipt if requested, otherwise just the contract @@ -392,22 +486,40 @@ export class DeployMethod extends } /** - * Builds the contract instance and returns it. + * Builds the contract instance and returns it. The instance is computed once and cached for + * the lifetime of this DeployMethod; subsequent calls return the same instance. + * + * Requires the deployer to have been locked. The deployer is locked either by passing + * `deployer` / `universalDeploy: true` at construction, or by a prior call to + * `request` / `send` / `simulate` / `profile` (which lock from `options.from`). Calling + * `getInstance()` before the deployer is locked throws, because the address is otherwise + * ambiguous and would silently change once the user finally invokes a send. * - * @param options - An object containing various initialization and publication options. * @returns An instance object. */ - public async getInstance(options?: RequestDeployOptions): Promise { - if (!this.instance) { - this.instance = await getContractInstanceFromInstantiationParams(this.artifact, { + public getInstance(): Promise { + if (this.deployer === undefined) { + throw new Error( + 'Cannot resolve contract instance: deployer is not yet locked. Pass `deployer:
` ' + + 'or `universalDeploy: true` as the instantiation option when constructing the deploy ' + + '(e.g. `MyContract.deploy(wallet, ...args, { deployer: alice })`), or call `.send` / ' + + '`.simulate` / `.profile` first to lock the deployer from the sender.', + ); + } + const deployer = this.deployer; + if (!this.instancePromise) { + this.instancePromise = getContractInstanceFromInstantiationParams(this.artifact, { constructorArgs: this.args, - salt: options?.contractAddressSalt ?? Fr.random(), + salt: this.salt, publicKeys: this.publicKeys, constructorArtifact: this.constructorArtifact, - deployer: options?.deployer ? options.deployer : AztecAddress.ZERO, + deployer, + }).then(instance => { + this.resolvedInstance = instance; + return instance; }); } - return this.instance; + return this.instancePromise; } /** @@ -418,7 +530,8 @@ export class DeployMethod extends * estimations (if requested via options), execution statistics and emitted offchain effects */ public async simulate(options: SimulateDeployOptions): Promise { - const executionPayload = await this.request(this.convertDeployOptionsToRequestOptions(options)); + this.lockDeployerFromSendOptions(options.from); + const executionPayload = await this.request(options); const simulatedTx = await this.wallet.simulateTx( executionPayload, this.convertDeployOptionsToSimulateOptions(options), @@ -446,18 +559,31 @@ export class DeployMethod extends * @returns An object containing the function return value and profile result. */ public async profile(options: DeployOptionsWithoutWait & ProfileInteractionOptions): Promise { - const executionPayload = await this.request(this.convertDeployOptionsToRequestOptions(options)); + this.lockDeployerFromSendOptions(options.from); + const executionPayload = await this.request(options); return await this.wallet.profileTx(executionPayload, this.convertDeployOptionsToProfileOptions(options)); } - /** Return this deployment address. */ - public get address() { - return this.instance?.address; + /** Returns the deployed contract address. */ + public async getAddress(): Promise { + return (await this.getInstance()).address; } /** Returns the partial address for this deployment. */ - public get partialAddress() { - return this.instance && computePartialAddress(this.instance); + public async getPartialAddress(): Promise { + return computePartialAddress(await this.getInstance()); + } + + /** + * Returns the cached resolved instance synchronously, or throws if no instance has been computed yet. + * Intended for subclasses that run inside a code path where `getInstance()` is guaranteed to have already + * been awaited (e.g. `request()` invoked it). Not part of the public API. + */ + protected getCachedInstanceOrThrow(): ContractInstanceWithAddress { + if (!this.resolvedInstance) { + throw new Error('Contract instance has not been computed yet. Call getInstance() first.'); + } + return this.resolvedInstance; } /** @@ -475,14 +601,30 @@ export class DeployMethod extends capsules?: Capsule[]; }): DeployMethod { return new DeployMethod( - this.publicKeys, this.wallet, this.artifact, this.postDeployCtor, this.args, this.constructorArtifact?.name, + this.cloneInstantiation(), this.authWitnesses.concat(authWitnesses), this.capsules.concat(capsules), ); } + + /** + * Returns the instantiation options to pass to a freshly-constructed copy of this DeployMethod + * (e.g. via `with(...)`). Encodes the current locked-deployer state: a locked AztecAddress.ZERO + * deployer becomes `universalDeploy: true`; an undefined deployer stays unset so the new copy can + * still infer it from the first send. + */ + protected cloneInstantiation(): DeployInstantiationOptions { + if (this.deployer === undefined) { + return { salt: this.salt, publicKeys: this.publicKeys }; + } + if (this.deployer.equals(AztecAddress.ZERO)) { + return { salt: this.salt, publicKeys: this.publicKeys, universalDeploy: true }; + } + return { salt: this.salt, publicKeys: this.publicKeys, deployer: this.deployer }; + } } diff --git a/yarn-project/aztec.js/src/deployment/contract_deployer.ts b/yarn-project/aztec.js/src/deployment/contract_deployer.ts index 5280fdd6e4e0..890b7723dd30 100644 --- a/yarn-project/aztec.js/src/deployment/contract_deployer.ts +++ b/yarn-project/aztec.js/src/deployment/contract_deployer.ts @@ -1,9 +1,8 @@ import type { ContractArtifact } from '@aztec/stdlib/abi'; import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract'; -import { PublicKeys } from '@aztec/stdlib/keys'; import { Contract } from '../contract/contract.js'; -import { DeployMethod } from '../contract/deploy_method.js'; +import { type DeployInstantiationOptions, DeployMethod } from '../contract/deploy_method.js'; import type { Wallet } from '../wallet/wallet.js'; /** @@ -14,29 +13,24 @@ export class ContractDeployer { constructor( private artifact: ContractArtifact, private wallet: Wallet, - private publicKeys?: PublicKeys, private constructorName?: string, ) {} /** - * Deploy a contract using the provided ABI and constructor arguments. - * This function creates a new DeployMethod instance that can be used to send deployment transactions - * and query deployment status. The method accepts any number of constructor arguments, which will - * be passed to the contract's constructor during deployment. + * Deploy a contract using the provided instantiation parameters and constructor arguments. + * Creates a new DeployMethod instance that can be used to send the deployment transaction. * + * The first argument is the {@link DeployInstantiationOptions} (salt, deployer) — pass `{}` to + * accept defaults (random salt, deployer = AztecAddress.ZERO). The remaining arguments are the + * constructor arguments for the contract. + * + * @param instantiation - Salt and deployer to mix into the address derivation. * @param args - The constructor arguments for the contract being deployed. * @returns A DeployMethod instance configured with the ABI, PXE, and constructor arguments. */ - public deploy(...args: any[]) { + public deploy(args?: any[], instantiation?: DeployInstantiationOptions) { const postDeployCtor = (instance: ContractInstanceWithAddress, wallet: Wallet) => Contract.at(instance.address, this.artifact, wallet); - return new DeployMethod( - this.publicKeys ?? PublicKeys.default(), - this.wallet, - this.artifact, - postDeployCtor, - args, - this.constructorName, - ); + return new DeployMethod(this.wallet, this.artifact, postDeployCtor, args, this.constructorName, instantiation); } } diff --git a/yarn-project/aztec.js/src/test/fixtures.ts b/yarn-project/aztec.js/src/test/fixtures.ts new file mode 100644 index 000000000000..f2f1881ecfb8 --- /dev/null +++ b/yarn-project/aztec.js/src/test/fixtures.ts @@ -0,0 +1,131 @@ +import { MEGA_VK_LENGTH_IN_FIELDS } from '@aztec/constants'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { type ContractArtifact, FunctionType } from '@aztec/stdlib/abi'; +import { DEV_VERSION } from '@aztec/stdlib/update-checker'; + +/** + * A minimal but representative `ContractArtifact` shared by unit tests in this package. Covers + * every function shape the tests exercise: a private initializer (`constructor`), the standard + * `public_dispatch` entry, a private function with mixed-visibility params (`bar`), a utility + * function (`qux`), and two functions exercising Noir `Option` parameters (`optionEcho`, + * `mixedParams`). + * + * We deliberately do not depend on `@aztec/noir-test-contracts.js` here: that package depends on + * `@aztec/aztec.js`, so importing from it would create a workspace cycle. + */ +export const testContractArtifact: ContractArtifact = { + name: 'TestContract', + aztecVersion: DEV_VERSION, + functions: [ + { + name: 'constructor', + isInitializer: true, + functionType: FunctionType.PRIVATE, + isOnlySelf: false, + isStatic: false, + debugSymbols: '', + parameters: [], + returnTypes: [], + errorTypes: {}, + bytecode: Buffer.alloc(8, 0xfa), + verificationKey: Buffer.alloc(MEGA_VK_LENGTH_IN_FIELDS * Fr.SIZE_IN_BYTES).toString('base64'), + }, + { + name: 'public_dispatch', + isInitializer: false, + isStatic: false, + functionType: FunctionType.PUBLIC, + isOnlySelf: false, + parameters: [{ name: 'selector', type: { kind: 'field' }, visibility: 'public' }], + returnTypes: [], + errorTypes: {}, + bytecode: Buffer.alloc(8, 0xfb), + debugSymbols: '', + }, + { + name: 'bar', + isInitializer: false, + functionType: FunctionType.PRIVATE, + isOnlySelf: false, + isStatic: false, + debugSymbols: '', + parameters: [ + { name: 'value', type: { kind: 'field' }, visibility: 'public' }, + { name: 'value', type: { kind: 'field' }, visibility: 'private' }, + ], + returnTypes: [], + errorTypes: {}, + bytecode: Buffer.alloc(8, 0xfa), + verificationKey: Buffer.alloc(MEGA_VK_LENGTH_IN_FIELDS * Fr.SIZE_IN_BYTES).toString('base64'), + }, + { + name: 'qux', + isInitializer: false, + isStatic: false, + functionType: FunctionType.UTILITY, + isOnlySelf: false, + parameters: [{ name: 'value', type: { kind: 'field' }, visibility: 'public' }], + returnTypes: [{ kind: 'integer', sign: 'unsigned', width: 32 }], + bytecode: Buffer.alloc(8, 0xfc), + debugSymbols: '', + errorTypes: {}, + }, + { + name: 'optionEcho', + isInitializer: false, + functionType: FunctionType.PRIVATE, + isOnlySelf: false, + isStatic: false, + parameters: [ + { + name: 'value', + type: { + kind: 'struct', + path: 'std::option::Option', + fields: [ + { name: '_is_some', type: { kind: 'boolean' } }, + { name: '_value', type: { kind: 'field' } }, + ], + }, + visibility: 'private', + }, + ], + returnTypes: [], + errorTypes: {}, + bytecode: Buffer.alloc(8, 0xfd), + verificationKey: Buffer.alloc(MEGA_VK_LENGTH_IN_FIELDS * Fr.SIZE_IN_BYTES).toString('base64'), + debugSymbols: '', + }, + { + name: 'mixedParams', + isInitializer: false, + functionType: FunctionType.PRIVATE, + isOnlySelf: false, + isStatic: false, + parameters: [ + { + name: 'optValue', + type: { + kind: 'struct', + path: 'std::option::Option', + fields: [ + { name: '_is_some', type: { kind: 'boolean' } }, + { name: '_value', type: { kind: 'field' } }, + ], + }, + visibility: 'private', + }, + { name: 'aField', type: { kind: 'field' }, visibility: 'private' }, + ], + returnTypes: [], + errorTypes: {}, + bytecode: Buffer.alloc(8, 0xfe), + verificationKey: Buffer.alloc(MEGA_VK_LENGTH_IN_FIELDS * Fr.SIZE_IN_BYTES).toString('base64'), + debugSymbols: '', + }, + ], + nonDispatchPublicFunctions: [], + outputs: { structs: {}, globals: {} }, + fileMap: {}, + storageLayout: {}, +}; diff --git a/yarn-project/aztec.js/src/wallet/deploy_account_method.ts b/yarn-project/aztec.js/src/wallet/deploy_account_method.ts index e4dc9349348a..25669633be9b 100644 --- a/yarn-project/aztec.js/src/wallet/deploy_account_method.ts +++ b/yarn-project/aztec.js/src/wallet/deploy_account_method.ts @@ -11,7 +11,6 @@ import type { Account } from '../account/account.js'; import type { Contract } from '../contract/contract.js'; import type { ContractBase } from '../contract/contract_base.js'; import { - type DeployInteractionWaitOptions, DeployMethod, type DeployOptions, type DeployOptionsWithoutWait, @@ -22,6 +21,7 @@ import { type FeePaymentMethodOption, type InteractionWaitOptions, NO_FROM, + type NoFrom, type ProfileInteractionOptions, type SendInteractionOptionsWithoutWait, } from '../contract/interaction_options.js'; @@ -39,27 +39,22 @@ export type DeployAccountFeePaymentMethodOption = FeePaymentMethodOption & { }; /** - * The configuration options for the request method. Omits the contractAddressSalt, since - * for account contracts that is fixed in the constructor + * The configuration options for the request method. */ -export type RequestDeployAccountOptions = Omit & { +export type RequestDeployAccountOptions = Omit & { /** Fee options specific to account deployment */ fee?: DeployAccountFeePaymentMethodOption; + /** + * Sender of the request. When NO_FROM, the to-be-deployed account pays for its own + * deployment (self-paid deploy) and the payload is wrapped through the multicall entrypoint. + */ + from?: AztecAddress | NoFrom; }; /** - * Base configuration options for the send/prove methods without wait parameter. Omits: - * - The contractAddressSalt, since for account contracts that is fixed in the constructor. - * - UniversalDeployment flag, since account contracts are always deployed with it set to true - */ -export type DeployAccountOptionsWithoutWait = Omit; - -/** - * The configuration options for the send/prove methods. Omits: - * - The contractAddressSalt, since for account contracts that is fixed in the constructor. - * - UniversalDeployment flag, since account contracts are always deployed with it set to true + * The configuration options for the send/prove methods. */ -export type DeployAccountOptions = DeployAccountOptionsWithoutWait & { +export type DeployAccountOptions = DeployOptionsWithoutWait & { /** * Whether to wait for the transaction to be mined. * - undefined (default): wait with default options and return TxReceipt @@ -70,10 +65,9 @@ export type DeployAccountOptions = }; /** - * The configuration options for the simulate method. Omits the contractAddressSalt, since - * for account contracts that is fixed in the constructor + * The configuration options for the simulate method. */ -export type SimulateDeployAccountOptions = Omit; +export type SimulateDeployAccountOptions = SimulateDeployOptions; /** Fields from any interaction option shape that `DeployAccountMethod.prepareDeployOptions` reads or sets. */ type DeployAccountInteractionOptions = Pick< @@ -91,7 +85,7 @@ export class DeployAccountMethod exte wallet: Wallet, artifact: ContractArtifact, postDeployCtor: (instance: ContractInstanceWithAddress, wallet: Wallet) => TContract, - private salt: Fr, + salt: Fr, private account: Account, args: any[] = [], constructorNameOrArtifact?: string | FunctionArtifact, @@ -100,12 +94,13 @@ export class DeployAccountMethod exte extraHashedArgs: HashedValues[] = [], ) { super( - publicKeys, wallet, artifact, postDeployCtor, args, constructorNameOrArtifact, + // Account contracts are always deployed universally. + { salt, universalDeploy: true, publicKeys }, authWitnesses, capsules, extraHashedArgs, @@ -124,9 +119,6 @@ export class DeployAccountMethod exte * @returns A FeePaymentMethod that routes the original one through the account's entrypoint (AccountEntrypointMetaPaymentMethod) */ private async getSelfFeePaymentMethod(originalPaymentMethod?: FeePaymentMethod, feeEntrypointOptions?: any) { - if (!this.address) { - throw new Error('Instance is not yet constructed. This is a bug!'); - } const chainInfo = await this.wallet.getChainInfo(); return new AccountEntrypointMetaPaymentMethod(this.account, chainInfo, originalPaymentMethod, feeEntrypointOptions); } @@ -141,10 +133,6 @@ export class DeployAccountMethod exte public override async request(opts?: RequestDeployAccountOptions): Promise { const optionsWithDefaults: RequestDeployOptions = { ...opts, - // Regardless of whom sends the transaction, account contracts - // are always deployed as universalDeployment: true - deployer: undefined, - contractAddressSalt: new Fr(this.salt), skipClassPublication: opts?.skipClassPublication ?? true, skipInstancePublication: opts?.skipInstancePublication ?? true, skipInitialization: opts?.skipInitialization ?? false, @@ -152,8 +140,9 @@ export class DeployAccountMethod exte // Override the fee to undefined, since we'll replace it const deploymentExecutionPayload = await super.request({ ...optionsWithDefaults, fee: undefined }); const executionPayloads = [deploymentExecutionPayload]; - // If this is a self-deployment, manage the fee accordingly - if (opts?.deployer?.equals(AztecAddress.ZERO)) { + // If this is a self-paid deployment (the to-be-deployed account pays for its own deploy), + // wrap the payload through the multicall entrypoint after attaching the fee. + if (opts?.from === NO_FROM) { const feePaymentMethod = await this.getSelfFeePaymentMethod( opts?.fee?.paymentMethod, opts?.fee?.feeEntrypointOptions, @@ -178,18 +167,7 @@ export class DeployAccountMethod exte } } - override convertDeployOptionsToRequestOptions(options: DeployAccountOptionsWithoutWait): RequestDeployAccountOptions { - return { - ...options, - // Deployer is handled in the request method and forcibly set to undefined, - // since our account contracts are created with universalDeployment: true - // We need to forward it though, because depending on the deployer we have to assemble - // The fee payment method one way or another - deployer: options.from === NO_FROM ? AztecAddress.ZERO : options.from, - }; - } - - protected override convertDeployOptionsToSendOptions( + protected override convertDeployOptionsToSendOptions( options: DeployOptions, // eslint-disable-next-line jsdoc/require-jsdoc ): SendOptions { @@ -213,15 +191,18 @@ export class DeployAccountMethod exte * - When `from === NO_FROM` (self-paid deploy), supplies the to-be-deployed address as `sendMessagesAs`. Without * this, fee-payment calls would have no sender for message tagging, and any private log they emit would fail * the "Sender for tags is not set" assertion. + * + * Note: this reads the cached instance synchronously via `getCachedInstance()`. Because every code path that + * calls `prepareDeployOptions` (send/simulate/profile) flows through `request()` first, which calls + * `getInstance()`, the cache is always populated by the time we get here. + * * @param options - The deploy options to augment. */ private prepareDeployOptions(options: T): T { - if (!this.address) { - throw new Error('Instance not yet constructed. This is a bug!'); - } + const { address } = this.getCachedInstanceOrThrow(); const existing = options.additionalScopes ?? []; - const sendMessagesAs = options.sendMessagesAs ?? (options.from === NO_FROM ? this.address : undefined); - return { ...options, additionalScopes: [...existing, this.address], sendMessagesAs }; + const sendMessagesAs = options.sendMessagesAs ?? (options.from === NO_FROM ? address : undefined); + return { ...options, additionalScopes: [...existing, address], sendMessagesAs }; } /** diff --git a/yarn-project/aztec/src/local-network/banana_fpc.ts b/yarn-project/aztec/src/local-network/banana_fpc.ts index e5363e0eda73..1c0c1f500b4a 100644 --- a/yarn-project/aztec/src/local-network/banana_fpc.ts +++ b/yarn-project/aztec/src/local-network/banana_fpc.ts @@ -49,15 +49,12 @@ export async function setupBananaFPC(initialAccounts: InitialAccountData[], wall const bananaCoinAddress = await getBananaCoinAddress(initialAccounts); const admin = getBananaAdmin(initialAccounts); const [{ contract: bananaCoin }, { contract: fpc }] = await Promise.all([ - TokenContract.deploy(wallet, admin, bananaCoinArgs.name, bananaCoinArgs.symbol, bananaCoinArgs.decimal).send({ - from: admin, - contractAddressSalt: BANANA_COIN_SALT, + TokenContract.deploy(wallet, admin, bananaCoinArgs.name, bananaCoinArgs.symbol, bananaCoinArgs.decimal, { + salt: BANANA_COIN_SALT, universalDeploy: true, - }), - FPCContract.deploy(wallet, bananaCoinAddress, admin).send({ + }).send({ from: admin }), + FPCContract.deploy(wallet, bananaCoinAddress, admin, { salt: BANANA_FPC_SALT, universalDeploy: true }).send({ from: admin, - contractAddressSalt: BANANA_FPC_SALT, - universalDeploy: true, }), ]); diff --git a/yarn-project/bot/src/factory.ts b/yarn-project/bot/src/factory.ts index e12d6534354f..a7d765011695 100644 --- a/yarn-project/bot/src/factory.ts +++ b/yarn-project/bot/src/factory.ts @@ -178,12 +178,8 @@ export class BotFactory { } private async setupTestContract(deployer: AztecAddress): Promise { - const deployOpts: DeployOptions = { - from: deployer, - contractAddressSalt: this.config.tokenSalt, - universalDeploy: true, - }; - const deploy = TestContract.deploy(this.wallet); + const deployOpts: DeployOptions = { from: deployer }; + const deploy = TestContract.deploy(this.wallet, { salt: this.config.tokenSalt, universalDeploy: true }); const instance = await this.registerOrDeployContract('TestContract', deploy, deployOpts); return TestContract.at(instance.address, this.wallet); } @@ -253,12 +249,74 @@ export class BotFactory { } /** +<<<<<<< HEAD +======= + * Setup token and refuel first: if the token already exists (restart scenario), + * run ensureFeeJuiceBalance before any step that might need fee juice. When deploying, + * use a bridge claim if balance is below threshold. + */ + private async setupTokenWithOptionalEarlyRefuel(sender: AztecAddress): Promise { + const token = await this.getTokenInstance(sender); + const address = token.address; + const metadata = await this.wallet.getContractMetadata(address); + if (metadata.isContractPublished) { + this.log.info(`Token at ${address.toString()} already deployed, refueling before setup`); + await this.ensureFeeJuiceBalance(sender, token); + } + return this.setupToken(sender); + } + + /** + * Setup token0 for AMM with refuel-first behaviour when token already exists. + */ + private async setupTokenContractWithOptionalEarlyRefuel( + deployer: AztecAddress, + salt: Fr, + name: string, + ticker: string, + decimals = 18, + ): Promise { + const deploy = TokenContract.deploy(this.wallet, deployer, name, ticker, decimals, { salt, universalDeploy: true }); + const instance = await deploy.getInstance(); + const metadata = await this.wallet.getContractMetadata(instance.address); + if (metadata.isContractPublished) { + this.log.info(`Token ${name} at ${instance.address.toString()} already deployed, refueling before setup`); + const token = TokenContract.at(instance.address, this.wallet); + await this.ensureFeeJuiceBalance(deployer, token); + } + return this.setupTokenContract(deployer, salt, name, ticker, decimals); + } + + private async getTokenInstance(sender: AztecAddress): Promise { + const salt = this.config.tokenSalt; + if (this.config.contract === SupportedTokenContracts.TokenContract) { + const deploy = TokenContract.deploy(this.wallet, sender, 'BotToken', 'BOT', 18, { salt, universalDeploy: true }); + const instance = await deploy.getInstance(); + return TokenContract.at(instance.address, this.wallet); + } + if (this.config.contract === SupportedTokenContracts.PrivateTokenContract) { + const tokenSecretKey = Fr.random(); + const tokenPublicKeys = (await deriveKeys(tokenSecretKey)).publicKeys; + const deploy = PrivateTokenContract.deploy(this.wallet, MINT_BALANCE, sender, { + salt, + universalDeploy: true, + publicKeys: tokenPublicKeys, + }); + const instance = await deploy.getInstance(); + return PrivateTokenContract.at(instance.address, this.wallet); + } + throw new Error(`Unsupported token contract type: ${this.config.contract}`); + } + + /** +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) * Checks if the token contract is deployed and deploys it if necessary. * @param wallet - Wallet to deploy the token contract from. * @returns The TokenContract instance. */ private async setupToken(sender: AztecAddress): Promise { let deploy: DeployMethod; +<<<<<<< HEAD let tokenInstance: ContractInstanceWithAddress | undefined; const deployOpts: DeployOptions = { from: sender, @@ -270,17 +328,34 @@ export class BotFactory { deploy = TokenContract.deploy(this.wallet, sender, 'BotToken', 'BOT', 18); tokenInstance = await deploy.getInstance(deployOpts); token = TokenContract.at(tokenInstance.address, this.wallet); +======= + const salt = this.config.tokenSalt; + const deployOpts: DeployOptions = { from: sender }; + let token: TokenContract | PrivateTokenContract; + if (this.config.contract === SupportedTokenContracts.TokenContract) { + deploy = TokenContract.deploy(this.wallet, sender, 'BotToken', 'BOT', 18, { salt, universalDeploy: true }); + const instance = await deploy.getInstance(); + token = TokenContract.at(instance.address, this.wallet); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) } else if (this.config.contract === SupportedTokenContracts.PrivateTokenContract) { // Generate keys for the contract since PrivateToken uses SinglePrivateMutable which requires keys const tokenSecretKey = Fr.random(); const tokenPublicKeys = (await deriveKeys(tokenSecretKey)).publicKeys; - deploy = PrivateTokenContract.deployWithPublicKeys(tokenPublicKeys, this.wallet, MINT_BALANCE, sender); + deploy = PrivateTokenContract.deploy(this.wallet, MINT_BALANCE, sender, { + salt, + universalDeploy: true, + publicKeys: tokenPublicKeys, + }); deployOpts.skipInstancePublication = true; deployOpts.skipClassPublication = true; deployOpts.skipInitialization = false; // Register the contract with the secret key before deployment +<<<<<<< HEAD tokenInstance = await deploy.getInstance(deployOpts); +======= + const tokenInstance = await deploy.getInstance(); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) token = PrivateTokenContract.at(tokenInstance.address, this.wallet); await this.wallet.registerContract(tokenInstance, PrivateTokenContract.artifact, tokenSecretKey); // The contract constructor initializes private storage vars that need the contract's own nullifier key. @@ -313,26 +388,29 @@ export class BotFactory { */ private async setupTokenContract( deployer: AztecAddress, - contractAddressSalt: Fr, + salt: Fr, name: string, ticker: string, decimals = 18, ): Promise { - const deployOpts: DeployOptions = { from: deployer, contractAddressSalt, universalDeploy: true }; - const deploy = TokenContract.deploy(this.wallet, deployer, name, ticker, decimals); + const deployOpts: DeployOptions = { from: deployer }; + const deploy = TokenContract.deploy(this.wallet, deployer, name, ticker, decimals, { salt, universalDeploy: true }); const instance = await this.registerOrDeployContract('Token - ' + name, deploy, deployOpts); return TokenContract.at(instance.address, this.wallet); } private async setupAmmContract( deployer: AztecAddress, - contractAddressSalt: Fr, + salt: Fr, token0: TokenContract, token1: TokenContract, lpToken: TokenContract, ): Promise { - const deployOpts: DeployOptions = { from: deployer, contractAddressSalt, universalDeploy: true }; - const deploy = AMMContract.deploy(this.wallet, token0.address, token1.address, lpToken.address); + const deployOpts: DeployOptions = { from: deployer }; + const deploy = AMMContract.deploy(this.wallet, token0.address, token1.address, lpToken.address, { + salt, + universalDeploy: true, + }); const instance = await this.registerOrDeployContract('AMM', deploy, deployOpts); const amm = AMMContract.at(instance.address, this.wallet); @@ -437,7 +515,7 @@ export class BotFactory { deploy: DeployMethod, deployOpts: DeployOptions, ): Promise { - const instance = await deploy.getInstance(deployOpts); + const instance = await deploy.getInstance(); const address = instance.address; const metadata = await this.wallet.getContractMetadata(address); if (metadata.isContractPublished) { diff --git a/yarn-project/builder/src/contract-interface-gen/typescript.ts b/yarn-project/builder/src/contract-interface-gen/typescript.ts index a8a427ab0d44..e3e47bc56b84 100644 --- a/yarn-project/builder/src/contract-interface-gen/typescript.ts +++ b/yarn-project/builder/src/contract-interface-gen/typescript.ts @@ -93,39 +93,37 @@ function generateMethod(entry: FunctionAbi) { */ function generateDeploy(input: ContractArtifact) { const ctor = getDefaultInitializer(input); - const args = (ctor?.parameters ?? []).map(generateParameter).join(', '); + const ctorParams = ctor?.parameters ?? []; + const args = ctorParams.map(generateParameter).join(', '); + const argNames = ctorParams.map(p => p.name).join(', '); + const argsForwarding = argNames ? `[${argNames}]` : '[]'; const contractName = `${input.name}Contract`; const artifactName = `${contractName}Artifact`; return ` /** * Creates a tx to deploy a new instance of this contract. + * @param instantiation - Optional address-affecting parameters (salt, deployer / universalDeploy, publicKeys). + * Salt defaults to a random value; the deployer is locked lazily from the first send-time \`from\`. */ - public static deploy(wallet: Wallet, ${args}) { - return new DeployMethod<${contractName}>(PublicKeys.default(), wallet, ${artifactName}, (instance, wallet) => ${contractName}.at(instance.address, wallet), Array.from(arguments).slice(1)); - } - - /** - * Creates a tx to deploy a new instance of this contract using the specified public keys hash to derive the address. - */ - public static deployWithPublicKeys(publicKeys: PublicKeys, wallet: Wallet, ${args}) { - return new DeployMethod<${contractName}>(publicKeys, wallet, ${artifactName}, (instance, wallet) => ${contractName}.at(instance.address, wallet), Array.from(arguments).slice(2)); + public static deploy(wallet: Wallet, ${args ? `${args}, ` : ''}instantiation?: DeployInstantiationOptions) { + return new DeployMethod<${contractName}>(wallet, ${artifactName}, (instance, wallet) => ${contractName}.at(instance.address, wallet), ${argsForwarding}, undefined, instantiation); } /** * Creates a tx to deploy a new instance of this contract using the specified constructor method. */ public static deployWithOpts( - opts: { publicKeys?: PublicKeys; method?: M; wallet: Wallet }, + opts: { method?: M; wallet: Wallet; instantiation?: DeployInstantiationOptions }, ...args: Parameters<${contractName}['methods'][M]> ) { return new DeployMethod<${contractName}>( - opts.publicKeys ?? PublicKeys.default(), opts.wallet, ${artifactName}, (instance, wallet) => ${contractName}.at(instance.address, wallet), - Array.from(arguments).slice(1), + args, opts.method ?? 'constructor', + opts.instantiation, ); } `; @@ -310,7 +308,7 @@ export async function generateTypescriptContractInterface(input: ContractArtifac /* eslint-disable */ import { AztecAddress, CompleteAddress } from '@aztec/aztec.js/addresses'; import { type AbiType, type AztecAddressLike, type ContractArtifact, EventSelector, decodeFromAbi, type EthAddressLike, type FieldLike, type FunctionSelectorLike, loadContractArtifact, loadContractArtifactForPublic, type NoirCompiledContract, type OptionLike, type U128Like, type WrappedFieldLike } from '@aztec/aztec.js/abi'; -import { Contract, ContractBase, ContractFunctionInteraction, type ContractMethod, type ContractStorageLayout, DeployMethod } from '@aztec/aztec.js/contracts'; +import { Contract, ContractBase, ContractFunctionInteraction, type ContractMethod, type ContractStorageLayout, type DeployInstantiationOptions, DeployMethod } from '@aztec/aztec.js/contracts'; import { EthAddress } from '@aztec/aztec.js/addresses'; import { Fr, Point } from '@aztec/aztec.js/fields'; import { type PublicKey, PublicKeys } from '@aztec/aztec.js/keys'; diff --git a/yarn-project/cli-wallet/src/cmds/deploy.ts b/yarn-project/cli-wallet/src/cmds/deploy.ts index d7f23de2b16d..67bce11bb1e5 100644 --- a/yarn-project/cli-wallet/src/cmds/deploy.ts +++ b/yarn-project/cli-wallet/src/cmds/deploy.ts @@ -45,12 +45,7 @@ export async function deploy( // TODO(#12081): Add contractArtifact.noirVersion and check here (via Noir.lock)? - const contractDeployer = new ContractDeployer( - contractArtifact, - wallet, - publicKeys ?? PublicKeys.default(), - initializer, - ); + const contractDeployer = new ContractDeployer(contractArtifact, wallet, initializer); let args = []; if (rawArgs.length > 0) { @@ -62,13 +57,11 @@ export async function deploy( debugLogger.debug(`Encoded arguments: ${args.join(', ')}`); } - const deployInteraction = contractDeployer.deploy(...args); + const deployInteraction = contractDeployer.deploy(args, { salt, publicKeys: publicKeys ?? PublicKeys.default() }); const { paymentMethod, gasSettings } = await feeOpts.toUserFeeOptions(node, wallet, deployer); const deployOpts: DeployOptions = { fee: { gasSettings, paymentMethod }, from: deployer ?? NO_FROM, - contractAddressSalt: salt, - universalDeploy: !deployer, skipClassPublication, skipInitialization, skipInstancePublication, @@ -101,8 +94,9 @@ export async function deploy( printProfileResult(stats, log); } - const { address, partialAddress } = deployInteraction; const instance = await deployInteraction.getInstance(); + const address = instance.address; + const partialAddress = await deployInteraction.getPartialAddress(); const { txHash } = await deployInteraction.send({ ...deployOpts, wait: NO_WAIT }); const localTimeMs = performance.now() - localStart; @@ -115,8 +109,8 @@ export async function deploy( const nodeTimeMs = performance.now() - nodeStart; if (!json) { - log(`Contract deployed at ${address?.toString()}`); - log(`Contract partial address ${(await partialAddress)?.toString()}`); + log(`Contract deployed at ${address.toString()}`); + log(`Contract partial address ${partialAddress.toString()}`); log(`Contract init hash ${instance.initializationHash.toString()}`); log(`Deployment tx hash: ${txHash.toString()}`); log(`Deployment salt: ${salt.toString()}`); @@ -126,8 +120,8 @@ export async function deploy( log(` Node inclusion time: ${(nodeTimeMs / 1000).toFixed(1)}s`); } else { out.contract = { - address: address?.toString(), - partialAddress: (await partialAddress)?.toString(), + address: address.toString(), + partialAddress: partialAddress.toString(), initializationHash: instance.initializationHash.toString(), salt: salt.toString(), transactionFee: receipt.transactionFee?.toString(), @@ -135,16 +129,16 @@ export async function deploy( } } else { if (!json) { - log(`Contract deployed at ${address?.toString()}`); - log(`Contract partial address ${(await partialAddress)?.toString()}`); + log(`Contract deployed at ${address.toString()}`); + log(`Contract partial address ${partialAddress.toString()}`); log(`Contract init hash ${instance.initializationHash.toString()}`); log(`Deployment tx hash: ${txHash.toString()}`); log(`Deployment salt: ${salt.toString()}`); log(`Deployer: ${instance.deployer.toString()}`); } else { out.contract = { - address: address?.toString(), - partialAddress: (await partialAddress)?.toString(), + address: address.toString(), + partialAddress: partialAddress.toString(), initializationHash: instance.initializationHash.toString(), salt: salt.toString(), }; @@ -154,5 +148,5 @@ export async function deploy( if (json) { log(prettyPrintJSON(out)); } - return deployInteraction.address; + return await deployInteraction.getAddress(); } diff --git a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts index d3e55a0a597b..e4a126fb775c 100644 --- a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts +++ b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts @@ -278,10 +278,13 @@ describe('HA Full Setup', () => { // Deploy a contract to trigger block building const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); logger.info(`Deploying contract from ${ownerAddress}`); - const { receipt } = await deployer.deploy(ownerAddress, 1).send({ + const { receipt } = await deployer.deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }).send({ from: ownerAddress, +<<<<<<< HEAD contractAddressSalt: new Fr(BigInt(1)), wait: { returnReceipt: true }, +======= +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }); await waitForProven(aztecNode, receipt, { @@ -397,10 +400,13 @@ describe('HA Full Setup', () => { // Send a transaction to trigger block building which will also trigger voting logger.info('Sending transaction to trigger block building...'); const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); - const { receipt } = await deployer.deploy(ownerAddress, 42).send({ + const { receipt } = await deployer.deploy([ownerAddress, 42], { salt: Fr.random() }).send({ from: ownerAddress, +<<<<<<< HEAD contractAddressSalt: Fr.random(), wait: { returnReceipt: true }, +======= +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }); expect(receipt.blockNumber).toBeDefined(); logger.info(`Transaction mined in block ${receipt.blockNumber}`); @@ -490,6 +496,83 @@ describe('HA Full Setup', () => { logger.info('Governance voting with HA coordination and L1 verification complete'); }); +<<<<<<< HEAD +======= + it('should reload keystore via admin API and keep building blocks after swapping attesters', async () => { + logger.info('Testing reloadKeystore: swap all attesters across HA nodes'); + + const groupA = attesterAddresses.slice(0, 2); + const groupB = attesterAddresses.slice(2, 4); + + const writeKeystoreForNode = async (nodeIdx: number, attesters: string[]) => { + const ks = { + schemaVersion: 1, + validators: [ + { + attester: attesters, + feeRecipient: AztecAddress.ZERO.toString(), + coinbase: EthAddress.fromString(attesters[0]).toChecksumString(), + remoteSigner: web3SignerUrl, + publisher: [publisherAddresses[nodeIdx]], + }, + ], + }; + await writeFile(join(haKeystoreDirs[nodeIdx], 'keystore.json'), JSON.stringify(ks, null, 2)); + }; + + const verifyNodeAttesters = (nodeIdx: number, expectedAttesters: string[], label: string) => { + const vc: ValidatorClient = (haNodeServices[nodeIdx] as any).validatorClient; + const addrs = vc.getValidatorAddresses(); + expect(addrs).toHaveLength(expectedAttesters.length); + for (const expected of expectedAttesters) { + expect(addrs.some(a => a.equals(EthAddress.fromString(expected)))).toBe(true); + } + logger.info(`Node ${nodeIdx}: ${addrs.length} attesters (${label})`); + }; + + const quorum = Math.floor((COMMITTEE_SIZE * 2) / 3) + 1; + + try { + // Phase 1: Nodes 0,1,2 get attesters [A0,A1], nodes 3,4 get [A2,A3] + logger.info('Phase 1: Initial attester split'); + for (let i = 0; i < NODE_COUNT; i++) { + await writeKeystoreForNode(i, i < 3 ? groupA : groupB); + await haNodeServices[i].reloadKeystore(); + } + for (let i = 0; i < NODE_COUNT; i++) { + verifyNodeAttesters(i, i < 3 ? groupA : groupB, i < 3 ? 'group A' : 'group B'); + } + + // Phase 2: Swap — nodes 0,1,2 get [A2,A3], nodes 3,4 get [A0,A1] + logger.info('Phase 2: Swapping all attesters'); + for (let i = 0; i < NODE_COUNT; i++) { + await writeKeystoreForNode(i, i < 3 ? groupB : groupA); + await haNodeServices[i].reloadKeystore(); + } + for (let i = 0; i < NODE_COUNT; i++) { + verifyNodeAttesters(i, i < 3 ? groupB : groupA, i < 3 ? 'group B (swapped)' : 'group A (swapped)'); + } + + const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); + const receipt = await deployer.deploy([ownerAddress, 201], { salt: new Fr(201) }).send({ + from: ownerAddress, + }); + expect(receipt.receipt.blockNumber).toBeDefined(); + const [block] = await aztecNode.getCheckpointedBlocks(receipt.receipt.blockNumber!, 1); + const [cp] = await aztecNode.getCheckpoints(block!.checkpointNumber, 1, { includeAttestations: true }); + const att = (cp.attestations ?? []).filter(a => !a.signature.isEmpty()); + expect(att.length).toBeGreaterThanOrEqual(quorum); + logger.info(`Phase 2: block ${receipt.receipt.blockNumber}, ${att.length} attestations (quorum ${quorum})`); + } finally { + // Restore each node's saved initial keystore so subsequent tests see original state + for (let i = 0; i < NODE_COUNT; i++) { + await writeFile(join(haKeystoreDirs[i], 'keystore.json'), initialKeystoreJsons[i]); + await haNodeServices[i].reloadKeystore(); + } + } + }); + +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) // NOTE: this test needs to run last it('should distribute work across multiple HA nodes', async () => { logger.info('Testing HA resilience by killing nodes after they produce blocks'); @@ -513,10 +596,13 @@ describe('HA Full Setup', () => { logger.info(`Active nodes: ${haNodeServices.length - killedNodes.length}/${NODE_COUNT}`); const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); - const { receipt } = await deployer.deploy(ownerAddress, i + 100).send({ + const { receipt } = await deployer.deploy([ownerAddress, i + 100], { salt: new Fr(BigInt(i + 100)) }).send({ from: ownerAddress, +<<<<<<< HEAD contractAddressSalt: new Fr(BigInt(i + 100)), wait: { returnReceipt: true }, +======= +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }); expect(receipt.blockNumber).toBeDefined(); diff --git a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts index 1d2b1fceebc6..aeee26cabba3 100644 --- a/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts +++ b/yarn-project/end-to-end/src/composed/web3signer/e2e_multi_validator_node_key_store.test.ts @@ -324,11 +324,10 @@ describe('e2e_multi_validator_node', () => { await rmdir(keyStoreDirectory, { recursive: true }); }); - const sendTx = (contractAddressSalt: Fr) => { + const sendTx = (salt: Fr) => { const deployer = new ContractDeployer(artifact, wallet); - return deployer.deploy(ownerAddress, 1).send({ + return deployer.deploy([ownerAddress, 1], { salt }).send({ from: ownerAddress, - contractAddressSalt, skipClassPublication: true, wait: NO_WAIT, }); diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index f5edd5eeaadc..275c348797da 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -133,15 +133,17 @@ describe('e2e_block_building', () => { // Need to have value > 0, so adding + 1 // We need to do so, because noir currently will fail if the multiscalarmul is in an `if` // that we DO NOT enter. This should be fixed by https://github.com/noir-lang/noir/issues/5045. - const methods = times(TX_COUNT, i => StatefulTestContract.deploy(wallet, ownerAddress, i + 1)); + const methods = times(TX_COUNT, i => + StatefulTestContract.deploy(wallet, ownerAddress, i + 1, { + salt: new Fr(BigInt(i + 1)), + deployer: ownerAddress, + }), + ); const provenTxs = []; const addresses = []; for (let i = 0; i < TX_COUNT; i++) { - const options: DeployOptions = { - from: ownerAddress, - contractAddressSalt: new Fr(BigInt(i + 1)), - }; - const instance = await methods[i].getInstance(options); + const options: DeployOptions = { from: ownerAddress }; + const instance = await methods[i].getInstance(); addresses.push(instance.address); provenTxs.push(await proveInteraction(wallet, methods[i], options)); } @@ -232,7 +234,9 @@ describe('e2e_block_building', () => { // Deploy a contract in the first transaction // In the same block, call a public method on the contract - const deployMethod = TokenContract.deploy(wallet, ownerAddress, 'TokenName', 'TokenSymbol', 18); + const deployMethod = TokenContract.deploy(wallet, ownerAddress, 'TokenName', 'TokenSymbol', 18, { + deployer: ownerAddress, + }); // We can't use `TokenContract.at` to call a function because it checks the contract is deployed // but we are in the same block as the deployment transaction diff --git a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts index 3eb4e12a92af..ce21efa245d6 100644 --- a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts +++ b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts @@ -101,12 +101,17 @@ describe('e2e_contract_updates', () => { initialFundedAccounts, })); +<<<<<<< HEAD ({ receipt: { contract, instance }, } = await UpdatableContract.deploy(wallet, constructorArgs[0]).send({ from: defaultAccountAddress, contractAddressSalt: salt, wait: { returnReceipt: true }, +======= + ({ contract, instance } = await UpdatableContract.deploy(wallet, constructorArgs[0], { salt }).send({ + from: defaultAccountAddress, +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) })); const registerMethod = await publishContractClass(wallet, UpdatedContractArtifact); diff --git a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts index 5668ba4e3e77..1fd23d78063f 100644 --- a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts +++ b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts @@ -85,12 +85,12 @@ describe('e2e_crowdfunding_and_claim', () => { crowdfundingSecretKey = Fr.random(); crowdfundingPublicKeys = (await deriveKeys(crowdfundingSecretKey)).publicKeys; - const crowdfundingDeployment = CrowdfundingContract.deployWithPublicKeys( - crowdfundingPublicKeys, + const crowdfundingDeployment = CrowdfundingContract.deploy( wallet, donationToken.address, operatorAddress, deadline, + { publicKeys: crowdfundingPublicKeys, deployer: operatorAddress }, ); const crowdfundingInstance = await crowdfundingDeployment.getInstance(); await wallet.registerContract(crowdfundingInstance, CrowdfundingContract.artifact, crowdfundingSecretKey); @@ -226,12 +226,12 @@ describe('e2e_crowdfunding_and_claim', () => { // 1) Deploy another instance of the crowdfunding contract let otherCrowdfundingContract: CrowdfundingContract; { - const otherCrowdfundingDeployment = CrowdfundingContract.deployWithPublicKeys( - crowdfundingPublicKeys, + const otherCrowdfundingDeployment = CrowdfundingContract.deploy( wallet, donationToken.address, operatorAddress, deadline, + { publicKeys: crowdfundingPublicKeys, deployer: operatorAddress }, ); const otherCrowdfundingInstance = await otherCrowdfundingDeployment.getInstance(); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts index 181302b58961..4bdf1e9fc248 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts @@ -119,7 +119,11 @@ describe('e2e_deploy_contract deploy method', () => { // because the public initializer hasn't emitted the private initialization nullifier yet. it('refuses to call a private init-checked function in same tx as public initialization', async () => { const owner = defaultAccountAddress; - const deployMethod = StatefulTestContract.deployWithOpts({ wallet, method: 'public_constructor' }, owner, 42); + const deployMethod = StatefulTestContract.deployWithOpts( + { wallet, method: 'public_constructor', instantiation: { deployer: defaultAccountAddress } }, + owner, + 42, + ); const contract = await deployMethod.register(); const batch = new BatchCall(wallet, [deployMethod, contract.methods.create_note(owner, 10)]); await expect(batch.send({ from: defaultAccountAddress })).rejects.toThrow(/Cannot find the leaf for nullifier/); @@ -161,7 +165,7 @@ describe('e2e_deploy_contract deploy method', () => { const owner = defaultAccountAddress; // docs:start:deploy_batch // Create a contract instance and make the PXE aware of it - const deployMethod = StatefulTestContract.deploy(wallet, owner, 42); + const deployMethod = StatefulTestContract.deploy(wallet, owner, 42, { deployer: defaultAccountAddress }); const contract = await deployMethod.register(); // Batch deployment and a public call into the same transaction @@ -172,40 +176,42 @@ describe('e2e_deploy_contract deploy method', () => { it('publicly deploys a contract in one tx and calls a public function on it later in the same block', async () => { await t.aztecNodeAdmin.setConfig({ minTxsPerBlock: 2 }); - - const owner = defaultAccountAddress; - logger.debug('Initializing deploy method'); - const deployMethod = StatefulTestContract.deploy(wallet, owner, 42); - logger.debug('Creating request/calls to register and deploy contract'); - const deployTx = new BatchCall(wallet, [deployMethod]); - logger.debug('Registering the not-yet-deployed contract to batch calls to'); - const contract = await deployMethod.register(); - - logger.debug('Creating public call to run in same block as deployment'); - const publicCall = contract.methods.increment_public_value(owner, 84); - - // First send the deploy transaction - // Pay priority fee to ensure the deployment transaction gets processed first. - // Use L2 gas priority (not DA) because DA gas fees can be zero, and priority fees - // are capped by maxFeesPerGas, so a DA priority of 1 gets capped to min(0, 1) = 0. - const maxPriorityFeesPerGas = new GasFees(0n, 1n); - const deployTxPromise = deployTx.send({ - from: defaultAccountAddress, - fee: { gasSettings: { maxPriorityFeesPerGas } }, - wait: { timeout: 600 }, - }); - - // Then send the public call transaction - const publicCallTxPromise = publicCall.send({ from: defaultAccountAddress, wait: { timeout: 600 } }); - - logger.debug('Deploying a contract and calling a public function in the same block'); - const [{ receipt: deployTxReceipt }, { receipt: publicCallTxReceipt }] = await Promise.all([ - deployTxPromise, - publicCallTxPromise, - ]); - expect(deployTxReceipt.blockNumber).toEqual(publicCallTxReceipt.blockNumber); - - await t.aztecNodeAdmin.setConfig({ minTxsPerBlock: 1 }); + try { + const owner = defaultAccountAddress; + logger.debug('Initializing deploy method'); + const deployMethod = StatefulTestContract.deploy(wallet, owner, 42, { deployer: defaultAccountAddress }); + logger.debug('Creating request/calls to register and deploy contract'); + const deployTx = new BatchCall(wallet, [deployMethod]); + logger.debug('Registering the not-yet-deployed contract to batch calls to'); + const contract = await deployMethod.register(); + + logger.debug('Creating public call to run in same block as deployment'); + const publicCall = contract.methods.increment_public_value(owner, 84); + + // First send the deploy transaction + // Pay priority fee to ensure the deployment transaction gets processed first. + // Use L2 gas priority (not DA) because DA gas fees can be zero, and priority fees + // are capped by maxFeesPerGas, so a DA priority of 1 gets capped to min(0, 1) = 0. + const maxPriorityFeesPerGas = new GasFees(0n, 1n); + const deployTxPromise = deployTx.send({ + from: defaultAccountAddress, + fee: { gasSettings: { maxPriorityFeesPerGas } }, + wait: { timeout: 600 }, + }); + + // Then send the public call transaction + const publicCallTxPromise = publicCall.send({ from: defaultAccountAddress, wait: { timeout: 600 } }); + + logger.debug('Deploying a contract and calling a public function in the same block'); + const [{ receipt: deployTxReceipt }, { receipt: publicCallTxReceipt }] = await Promise.all([ + deployTxPromise, + publicCallTxPromise, + ]); + expect(deployTxReceipt.blockNumber).toEqual(publicCallTxReceipt.blockNumber); + } finally { + // Restore minTxsPerBlock so subsequent tests aren't blocked waiting for a second tx. + await t.aztecNodeAdmin.setConfig({ minTxsPerBlock: 1 }); + } }, 300_000); it('reports YES for initialization status via public nullifier when instance is not registered', async () => { diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts index ae2c526cdbce..95b0ae287b21 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts @@ -35,11 +35,19 @@ describe('e2e_deploy_contract legacy', () => { salt, deployer: defaultAccountAddress, }); +<<<<<<< HEAD const deployer = new ContractDeployer(TestContractArtifact, wallet); const { receipt } = await deployer .deploy() .send({ from: defaultAccountAddress, contractAddressSalt: salt, wait: { returnReceipt: true } }); expect(receipt.contract.address).toEqual(deploymentData.address); +======= + const contractDeployer = new ContractDeployer(TestContractArtifact, wallet); + const { contract } = await contractDeployer + .deploy([], { salt, deployer: defaultAccountAddress }) + .send({ from: defaultAccountAddress }); + expect(contract.address).toEqual(deploymentData.address); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) const { instance, isContractPublished } = await wallet.getContractMetadata(deploymentData.address); expect(instance).toBeDefined(); expect(isContractPublished).toBe(true); @@ -49,11 +57,11 @@ describe('e2e_deploy_contract legacy', () => { * Verify that we can produce multiple rollups. */ it('should deploy one contract after another in consecutive rollups', async () => { - const deployer = new ContractDeployer(TestContractArtifact, wallet); + const contractDeployer = new ContractDeployer(TestContractArtifact, wallet); for (let index = 0; index < 2; index++) { logger.info(`Deploying contract ${index + 1}...`); - await deployer.deploy().send({ from: defaultAccountAddress, contractAddressSalt: Fr.random() }); + await contractDeployer.deploy([], { salt: Fr.random() }).send({ from: defaultAccountAddress }); } }); @@ -61,13 +69,19 @@ describe('e2e_deploy_contract legacy', () => { * Verify that we can deploy multiple contracts and interact with all of them. */ it('should deploy multiple contracts and interact with them', async () => { - const deployer = new ContractDeployer(TestContractArtifact, wallet); + const contractDeployer = new ContractDeployer(TestContractArtifact, wallet); for (let index = 0; index < 2; index++) { logger.info(`Deploying contract ${index + 1}...`); +<<<<<<< HEAD const { receipt } = await deployer .deploy() .send({ from: defaultAccountAddress, contractAddressSalt: Fr.random(), wait: { returnReceipt: true } }); +======= + const { contract: deployed } = await contractDeployer + .deploy([], { salt: Fr.random() }) + .send({ from: defaultAccountAddress }); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) logger.info(`Sending TX to contract ${index + 1}...`); await receipt.contract.methods .get_master_incoming_viewing_public_key(defaultAccountAddress) @@ -80,11 +94,11 @@ describe('e2e_deploy_contract legacy', () => { * https://hackmd.io/-a5DjEfHTLaMBR49qy6QkA */ it('should not deploy a contract with the same salt twice', async () => { - const contractAddressSalt = Fr.random(); - const deployer = new ContractDeployer(TestContractArtifact, wallet); + const salt = Fr.random(); + const contractDeployer = new ContractDeployer(TestContractArtifact, wallet); - await deployer.deploy().send({ from: defaultAccountAddress, contractAddressSalt }); - await expect(deployer.deploy().send({ from: defaultAccountAddress, contractAddressSalt })).rejects.toThrow( + await contractDeployer.deploy([], { salt }).send({ from: defaultAccountAddress }); + await expect(contractDeployer.deploy([], { salt }).send({ from: defaultAccountAddress })).rejects.toThrow( TX_ERROR_EXISTING_NULLIFIER, ); }); @@ -92,9 +106,11 @@ describe('e2e_deploy_contract legacy', () => { it('should not deploy a contract which failed the public part of the execution', async () => { // This test requires at least another good transaction to go through in the same block as the bad one. const artifact = TokenContractArtifact; - const initArgs = ['TokenName', 'TKN', 18] as const; + const initArgs = ['TokenName', 'TKN', 18]; const goodDeploy = StatefulTestContract.deploy(wallet, defaultAccountAddress, 42); - const badDeploy = new ContractDeployer(artifact, wallet).deploy(AztecAddress.ZERO, ...initArgs); + // The Token constructor is (admin, name, symbol, decimals); using AztecAddress.ZERO as the admin + // is a deliberately broken setup that fails in the public part of execution. + const badDeploy = new ContractDeployer(artifact, wallet).deploy([AztecAddress.ZERO, ...initArgs]); const firstOpts: DeployOptions = { from: defaultAccountAddress, diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts index 0f293e34e4aa..65f5be347a55 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.parallel.test.ts @@ -510,7 +510,7 @@ describe('e2e_epochs/epochs_mbps', () => { const highPriority = new GasFees(100, 100); const lowPriority = new GasFees(1, 1); - const deployMethod = TestContract.deploy(wallet); + const deployMethod = TestContract.deploy(wallet, { deployer: from }); const deployInstance = await deployMethod.getInstance(); logger.warn(`Will deploy TestContract at ${deployInstance.address}`); 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 949e5eb6e15c..4763abf825e0 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 @@ -38,7 +38,7 @@ describe('e2e_escrow_contract', () => { // Note that we need to register it first if we want to emit an encrypted note for it in the constructor escrowSecretKey = Fr.random(); escrowPublicKeys = (await deriveKeys(escrowSecretKey)).publicKeys; - const escrowDeployment = EscrowContract.deployWithPublicKeys(escrowPublicKeys, wallet, owner); + const escrowDeployment = EscrowContract.deploy(wallet, owner, { publicKeys: escrowPublicKeys, deployer: owner }); const escrowInstance = await escrowDeployment.getInstance(); await wallet.registerContract(escrowInstance, EscrowContract.artifact, escrowSecretKey); // The contract constructor initializes private storage vars that need the contract's own nullifier key. diff --git a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts index b77a07ef602d..983a27506e7f 100644 --- a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts @@ -181,21 +181,23 @@ describe('e2e_fees account_init', () => { await t.mintPrivateBananas(mintedBananas, bobsAddress); const [aliceBalanceBefore] = await t.getGasBalanceFn(aliceAddress); - const { receipt: tx } = await SchnorrAccountContractInterface.deployWithPublicKeys( - bobsPublicKeys, + const { receipt: tx } = await SchnorrAccountContractInterface.deploy( wallet, bobsSigningPubKey.x, bobsSigningPubKey.y, + { salt: bobsInstance.salt, universalDeploy: true, publicKeys: bobsPublicKeys }, ).send({ from: aliceAddress, // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. additionalScopes: [bobsAddress], - contractAddressSalt: bobsInstance.salt, skipClassPublication: true, skipInstancePublication: true, skipInitialization: false, +<<<<<<< HEAD universalDeploy: true, wait: { returnReceipt: true }, +======= +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }); // alice paid in Fee Juice diff --git a/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts b/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts index 3b776cb963c4..beb0ae32e5b2 100644 --- a/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts +++ b/yarn-project/end-to-end/src/e2e_multi_eoa.test.ts @@ -108,11 +108,11 @@ describe('e2e_multi_eoa', () => { // We should then see that another block is published but this time with a different expected account const testAccountRotation = async (expectedFirstSender: number, expectedSecondSender: number) => { // the L2 tx we are going to try and execute - const deployMethod = StatefulTestContract.deploy(wallet, defaultAccountAddress, 0); - const deployMethodTx = await proveInteraction(wallet, deployMethod, { - contractAddressSalt: Fr.random(), - from: defaultAccountAddress, + const deployMethod = StatefulTestContract.deploy(wallet, defaultAccountAddress, 0, { + salt: Fr.random(), + deployer: defaultAccountAddress, }); + const deployMethodTx = await proveInteraction(wallet, deployMethod, { from: defaultAccountAddress }); const l1Utils: L1TxUtils[] = (publisherManager as any).publishers; diff --git a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts index 8e04f856b206..15b3d1387852 100644 --- a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts +++ b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts @@ -113,11 +113,17 @@ describe('e2e_multi_validator_node', () => { const deployer = new ContractDeployer(artifact, wallet); logger.info(`Deploying contract from ${ownerAddress}`); +<<<<<<< HEAD const { receipt: tx } = await deployer.deploy(ownerAddress, 1).send({ from: ownerAddress, contractAddressSalt: new Fr(BigInt(1)), wait: { returnReceipt: true }, }); +======= + const { receipt: tx } = await deployer + .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) + .send({ from: ownerAddress }); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) await waitForProven(aztecNode, tx, { provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, }); @@ -172,11 +178,17 @@ describe('e2e_multi_validator_node', () => { // new aztec transaction logger.info(`Deploying contract from ${ownerAddress}`); const deployer = new ContractDeployer(artifact, wallet); +<<<<<<< HEAD const { receipt: tx } = await deployer.deploy(ownerAddress, 1).send({ from: ownerAddress, contractAddressSalt: new Fr(BigInt(1)), wait: { returnReceipt: true }, }); +======= + const { receipt: tx } = await deployer + .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) + .send({ from: ownerAddress }); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) await waitForProven(aztecNode, tx, { provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, }); diff --git a/yarn-project/end-to-end/src/e2e_phase_check.test.ts b/yarn-project/end-to-end/src/e2e_phase_check.test.ts index 581611cbbd71..793368f9c582 100644 --- a/yarn-project/end-to-end/src/e2e_phase_check.test.ts +++ b/yarn-project/end-to-end/src/e2e_phase_check.test.ts @@ -36,9 +36,10 @@ describe('Phase check', () => { } = await setup(1, { genesisPublicData: [genesisBalanceEntry] })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); - sponsoredFPC = await SponsoredFPCNoEndSetupContract.deploy(wallet).register({ - contractAddressSalt: new Fr(SPONSORED_FPC_SALT), - }); + sponsoredFPC = await SponsoredFPCNoEndSetupContract.deploy(wallet, { + salt: new Fr(SPONSORED_FPC_SALT), + universalDeploy: true, + }).register(); // If the below fails, the registration parameters are different than the instance generation parameters that we used for funding the address. expect(sponsorInstance.address).toEqual(sponsoredFPC.address); diff --git a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts index 551304e259bd..bf507e00cbe2 100644 --- a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts @@ -52,19 +52,16 @@ describe(`deploys and transfers a private only token`, () => { const tokenSecretKey = Fr.random(); const tokenPublicKeys = (await deriveKeys(tokenSecretKey)).publicKeys; - const tokenDeployment = PrivateTokenContract.deployWithPublicKeys( - tokenPublicKeys, - wallet, - initialBalance, - deployerAddress, - ); + const tokenDeployment = PrivateTokenContract.deploy(wallet, initialBalance, deployerAddress, { + universalDeploy: true, + publicKeys: tokenPublicKeys, + }); const tokenInstance = await tokenDeployment.getInstance(); await wallet.registerContract(tokenInstance, PrivateTokenContract.artifact, tokenSecretKey); const { contract: token } = await tokenDeployment.send({ from: deployerAddress, // The contract constructor initializes private storage vars that need the contract's own nullifier key. additionalScopes: [tokenInstance.address], - universalDeploy: true, skipInstancePublication: true, skipClassPublication: true, skipInitialization: false, diff --git a/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts index 4702f3077144..3df08722d830 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/reload_keystore.test.ts @@ -130,11 +130,9 @@ describe('e2e_reload_keystore', () => { // Send a tx and verify the block uses the initial coinbase const deployer = new ContractDeployer(artifact, wallet); - const { txHash: sentTx1 } = await deployer.deploy(ownerAddress, 1).send({ - from: ownerAddress, - contractAddressSalt: new Fr(1), - wait: NO_WAIT, - }); + const { txHash: sentTx1 } = await deployer + .deploy([ownerAddress, 1], { salt: new Fr(1) }) + .send({ from: ownerAddress, wait: NO_WAIT }); const receipt1 = await waitForTx(aztecNode, sentTx1); const block1 = await aztecNode.getBlock(BlockNumber(receipt1.blockNumber!)); @@ -195,11 +193,9 @@ describe('e2e_reload_keystore', () => { // Whichever validator is the proposer, its coinbase must be from the reloaded keystore. const allNewCoinbasesLower = newCoinbases.map(c => c.toString().toLowerCase()); - const { txHash: sentTx2 } = await deployer.deploy(ownerAddress, 2).send({ - from: ownerAddress, - contractAddressSalt: new Fr(2), - wait: NO_WAIT, - }); + const { txHash: sentTx2 } = await deployer + .deploy([ownerAddress, 2], { salt: new Fr(2) }) + .send({ from: ownerAddress, wait: NO_WAIT }); const receipt2 = await waitForTx(aztecNode, sentTx2); const block2 = await aztecNode.getBlock(BlockNumber(receipt2.blockNumber!)); diff --git a/yarn-project/end-to-end/src/e2e_simple.test.ts b/yarn-project/end-to-end/src/e2e_simple.test.ts index df4ad6be3a9c..2d625b32e074 100644 --- a/yarn-project/end-to-end/src/e2e_simple.test.ts +++ b/yarn-project/end-to-end/src/e2e_simple.test.ts @@ -71,11 +71,17 @@ describe('e2e_simple', () => { it('deploys a contract', async () => { const deployer = new ContractDeployer(artifact, wallet); +<<<<<<< HEAD const { receipt: txReceipt } = await deployer.deploy(ownerAddress, 1).send({ from: ownerAddress, contractAddressSalt: new Fr(BigInt(1)), wait: { returnReceipt: true }, }); +======= + const { receipt: txReceipt } = await deployer + .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) + .send({ from: ownerAddress }); +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) await waitForProven(aztecNode, txReceipt, { provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, }); diff --git a/yarn-project/end-to-end/src/fixtures/setup.ts b/yarn-project/end-to-end/src/fixtures/setup.ts index bcd0ac6b0666..d2b307c257b0 100644 --- a/yarn-project/end-to-end/src/fixtures/setup.ts +++ b/yarn-project/end-to-end/src/fixtures/setup.ts @@ -7,6 +7,11 @@ import { BatchCall, type ContractFunctionInteraction, type ContractMethod, +<<<<<<< HEAD +======= + type DeployOptions, + type InteractionWaitOptions, +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) getContractClassFromArtifact, waitForProven, } from '@aztec/aztec.js/contracts'; @@ -865,7 +870,11 @@ export async function ensureAccountContractsPublished(wallet: Wallet, accountsTo * Returns deployed account data that can be used by tests. */ export const deployAccounts = +<<<<<<< HEAD (numberOfAccounts: number, logger: Logger) => +======= + (numberOfAccounts: number, logger: Logger, deployOptions?: Partial>) => +>>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) async ({ wallet, initialFundedAccounts }: { wallet: TestWallet; initialFundedAccounts: InitialAccountData[] }) => { if (initialFundedAccounts.length < numberOfAccounts) { throw new Error(`Cannot deploy more than ${initialFundedAccounts.length} initial accounts.`); diff --git a/yarn-project/end-to-end/src/test-wallet/utils.ts b/yarn-project/end-to-end/src/test-wallet/utils.ts index f75a0518492e..ec7b2554a414 100644 --- a/yarn-project/end-to-end/src/test-wallet/utils.ts +++ b/yarn-project/end-to-end/src/test-wallet/utils.ts @@ -65,12 +65,7 @@ export async function proveInteraction( interaction: ContractFunctionInteraction | DeployMethod, options: SendInteractionOptions | DeployOptions, ) { - let execPayload; - if (interaction instanceof DeployMethod) { - execPayload = await interaction.request(interaction.convertDeployOptionsToRequestOptions(options)); - } else { - execPayload = await interaction.request(options); - } + const execPayload = await interaction.request(options); return wallet.proveTx(execPayload, toSendOptions(options)); } From d3d6d68dea94ac5711f66e978c98ed304e65f87e Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 06:30:30 +0000 Subject: [PATCH 08/30] fix: resolve cherry-pick conflicts Resolve conflicts in #22985 cherry-pick onto v4-next-staging: - migration_notes.md: keep only the new DeployMethod note. Drop unrelated entries (getBlock/getCheckpoint, feeAssetPriceModifier, Domain separators, aztec-up table, slasher renames, Unreleased v5 returnReceipt removal) from PRs not yet backported. - txe_oracles.nr / constants*.nr: drop bleed-through constants (NULL_MSG_SENDER_CONTRACT_ADDRESS, DOM_SEP__HANDSHAKE_SECRET_HASH, DOM_SEP__MERKLE_HASH, DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__PARTIAL_NOTE_COMMITMENT, DOM_SEP__PUBLIC_DATA_MERKLE) introduced by other PRs. - bot/factory.ts: adopt new DeployInstantiationOptions API; drop setupTokenWithOptionalEarlyRefuel / setupTokenContractWithOptionalEarlyRefuel / getTokenInstance helpers from an unbackported refuel PR; hoist instance variable so the post-if address read works on v4-next. - e2e tests + cli-wallet/deploy.ts: adopt new DeployInstantiationOptions API (salt/deployer/universalDeploy/publicKeys move to construction); keep v4-next-only 'wait: { returnReceipt: true }' callers compatible. - aztec.js/api/contract.ts: keep DeployTxReceipt / DeployWaitOptions / DeployInteractionWaitOptions exports (v4-next-only). - e2e_ha_full.test.ts: drop the keystore-reload test (introduced by an unbackported keystore-reload PR). - token_bridge/index.ts: keep node.getProvenBlockNumber() (the new getBlockNumber('proven') ships with the unbackported getBlock RPC PR). --- .../docs/resources/migration_notes.md | 161 +----------------- docs/examples/ts/token_bridge/index.ts | 8 - .../aztec/src/test/helpers/txe_oracles.nr | 4 - .../crates/types/src/constants.nr | 7 - .../crates/types/src/constants_tests.nr | 20 --- yarn-project/aztec.js/src/api/contract.ts | 3 - .../aztec.js/src/contract/contract.test.ts | 158 ----------------- .../src/contract/deploy_method.test.ts | 39 ----- .../aztec.js/src/contract/deploy_method.ts | 12 +- yarn-project/bot/src/factory.ts | 92 +--------- .../src/composed/ha/e2e_ha_full.test.ts | 89 ---------- .../src/e2e_contract_updates.test.ts | 8 +- .../src/e2e_deploy_contract/legacy.test.ts | 16 +- .../src/e2e_fees/account_init.test.ts | 4 - .../e2e_multi_validator_node.test.ts | 20 +-- .../end-to-end/src/e2e_simple.test.ts | 10 +- yarn-project/end-to-end/src/fixtures/setup.ts | 7 - 17 files changed, 16 insertions(+), 642 deletions(-) diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 2cf7da2d33e7..fe38bd2f48b6 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -9,9 +9,6 @@ Aztec is in active development. Each version may introduce breaking changes that ## TBD -<<<<<<< HEAD -### [Aztec.nr] TXE `call_public_incognito` no longer takes a `from` parameter -======= ### [Aztec.js] `DeployMethod` address-affecting parameters move to construction time Salt, deployer, and public keys are now passed when the `DeployMethod` is constructed, not on every call to `send` / `simulate` / `request` / `getInstance`. This locks the contract address once it is determined and prevents the silent salt-cache poisoning bug where the address could change between calls. @@ -103,8 +100,7 @@ The synchronous `address` / `partialAddress` getters are gone: + const instance = await deploy.getInstance(); ``` -### [aztec-up] Bundled binaries are no longer exposed under bare names on `PATH` ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) +### [Aztec.nr] TXE `call_public_incognito` no longer takes a `from` parameter `TestEnvironment::call_public_incognito` previously accepted a `from` address that was silently ignored (the function always uses a null `msg_sender`). The `from` parameter has been removed. @@ -113,24 +109,7 @@ The synchronous `address` / `partialAddress` getters are gone: + env.call_public_incognito(SampleContract::at(addr).some_function()); ``` -<<<<<<< HEAD If you need to call a public function *with* a sender, use `call_public` instead. -======= -| Was on `PATH` | Now | -| ------------------ | ------------------------ | -| `forge` | `aztec-forge` | -| `cast` | `aztec-cast` | -| `anvil` | `aztec-anvil` | -| `chisel` | `aztec-chisel` | -| `nargo` | `aztec-nargo` | -| `noir-profiler` | `aztec-noir-profiler` | -| `bb` | `aztec-bb` | -| `bb-cli` | `aztec-bb-cli` | -| `pxe` | `aztec-pxe` | -| `txe` | `aztec-txe` | -| `validator-client` | `aztec-validator-client` | -| `blob-client` | `aztec-blob-client` | ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) ### [Aztec.nr] TXE `view_public_incognito` is deprecated @@ -168,61 +147,6 @@ The wallet SDK now supplies the default sender-for-tags from the transaction's ` The save/restore idiom previously used in account-contract constructors (`get` → `set(self.address)` → work → `set(prev)`) is also no longer needed and has been removed: the override never leaks out of the constructor, so there is nothing to restore. -<<<<<<< HEAD -======= -### [Aztec Node] Unified `getBlock` / `getCheckpoint` RPC API - -The Aztec Node JSON-RPC surface for fetching blocks and checkpoints has been consolidated. The unified `getBlock` and `getCheckpoint` methods return uniform `BlockResponse` / `CheckpointResponse` shapes. The extra fields a caller cares about (tx bodies, L1 publish info, committee attestations, nested blocks) are now controlled by an `options` argument rather than by picking the right method. `getBlocks` and `getCheckpoints` retain their names but now return the new response shapes. - -**Removed methods:** - -| Removed | Replacement | -| ---------------------------------- | -------------------------------------------- | -| `getBlockByHash(hash)` | `getBlock(hash)` or `getBlock({ hash })` | -| `getBlockByArchive(archive)` | `getBlock({ archive })` | -| `getBlockHeaderByArchive(archive)` | `getBlock({ archive }).then(r => r?.header)` | -| `getProvenBlockNumber()` | `getBlockNumber('proven')` | -| `getCheckpointedBlockNumber()` | `getBlockNumber('checkpointed')` | - -**Deprecated but still present** (scheduled for removal once internal consumers of the archiver shape are rewired): `getL2Tips` (use `getChainTips`), `getBlockHeader` (use `getBlock(param).then(r => r?.header)`), `getCheckpointedBlocks` (use `getBlocks(from, limit, { includeL1PublishInfo: true, includeAttestations: true })`), `getCheckpointsDataForEpoch` (use `getCheckpoints(from, limit)` over the epoch's checkpoint range). Do not adopt these in new code. - -**New response shapes:** `BlockResponse` always carries `header`, `archive`, `hash`, `number`, `checkpointNumber`, and `indexWithinCheckpoint`. `body`, `l1` (an `L1PublishInfo` discriminated union), and `attestations` are present only when the matching include option is set. `CheckpointResponse` mirrors this for checkpoints, with `blocks` gated on `includeBlocks`, and always carries `feeAssetPriceModifier` as a base field. The response types are generic over the options object, so passing a literal `{ includeTransactions: true }` narrows the return type and `response.body` becomes non-optional. - -**Nested blocks on `getCheckpoint`:** only `includeTransactions` is forwarded to the blocks embedded by `includeBlocks: true`. `includeL1PublishInfo` and `includeAttestations` on a checkpoint request attach L1 / attestation data to the checkpoint itself, not to its nested blocks. - -**Return type changes for `getBlocks` / `getCheckpoints`:** the return type is now `BlockResponse[]` / `CheckpointResponse[]` instead of `L2Block[]` / `PublishedCheckpoint[]`. Callers that previously consumed fields of `L2Block` (e.g. `.body`) must now opt in via `{ includeTransactions: true }`; callers that consumed `PublishedCheckpoint.checkpoint.blocks` must opt in via `{ includeBlocks: true }`. - -**Migration for wallet/SDK consumers (`@aztec/aztec.js`, `@aztec/wallet-sdk`):** - -```diff -- const block = await node.getBlockByHash(hash); -+ const block = await node.getBlock(hash, { includeTransactions: true }); - -- const archiveBlock = await node.getBlockByArchive(archive); -+ const archiveBlock = await node.getBlock({ archive }, { includeTransactions: true }); - -- const provenNumber = await node.getProvenBlockNumber(); -+ const provenNumber = await node.getBlockNumber('proven'); - -- const checkpointedNumber = await node.getCheckpointedBlockNumber(); -+ const checkpointedNumber = await node.getBlockNumber('checkpointed'); - -- const tips = await node.getL2Tips(); -+ const tips = await node.getChainTips(); -``` - -`getBlockHeader`, `getCheckpointedBlocks`, `getCheckpointsDataForEpoch`, and `getL2Tips` continue to work in this release but are deprecated; migrate to the replacements above. - -**Chain-tip selectors:** `getBlockNumber` and `getCheckpointNumber` now accept an optional `ChainTip` argument (`'proposed' | 'checkpointed' | 'proven' | 'finalized'`). Note the semantic difference: on the block side `'proposed'` means the latest proposed block (chain head), whereas on the checkpoint side `'proposed'` resolves to the latest L1-confirmed checkpoint. Pre-L1-confirmation checkpoints are not exposed over RPC. - -**Block parameter variants:** `BlockParameter` now also accepts a block hash, an archive root, and chain-tip names. The existing `number | 'latest'` forms continue to work — `'latest'` is an alias for `'proposed'`. - -**Impact**: Source changes are required anywhere the removed methods are called. Type changes are required anywhere `L2Block` / `BlockHeader` / `CheckpointedL2Block` were consumed from the RPC — those call sites now receive `BlockResponse` / `CheckpointResponse` and must request the fields they need via `options`. Production nodes will reject JSON-RPC calls to the removed method names. - -### [Aztec Node] `feeAssetPriceModifier` now correctly populated on confirmed checkpoints - -Confirmed checkpoints previously reported `feeAssetPriceModifier = 0n` regardless of the value observed on L1, because the archiver dropped the field on checkpoint confirmation. The field is now persisted and returned correctly on `CheckpointResponse`. Any wallet or indexer logic that special-cased `0n` as a sentinel for "no modifier" will need to be updated; it is now a valid value in its own right. ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) ### [CLI] `aztec-up` no longer exposes transitive npm bins on PATH @@ -242,47 +166,6 @@ echo $PATH `$HOME/.aztec/current/node_modules/.bin` should no longer appear in the output. You'll also see your own `jest`, `tsc`, etc. again instead of the ones bundled with the Aztec toolchain. -<<<<<<< HEAD -======= -### [Protocol] Domain separators introduced for merkle-node, block-headers, and blob hashes - -Several protocol hashes that previously used bare `poseidon2_hash` are now domain-separated via `poseidon2_hash_with_separator`. This is a security hardening change — it prevents a value produced by one hash context from being reinterpreted in another (e.g. a sibling path from one tree being transported to another). - -**New domain separators:** - -- `DOM_SEP__MERKLE_HASH` — sibling-pair hash for append-only trees (note-hash, L1→L2, archive, VK tree, and the balanced/unbalanced tree hash helpers in `@aztec/foundation/trees`). -- `DOM_SEP__NULLIFIER_MERKLE`, `DOM_SEP__PUBLIC_DATA_MERKLE`, `DOM_SEP__WRITTEN_SLOTS_MERKLE`, `DOM_SEP__RETRIEVED_BYTECODES_MERKLE` — per-tree sibling-pair hash for each indexed tree. Each tree uses its own separator so sibling paths are non-transportable across trees. -- `DOM_SEP__BLOCK_HEADERS_HASH` — used when accumulating block headers into `blockHeadersHash`. -- `DOM_SEP__BLOB_HASHED_Y_LIMBS`, `DOM_SEP__BLOB_CHALLENGE_Z`, `DOM_SEP__BLOB_Z_ACC`, `DOM_SEP__BLOB_GAMMA_ACC`, `DOM_SEP__BLOB_GAMMA_FINAL` — blob accumulator and challenge derivations. - -**:warning: Hard-coded test constants will no longer match.** Every value derived from any of the hashes above is new in this release. This includes (non-exhaustively): - -- **All merkle tree roots** — note-hash, nullifier, public-data, L1→L2 message, archive, VK, and the AVM-internal written-slots and retrieved-bytecodes (class-ids) trees. -- **Genesis constants** — `GENESIS_BLOCK_HEADER_HASH`, `GENESIS_ARCHIVE_ROOT`, `AVM_WRITTEN_PUBLIC_DATA_SLOTS_TREE_INITIAL_ROOT`, `AVM_RETRIEVED_BYTECODES_TREE_INITIAL_ROOT`. -- **Every block hash and archive root** — they commit to tree roots and the new block-headers-hash. -- **Protocol contract addresses** — their derivation depends on the private-function tree root. -- **Blob commitments / challenges** — any test that pins `z`, `gamma`, or the accumulator outputs. - -Regenerate these values from a fresh build of this release — do not copy them from previous release fixtures. - -**If you re-implement any of these hashes off-circuit** (e.g. a wallet that computes nullifier low-leaf membership, or an indexer that derives block hashes / tree roots), update the call sites: - -```diff - // Merkle sibling-pair hash (append-only trees) -- poseidon2Hash([left, right]) -+ poseidon2HashWithSeparator([left, right], DomainSeparator.MERKLE_HASH) - - // Indexed-tree sibling-pair hash — pick the matching tree separator -- poseidon2Hash([left, right]) -+ poseidon2HashWithSeparator([left, right], DomainSeparator.NULLIFIER_MERKLE) -+ // or PUBLIC_DATA_MERKLE, WRITTEN_SLOTS_MERKLE, RETRIEVED_BYTECODES_MERKLE -``` - -`poseidon2HashWithSeparator` is exported from `@aztec/foundation/crypto/poseidon`; the `DomainSeparator` enum and the matching `DOM_SEP__*` constants are defined in `@aztec/constants`. The new entries listed above are additions — existing separator names are unchanged. - -For TypeScript consumers, `@aztec/stdlib/hash` exports ready-made helpers that wrap the right separator: `computeMerkleHash` (append-only), `computeNullifierMerkleHash`, and `computePublicDataMerkleHash`. Prefer these over calling `poseidon2HashWithSeparator` directly so the separator choice stays colocated with the tree. - ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) ### [Aztec.nr] `emit_private_log_unsafe` / `emit_raw_note_log_unsafe` are deprecated `emit_private_log_unsafe` and `emit_raw_note_log_unsafe` are deprecated and will be removed in a future release. Migrate to the new `emit_private_log_vec_unsafe` / `emit_raw_note_log_vec_unsafe` functions, which take a `BoundedVec` instead of the `(log: [Field; PRIVATE_LOG_CIPHERTEXT_LEN], length: u32)` pair. @@ -336,49 +219,7 @@ This has been done because this is the format expected by the functionality in p The old `DEFAULT_GAS_LIMIT` and `DEFAULT_TEARDOWN_GAS_LIMIT` constants have been removed. Gas limits are now derived from protocol-level maximums (`MAX_PROCESSABLE_L2_GAS`, `MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT`) rather than arbitrary fixed values. -<<<<<<< HEAD A new `GasSettings.forEstimation()` method provides intentionally high gas limits for use during simulation. These limits exceed protocol maximums so the simulation doesn't hit gas caps — you must pass `skipTxValidation: true` when simulating with them, then use the results to set accurate gas limits on the actual transaction. `EmbeddedWallet` does this by default. -======= -**L1 contract changes:** - -- `SlasherFlavor` enum removed from `ISlasher.sol` -- `RollupConfigInput.slasherFlavor` (enum) replaced with `slasherEnabled` (bool) -- `TallySlashingProposer` contract renamed to `SlashingProposer` -- `TallySlasherDeploymentExtLib` library renamed to `SlasherDeploymentExtLib` -- `SlashFactory` periphery contract removed -- `SLASHING_PROPOSER_TYPE` constant removed from `SlashingProposer` -- All `TallySlashingProposer__` error prefixes renamed to `SlashingProposer__` - -**Environment variable changes:** - -```diff -- AZTEC_SLASHER_FLAVOR=tally # was: "tally" | "empire" | "none" -+ AZTEC_SLASHER_ENABLED=true # now a boolean -``` - -**Removed environment variables:** `SLASH_MIN_PENALTY_PERCENTAGE`, `SLASH_MAX_PENALTY_PERCENTAGE` - -**Removed from deploy outputs:** `slashFactoryAddress` - -**Node admin API:** `getSlashPayloads()` method removed. - -**TypeScript config changes:** - -```diff -- slasherFlavor: 'tally' | 'none' -+ slasherEnabled: boolean -``` - -`slashMinPenaltyPercentage` and `slashMaxPenaltyPercentage` removed from `SlasherConfig`. - -## Unreleased (v5) - -### [aztec.js] `DeployMethod.send()` always returns `{ contract, receipt, instance }` - -The `returnReceipt` option in deploy wait options has been removed. `DeployMethod.send()` now always returns an object with `contract`, `receipt`, and `instance` at the top level, provided the user waits for the transaction to be included. - -The `DeployTxReceipt` and `DeployWaitOptions` types have been removed. ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) **Migration:** diff --git a/docs/examples/ts/token_bridge/index.ts b/docs/examples/ts/token_bridge/index.ts index afefee3bfa44..37e77f0daa13 100644 --- a/docs/examples/ts/token_bridge/index.ts +++ b/docs/examples/ts/token_bridge/index.ts @@ -290,11 +290,7 @@ const msgLeaf = computeL2ToL1MessageHash({ console.log("Waiting for block to be proven..."); console.log(` Exit block number: ${exitReceipt.blockNumber}`); -<<<<<<< HEAD let provenBlockNumber = await node.getProvenBlockNumber(); -======= -let provenBlockNumber = await node.getBlockNumber("proven"); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) console.log(` Current proven block: ${provenBlockNumber}`); while (provenBlockNumber < exitReceipt.blockNumber!) { @@ -302,11 +298,7 @@ while (provenBlockNumber < exitReceipt.blockNumber!) { ` Waiting... (proven: ${provenBlockNumber}, needed: ${exitReceipt.blockNumber})`, ); await new Promise((resolve) => setTimeout(resolve, 10000)); // Wait 10 seconds -<<<<<<< HEAD provenBlockNumber = await node.getProvenBlockNumber(); -======= - provenBlockNumber = await node.getBlockNumber("proven"); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) } console.log("Block proven!\n"); diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr index 17d9b9f14746..8ab6ecb42db4 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr @@ -8,11 +8,7 @@ use crate::protocol::{ address::AztecAddress, constants::{ CONTRACT_INSTANCE_LENGTH, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_LOGS_PER_TX, -<<<<<<< HEAD PRIVATE_LOG_SIZE_IN_FIELDS, -======= - NULL_MSG_SENDER_CONTRACT_ADDRESS, PRIVATE_LOG_SIZE_IN_FIELDS, ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }, contract_instance::ContractInstance, traits::{Deserialize, ToField}, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 4c39ceaa468f..16fd271a96b6 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -762,13 +762,6 @@ pub global DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER: u32 = 3990889078; /// Domain separator for L1 to L2 message secret hashes. pub global DOM_SEP__SECRET_HASH: u32 = 4199652938; -<<<<<<< HEAD -======= -/// Domain separator for the secret hash stored in handshake notes produced by the handshake registry contract. -/// Kept distinct from [`DOM_SEP__SECRET_HASH`] (which is specifically for L1 to L2 messages). -pub global DOM_SEP__HANDSHAKE_SECRET_HASH: u32 = 3596796143; - ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) /// Domain separator for transaction nullifiers. /// /// Used to produce cancellable (replaceable) transactions. diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr index c19267aa3fe1..8ade1f4e9cbb 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr @@ -10,7 +10,6 @@ use crate::{ DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__CONTRACT_ADDRESS_V1, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY, DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FUNCTION_ARGS, -<<<<<<< HEAD DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, DOM_SEP__IVSK_M, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, DOM_SEP__OVSK_M, @@ -18,17 +17,6 @@ use crate::{ DOM_SEP__PRIVATE_FUNCTION_LEAF, DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, DOM_SEP__PRIVATE_LOG_FIRST_FIELD, DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, DOM_SEP__PUBLIC_BYTECODE, DOM_SEP__PUBLIC_CALLDATA, -======= - DOM_SEP__HANDSHAKE_SECRET_HASH, DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, - DOM_SEP__IVSK_M, DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, - DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_COMPLETION_LOG_TAG, - DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, - DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS, - DOM_SEP__PARTIAL_NOTE_COMMITMENT, DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, - DOM_SEP__PRIVATE_FUNCTION_LEAF, DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, - DOM_SEP__PRIVATE_LOG_FIRST_FIELD, DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, - DOM_SEP__PUBLIC_BYTECODE, DOM_SEP__PUBLIC_CALLDATA, DOM_SEP__PUBLIC_DATA_MERKLE, ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) DOM_SEP__PUBLIC_INITIALIZATION_NULLIFIER, DOM_SEP__PUBLIC_KEYS_HASH, DOM_SEP__PUBLIC_LEAF_SLOT, DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, DOM_SEP__PUBLIC_TX_HASH, DOM_SEP__SECRET_HASH, DOM_SEP__SIGNATURE_PAYLOAD, DOM_SEP__SILOED_NOTE_HASH, @@ -178,14 +166,6 @@ fn hashed_values_match_derived() { DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, "unconstrained_msg_log_tag", ); -<<<<<<< HEAD -======= - tester.assert_dom_sep_matches_derived( - DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, - "non_interactive_handshake_log_tag", - ); - tester.assert_dom_sep_matches_derived(DOM_SEP__HANDSHAKE_SECRET_HASH, "handshake_secret_hash"); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) tester.assert_dom_sep_matches_derived(DOM_SEP__MESSAGE_NULLIFIER, "message_nullifier"); tester.assert_dom_sep_matches_derived(DOM_SEP__PRIVATE_FUNCTION_LEAF, "private_function_leaf"); tester.assert_dom_sep_matches_derived(DOM_SEP__PUBLIC_BYTECODE, "public_bytecode"); diff --git a/yarn-project/aztec.js/src/api/contract.ts b/yarn-project/aztec.js/src/api/contract.ts index 67e458b4263d..5c659333bb35 100644 --- a/yarn-project/aztec.js/src/api/contract.ts +++ b/yarn-project/aztec.js/src/api/contract.ts @@ -75,12 +75,9 @@ export { type DeployOptions, type DeployResultMined, type DeployReturn, -<<<<<<< HEAD type DeployTxReceipt, type DeployWaitOptions, type DeployInteractionWaitOptions, -======= ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) DeployMethod, type RequestDeployOptions, type SimulateDeployOptions, diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index 7243f73eb362..09ecad876a02 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -35,164 +35,6 @@ describe('Contract Class', () => { anchorBlockTimestamp: 0n, } as any as UtilityExecutionResult; -<<<<<<< HEAD - const defaultArtifact: ContractArtifact = { - name: 'FooContract', - aztecVersion: DEV_VERSION, - functions: [ - { - name: 'bar', - isInitializer: false, - functionType: FunctionType.PRIVATE, - isOnlySelf: false, - isStatic: false, - debugSymbols: '', - parameters: [ - { - name: 'value', - type: { - kind: 'field', - }, - visibility: 'public', - }, - { - name: 'value', - type: { - kind: 'field', - }, - visibility: 'private', - }, - ], - returnTypes: [], - errorTypes: {}, - bytecode: Buffer.alloc(8, 0xfa), - verificationKey: Buffer.alloc(4064).toString('base64'), - }, - { - name: 'public_dispatch', - isInitializer: false, - isStatic: false, - functionType: FunctionType.PUBLIC, - isOnlySelf: false, - parameters: [ - { - name: 'selector', - type: { - kind: 'field', - }, - visibility: 'public', - }, - ], - returnTypes: [], - errorTypes: {}, - bytecode: Buffer.alloc(8, 0xfb), - debugSymbols: '', - }, - { - name: 'qux', - isInitializer: false, - isStatic: false, - functionType: FunctionType.UTILITY, - isOnlySelf: false, - parameters: [ - { - name: 'value', - type: { - kind: 'field', - }, - visibility: 'public', - }, - ], - returnTypes: [ - { - kind: 'integer', - sign: 'unsigned', - width: 32, - }, - ], - bytecode: Buffer.alloc(8, 0xfc), - debugSymbols: '', - errorTypes: {}, - }, - { - name: 'optionEcho', - isInitializer: false, - functionType: FunctionType.PRIVATE, - isOnlySelf: false, - isStatic: false, - parameters: [ - { - name: 'value', - type: { - kind: 'struct', - path: 'std::option::Option', - fields: [ - { - name: '_is_some', - type: { - kind: 'boolean', - }, - }, - { - name: '_value', - type: { - kind: 'field', - }, - }, - ], - }, - visibility: 'private', - }, - ], - returnTypes: [], - errorTypes: {}, - bytecode: Buffer.alloc(8, 0xfd), - verificationKey: Buffer.alloc(4064).toString('base64'), - debugSymbols: '', - }, - { - name: 'mixedParams', - isInitializer: false, - functionType: FunctionType.PRIVATE, - isOnlySelf: false, - isStatic: false, - parameters: [ - { - name: 'optValue', - type: { - kind: 'struct', - path: 'std::option::Option', - fields: [ - { name: '_is_some', type: { kind: 'boolean' } }, - { name: '_value', type: { kind: 'field' } }, - ], - }, - visibility: 'private', - }, - { - name: 'aField', - type: { kind: 'field' }, - visibility: 'private', - }, - ], - returnTypes: [], - errorTypes: {}, - bytecode: Buffer.alloc(8, 0xfe), - verificationKey: Buffer.alloc(4064).toString('base64'), - debugSymbols: '', - }, - ], - nonDispatchPublicFunctions: [], - outputs: { - structs: {}, - globals: {}, - }, - fileMap: {}, - storageLayout: {}, - }; - -======= ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) beforeEach(async () => { contractAddress = await AztecAddress.random(); account = mock(); diff --git a/yarn-project/aztec.js/src/contract/deploy_method.test.ts b/yarn-project/aztec.js/src/contract/deploy_method.test.ts index 60b958ce2d0e..3bc8b6458fa3 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.test.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.test.ts @@ -15,45 +15,6 @@ import { NO_FROM } from './interaction_options.js'; describe('DeployMethod', () => { let wallet: MockProxy; -<<<<<<< HEAD - const artifact: ContractArtifact = { - name: 'TestContract', - aztecVersion: DEV_VERSION, - functions: [ - { - name: 'constructor', - isInitializer: true, - functionType: FunctionType.PRIVATE, - isOnlySelf: false, - isStatic: false, - debugSymbols: '', - parameters: [], - returnTypes: [], - errorTypes: {}, - bytecode: Buffer.alloc(8, 0xfa), - verificationKey: Buffer.alloc(4064).toString('base64'), - }, - { - name: 'public_dispatch', - isInitializer: false, - isStatic: false, - functionType: FunctionType.PUBLIC, - isOnlySelf: false, - parameters: [{ name: 'selector', type: { kind: 'field' }, visibility: 'public' }], - returnTypes: [], - errorTypes: {}, - bytecode: Buffer.alloc(8, 0xfb), - debugSymbols: '', - }, - ], - nonDispatchPublicFunctions: [], - outputs: { structs: {}, globals: {} }, - fileMap: {}, - storageLayout: {}, - }; - -======= ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) beforeEach(() => { wallet = mock(); wallet.registerContract.mockResolvedValue({} as ContractInstanceWithAddress); diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index 27ae05f8ce5e..405fa3ea7404 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -40,7 +40,6 @@ import { import type { WaitOpts } from './wait_opts.js'; /** -<<<<<<< HEAD * Wait options specific to deployment transactions. * Extends WaitOpts with a flag to return the full receipt instead of just the contract. */ @@ -56,7 +55,8 @@ export type DeployWaitOptions = WaitOpts & { * - undefined: Wait with default options */ export type DeployInteractionWaitOptions = NoWait | DeployWaitOptions | undefined; -======= + +/** * Inputs that determine the contract's deployment address. * * `salt` and `publicKeys` are optional and default to a random Fr and `PublicKeys.default()` respectively. @@ -86,7 +86,6 @@ export type DeployInstantiationOptions = { /** Public keys mixed into the address. Defaults to PublicKeys.default(). */ publicKeys?: PublicKeys; }; ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) /** * Options for deploying a contract on the Aztec network. @@ -441,13 +440,8 @@ export class DeployMethod extends * Send a contract deployment transaction (initialize and/or publish) using the provided options. * By default, waits for the transaction to be mined and returns the deployed contract instance. * -<<<<<<< HEAD - * @param options - An object containing various deployment options such as contractAddressSalt and from. - * @returns TxHash (if wait is NO_WAIT), TContract (if wait is undefined or doesn't have returnReceipt), or DeployTxReceipt (if wait.returnReceipt is true) -======= * @param options - An object containing various deployment options such as `from` and `fee`. - * @returns TxHash (if wait is NO_WAIT), or DeployResultMined with contract, receipt, and instance (otherwise) ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) + * @returns TxHash (if wait is NO_WAIT), TContract (if wait is undefined or doesn't have returnReceipt), or DeployTxReceipt (if wait.returnReceipt is true) */ // Overload for when wait is not specified at all - returns the contract public override send(options: DeployOptionsWithoutWait): Promise>; diff --git a/yarn-project/bot/src/factory.ts b/yarn-project/bot/src/factory.ts index a7d765011695..f1d9f3c3a70e 100644 --- a/yarn-project/bot/src/factory.ts +++ b/yarn-project/bot/src/factory.ts @@ -249,94 +249,20 @@ export class BotFactory { } /** -<<<<<<< HEAD -======= - * Setup token and refuel first: if the token already exists (restart scenario), - * run ensureFeeJuiceBalance before any step that might need fee juice. When deploying, - * use a bridge claim if balance is below threshold. - */ - private async setupTokenWithOptionalEarlyRefuel(sender: AztecAddress): Promise { - const token = await this.getTokenInstance(sender); - const address = token.address; - const metadata = await this.wallet.getContractMetadata(address); - if (metadata.isContractPublished) { - this.log.info(`Token at ${address.toString()} already deployed, refueling before setup`); - await this.ensureFeeJuiceBalance(sender, token); - } - return this.setupToken(sender); - } - - /** - * Setup token0 for AMM with refuel-first behaviour when token already exists. - */ - private async setupTokenContractWithOptionalEarlyRefuel( - deployer: AztecAddress, - salt: Fr, - name: string, - ticker: string, - decimals = 18, - ): Promise { - const deploy = TokenContract.deploy(this.wallet, deployer, name, ticker, decimals, { salt, universalDeploy: true }); - const instance = await deploy.getInstance(); - const metadata = await this.wallet.getContractMetadata(instance.address); - if (metadata.isContractPublished) { - this.log.info(`Token ${name} at ${instance.address.toString()} already deployed, refueling before setup`); - const token = TokenContract.at(instance.address, this.wallet); - await this.ensureFeeJuiceBalance(deployer, token); - } - return this.setupTokenContract(deployer, salt, name, ticker, decimals); - } - - private async getTokenInstance(sender: AztecAddress): Promise { - const salt = this.config.tokenSalt; - if (this.config.contract === SupportedTokenContracts.TokenContract) { - const deploy = TokenContract.deploy(this.wallet, sender, 'BotToken', 'BOT', 18, { salt, universalDeploy: true }); - const instance = await deploy.getInstance(); - return TokenContract.at(instance.address, this.wallet); - } - if (this.config.contract === SupportedTokenContracts.PrivateTokenContract) { - const tokenSecretKey = Fr.random(); - const tokenPublicKeys = (await deriveKeys(tokenSecretKey)).publicKeys; - const deploy = PrivateTokenContract.deploy(this.wallet, MINT_BALANCE, sender, { - salt, - universalDeploy: true, - publicKeys: tokenPublicKeys, - }); - const instance = await deploy.getInstance(); - return PrivateTokenContract.at(instance.address, this.wallet); - } - throw new Error(`Unsupported token contract type: ${this.config.contract}`); - } - - /** ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) * Checks if the token contract is deployed and deploys it if necessary. * @param wallet - Wallet to deploy the token contract from. * @returns The TokenContract instance. */ private async setupToken(sender: AztecAddress): Promise { let deploy: DeployMethod; -<<<<<<< HEAD - let tokenInstance: ContractInstanceWithAddress | undefined; - const deployOpts: DeployOptions = { - from: sender, - contractAddressSalt: this.config.tokenSalt, - universalDeploy: true, - }; - let token: TokenContract | PrivateTokenContract; - if (this.config.contract === SupportedTokenContracts.TokenContract) { - deploy = TokenContract.deploy(this.wallet, sender, 'BotToken', 'BOT', 18); - tokenInstance = await deploy.getInstance(deployOpts); - token = TokenContract.at(tokenInstance.address, this.wallet); -======= const salt = this.config.tokenSalt; const deployOpts: DeployOptions = { from: sender }; let token: TokenContract | PrivateTokenContract; + let instance: ContractInstanceWithAddress; if (this.config.contract === SupportedTokenContracts.TokenContract) { deploy = TokenContract.deploy(this.wallet, sender, 'BotToken', 'BOT', 18, { salt, universalDeploy: true }); - const instance = await deploy.getInstance(); + instance = await deploy.getInstance(); token = TokenContract.at(instance.address, this.wallet); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) } else if (this.config.contract === SupportedTokenContracts.PrivateTokenContract) { // Generate keys for the contract since PrivateToken uses SinglePrivateMutable which requires keys const tokenSecretKey = Fr.random(); @@ -351,20 +277,16 @@ export class BotFactory { deployOpts.skipInitialization = false; // Register the contract with the secret key before deployment -<<<<<<< HEAD - tokenInstance = await deploy.getInstance(deployOpts); -======= - const tokenInstance = await deploy.getInstance(); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) - token = PrivateTokenContract.at(tokenInstance.address, this.wallet); - await this.wallet.registerContract(tokenInstance, PrivateTokenContract.artifact, tokenSecretKey); + instance = await deploy.getInstance(); + token = PrivateTokenContract.at(instance.address, this.wallet); + await this.wallet.registerContract(instance, PrivateTokenContract.artifact, tokenSecretKey); // The contract constructor initializes private storage vars that need the contract's own nullifier key. - deployOpts.additionalScopes = [tokenInstance.address]; + deployOpts.additionalScopes = [instance.address]; } else { throw new Error(`Unsupported token contract type: ${this.config.contract}`); } - const address = tokenInstance?.address ?? (await deploy.getInstance(deployOpts)).address; + const address = instance.address; const metadata = await this.wallet.getContractMetadata(address); if (metadata.isContractPublished) { this.log.info(`Token at ${address.toString()} already deployed`); diff --git a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts index e4a126fb775c..9bf3e96b1867 100644 --- a/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts +++ b/yarn-project/end-to-end/src/composed/ha/e2e_ha_full.test.ts @@ -280,11 +280,7 @@ describe('HA Full Setup', () => { logger.info(`Deploying contract from ${ownerAddress}`); const { receipt } = await deployer.deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }).send({ from: ownerAddress, -<<<<<<< HEAD - contractAddressSalt: new Fr(BigInt(1)), wait: { returnReceipt: true }, -======= ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }); await waitForProven(aztecNode, receipt, { @@ -402,11 +398,7 @@ describe('HA Full Setup', () => { const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); const { receipt } = await deployer.deploy([ownerAddress, 42], { salt: Fr.random() }).send({ from: ownerAddress, -<<<<<<< HEAD - contractAddressSalt: Fr.random(), wait: { returnReceipt: true }, -======= ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }); expect(receipt.blockNumber).toBeDefined(); logger.info(`Transaction mined in block ${receipt.blockNumber}`); @@ -496,83 +488,6 @@ describe('HA Full Setup', () => { logger.info('Governance voting with HA coordination and L1 verification complete'); }); -<<<<<<< HEAD -======= - it('should reload keystore via admin API and keep building blocks after swapping attesters', async () => { - logger.info('Testing reloadKeystore: swap all attesters across HA nodes'); - - const groupA = attesterAddresses.slice(0, 2); - const groupB = attesterAddresses.slice(2, 4); - - const writeKeystoreForNode = async (nodeIdx: number, attesters: string[]) => { - const ks = { - schemaVersion: 1, - validators: [ - { - attester: attesters, - feeRecipient: AztecAddress.ZERO.toString(), - coinbase: EthAddress.fromString(attesters[0]).toChecksumString(), - remoteSigner: web3SignerUrl, - publisher: [publisherAddresses[nodeIdx]], - }, - ], - }; - await writeFile(join(haKeystoreDirs[nodeIdx], 'keystore.json'), JSON.stringify(ks, null, 2)); - }; - - const verifyNodeAttesters = (nodeIdx: number, expectedAttesters: string[], label: string) => { - const vc: ValidatorClient = (haNodeServices[nodeIdx] as any).validatorClient; - const addrs = vc.getValidatorAddresses(); - expect(addrs).toHaveLength(expectedAttesters.length); - for (const expected of expectedAttesters) { - expect(addrs.some(a => a.equals(EthAddress.fromString(expected)))).toBe(true); - } - logger.info(`Node ${nodeIdx}: ${addrs.length} attesters (${label})`); - }; - - const quorum = Math.floor((COMMITTEE_SIZE * 2) / 3) + 1; - - try { - // Phase 1: Nodes 0,1,2 get attesters [A0,A1], nodes 3,4 get [A2,A3] - logger.info('Phase 1: Initial attester split'); - for (let i = 0; i < NODE_COUNT; i++) { - await writeKeystoreForNode(i, i < 3 ? groupA : groupB); - await haNodeServices[i].reloadKeystore(); - } - for (let i = 0; i < NODE_COUNT; i++) { - verifyNodeAttesters(i, i < 3 ? groupA : groupB, i < 3 ? 'group A' : 'group B'); - } - - // Phase 2: Swap — nodes 0,1,2 get [A2,A3], nodes 3,4 get [A0,A1] - logger.info('Phase 2: Swapping all attesters'); - for (let i = 0; i < NODE_COUNT; i++) { - await writeKeystoreForNode(i, i < 3 ? groupB : groupA); - await haNodeServices[i].reloadKeystore(); - } - for (let i = 0; i < NODE_COUNT; i++) { - verifyNodeAttesters(i, i < 3 ? groupB : groupA, i < 3 ? 'group B (swapped)' : 'group A (swapped)'); - } - - const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); - const receipt = await deployer.deploy([ownerAddress, 201], { salt: new Fr(201) }).send({ - from: ownerAddress, - }); - expect(receipt.receipt.blockNumber).toBeDefined(); - const [block] = await aztecNode.getCheckpointedBlocks(receipt.receipt.blockNumber!, 1); - const [cp] = await aztecNode.getCheckpoints(block!.checkpointNumber, 1, { includeAttestations: true }); - const att = (cp.attestations ?? []).filter(a => !a.signature.isEmpty()); - expect(att.length).toBeGreaterThanOrEqual(quorum); - logger.info(`Phase 2: block ${receipt.receipt.blockNumber}, ${att.length} attestations (quorum ${quorum})`); - } finally { - // Restore each node's saved initial keystore so subsequent tests see original state - for (let i = 0; i < NODE_COUNT; i++) { - await writeFile(join(haKeystoreDirs[i], 'keystore.json'), initialKeystoreJsons[i]); - await haNodeServices[i].reloadKeystore(); - } - } - }); - ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) // NOTE: this test needs to run last it('should distribute work across multiple HA nodes', async () => { logger.info('Testing HA resilience by killing nodes after they produce blocks'); @@ -598,11 +513,7 @@ describe('HA Full Setup', () => { const deployer = new ContractDeployer(StatefulTestContractArtifact, wallet); const { receipt } = await deployer.deploy([ownerAddress, i + 100], { salt: new Fr(BigInt(i + 100)) }).send({ from: ownerAddress, -<<<<<<< HEAD - contractAddressSalt: new Fr(BigInt(i + 100)), wait: { returnReceipt: true }, -======= ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }); expect(receipt.blockNumber).toBeDefined(); diff --git a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts index ce21efa245d6..21b81ea4ebc1 100644 --- a/yarn-project/end-to-end/src/e2e_contract_updates.test.ts +++ b/yarn-project/end-to-end/src/e2e_contract_updates.test.ts @@ -101,17 +101,11 @@ describe('e2e_contract_updates', () => { initialFundedAccounts, })); -<<<<<<< HEAD ({ receipt: { contract, instance }, - } = await UpdatableContract.deploy(wallet, constructorArgs[0]).send({ + } = await UpdatableContract.deploy(wallet, constructorArgs[0], { salt }).send({ from: defaultAccountAddress, - contractAddressSalt: salt, wait: { returnReceipt: true }, -======= - ({ contract, instance } = await UpdatableContract.deploy(wallet, constructorArgs[0], { salt }).send({ - from: defaultAccountAddress, ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) })); const registerMethod = await publishContractClass(wallet, UpdatedContractArtifact); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts index 95b0ae287b21..41c2ac527445 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts @@ -35,19 +35,11 @@ describe('e2e_deploy_contract legacy', () => { salt, deployer: defaultAccountAddress, }); -<<<<<<< HEAD - const deployer = new ContractDeployer(TestContractArtifact, wallet); - const { receipt } = await deployer - .deploy() - .send({ from: defaultAccountAddress, contractAddressSalt: salt, wait: { returnReceipt: true } }); - expect(receipt.contract.address).toEqual(deploymentData.address); -======= const contractDeployer = new ContractDeployer(TestContractArtifact, wallet); const { contract } = await contractDeployer .deploy([], { salt, deployer: defaultAccountAddress }) .send({ from: defaultAccountAddress }); expect(contract.address).toEqual(deploymentData.address); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) const { instance, isContractPublished } = await wallet.getContractMetadata(deploymentData.address); expect(instance).toBeDefined(); expect(isContractPublished).toBe(true); @@ -73,17 +65,11 @@ describe('e2e_deploy_contract legacy', () => { for (let index = 0; index < 2; index++) { logger.info(`Deploying contract ${index + 1}...`); -<<<<<<< HEAD - const { receipt } = await deployer - .deploy() - .send({ from: defaultAccountAddress, contractAddressSalt: Fr.random(), wait: { returnReceipt: true } }); -======= const { contract: deployed } = await contractDeployer .deploy([], { salt: Fr.random() }) .send({ from: defaultAccountAddress }); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) logger.info(`Sending TX to contract ${index + 1}...`); - await receipt.contract.methods + await deployed.methods .get_master_incoming_viewing_public_key(defaultAccountAddress) .send({ from: defaultAccountAddress }); } diff --git a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts index 983a27506e7f..df1e94881f27 100644 --- a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts @@ -193,11 +193,7 @@ describe('e2e_fees account_init', () => { skipClassPublication: true, skipInstancePublication: true, skipInitialization: false, -<<<<<<< HEAD - universalDeploy: true, wait: { returnReceipt: true }, -======= ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) }); // alice paid in Fee Juice diff --git a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts index 15b3d1387852..650e0387b710 100644 --- a/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts +++ b/yarn-project/end-to-end/src/e2e_multi_validator/e2e_multi_validator_node.test.ts @@ -113,17 +113,9 @@ describe('e2e_multi_validator_node', () => { const deployer = new ContractDeployer(artifact, wallet); logger.info(`Deploying contract from ${ownerAddress}`); -<<<<<<< HEAD - const { receipt: tx } = await deployer.deploy(ownerAddress, 1).send({ - from: ownerAddress, - contractAddressSalt: new Fr(BigInt(1)), - wait: { returnReceipt: true }, - }); -======= const { receipt: tx } = await deployer .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) - .send({ from: ownerAddress }); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) + .send({ from: ownerAddress, wait: { returnReceipt: true } }); await waitForProven(aztecNode, tx, { provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, }); @@ -178,17 +170,9 @@ describe('e2e_multi_validator_node', () => { // new aztec transaction logger.info(`Deploying contract from ${ownerAddress}`); const deployer = new ContractDeployer(artifact, wallet); -<<<<<<< HEAD - const { receipt: tx } = await deployer.deploy(ownerAddress, 1).send({ - from: ownerAddress, - contractAddressSalt: new Fr(BigInt(1)), - wait: { returnReceipt: true }, - }); -======= const { receipt: tx } = await deployer .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) - .send({ from: ownerAddress }); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) + .send({ from: ownerAddress, wait: { returnReceipt: true } }); await waitForProven(aztecNode, tx, { provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, }); diff --git a/yarn-project/end-to-end/src/e2e_simple.test.ts b/yarn-project/end-to-end/src/e2e_simple.test.ts index 2d625b32e074..add93c0dde2b 100644 --- a/yarn-project/end-to-end/src/e2e_simple.test.ts +++ b/yarn-project/end-to-end/src/e2e_simple.test.ts @@ -71,17 +71,9 @@ describe('e2e_simple', () => { it('deploys a contract', async () => { const deployer = new ContractDeployer(artifact, wallet); -<<<<<<< HEAD - const { receipt: txReceipt } = await deployer.deploy(ownerAddress, 1).send({ - from: ownerAddress, - contractAddressSalt: new Fr(BigInt(1)), - wait: { returnReceipt: true }, - }); -======= const { receipt: txReceipt } = await deployer .deploy([ownerAddress, 1], { salt: new Fr(BigInt(1)) }) - .send({ from: ownerAddress }); ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) + .send({ from: ownerAddress, wait: { returnReceipt: true } }); await waitForProven(aztecNode, txReceipt, { provenTimeout: (config.aztecProofSubmissionEpochs + 1) * config.aztecEpochDuration * config.aztecSlotDuration, }); diff --git a/yarn-project/end-to-end/src/fixtures/setup.ts b/yarn-project/end-to-end/src/fixtures/setup.ts index d2b307c257b0..136b725ba9fc 100644 --- a/yarn-project/end-to-end/src/fixtures/setup.ts +++ b/yarn-project/end-to-end/src/fixtures/setup.ts @@ -7,11 +7,8 @@ import { BatchCall, type ContractFunctionInteraction, type ContractMethod, -<<<<<<< HEAD -======= type DeployOptions, type InteractionWaitOptions, ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) getContractClassFromArtifact, waitForProven, } from '@aztec/aztec.js/contracts'; @@ -870,11 +867,7 @@ export async function ensureAccountContractsPublished(wallet: Wallet, accountsTo * Returns deployed account data that can be used by tests. */ export const deployAccounts = -<<<<<<< HEAD - (numberOfAccounts: number, logger: Logger) => -======= (numberOfAccounts: number, logger: Logger, deployOptions?: Partial>) => ->>>>>>> 01a6f5411b (fix: better DeployMethod (#22985)) async ({ wallet, initialFundedAccounts }: { wallet: TestWallet; initialFundedAccounts: InitialAccountData[] }) => { if (initialFundedAccounts.length < numberOfAccounts) { throw new Error(`Cannot deploy more than ${initialFundedAccounts.length} initial accounts.`); From fa2a24a1a0726460412f6ce7078bc5bada9ba1f4 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 06:31:07 +0000 Subject: [PATCH 09/30] fix: restore DeployInteractionWaitOptions for v4-next returnReceipt API v4-next-staging keeps DeployTxReceipt / DeployWaitOptions and the 'wait: { returnReceipt: true }' API. The upstream PR removed DeployInteractionWaitOptions and tightened the generic constraint to extends InteractionWaitOptions. Switch DeployOptions, DeployReturn, convertDeployOptionsToSendOptions, send overloads, and the deployAccounts parameter type back to DeployInteractionWaitOptions so the v4-next-only returnReceipt callers keep type-checking. --- docs/examples/ts/aave_bridge/index.ts | 419 ------------ docs/examples/ts/example_swap/index.ts | 594 ------------------ .../aztec.js/src/contract/deploy_method.ts | 11 +- .../src/wallet/deploy_account_method.ts | 6 +- yarn-project/end-to-end/src/fixtures/setup.ts | 5 +- 5 files changed, 11 insertions(+), 1024 deletions(-) delete mode 100644 docs/examples/ts/aave_bridge/index.ts delete mode 100644 docs/examples/ts/example_swap/index.ts diff --git a/docs/examples/ts/aave_bridge/index.ts b/docs/examples/ts/aave_bridge/index.ts deleted file mode 100644 index 01f618b05d67..000000000000 --- a/docs/examples/ts/aave_bridge/index.ts +++ /dev/null @@ -1,419 +0,0 @@ -import { getInitialTestAccountsData } from "@aztec/accounts/testing"; -import { AztecAddress, EthAddress } from "@aztec/aztec.js/addresses"; -import { SetPublicAuthwitContractInteraction } from "@aztec/aztec.js/authorization"; -import { Fr } from "@aztec/aztec.js/fields"; -import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node"; -import { createExtendedL1Client } from "@aztec/ethereum/client"; -import { deployL1Contract } from "@aztec/ethereum/deploy-l1-contract"; -import { sha256ToField } from "@aztec/foundation/crypto/sha256"; -import { - computeL2ToL1MessageHash, - computeSecretHash, -} from "@aztec/stdlib/hash"; -import { computeL2ToL1MembershipWitness } from "@aztec/stdlib/messaging"; -import { EmbeddedWallet } from "@aztec/wallets/embedded"; -import { decodeEventLog, pad, toFunctionSelector } from "@aztec/viem"; -import { foundry } from "@aztec/viem/chains"; -import AavePortal from "../../../target/solidity/aave_bridge/AavePortal.sol/AavePortal.json" with { type: "json" }; -import MockERC20 from "../../../target/solidity/aave_bridge/MockERC20.sol/MockERC20.json" with { type: "json" }; -import MockAToken from "../../../target/solidity/aave_bridge/MockAToken.sol/MockAToken.json" with { type: "json" }; -import MockAavePool from "../../../target/solidity/aave_bridge/MockAavePool.sol/MockAavePool.json" with { type: "json" }; -import { TokenContract } from "@aztec/noir-contracts.js/Token"; -import { AaveBridgeContract } from "./artifacts/AaveBridge.js"; - -// docs:start:setup -// Setup L1 client using anvil's default mnemonic -const MNEMONIC = "test test test test test test test test test test test junk"; -const l1Client = createExtendedL1Client( - [process.env.ETHEREUM_HOST ?? "http://localhost:8545"], - MNEMONIC, -); - -// Setup L2 using Aztec's local network -console.log("Setting up L2...\n"); -const node = createAztecNodeClient( - process.env.AZTEC_NODE_URL ?? "http://localhost:8080", -); -await waitForNode(node); -const aztecWallet = await EmbeddedWallet.create(node, { ephemeral: true }); -const [accData] = await getInitialTestAccountsData(); -const account = await aztecWallet.createSchnorrAccount( - accData.secret, - accData.salt, - accData.signingKey, -); -console.log(`Account: ${account.address.toString()}\n`); - -// Get node info -const nodeInfo = await node.getNodeInfo(); -const registryAddress = nodeInfo.l1ContractAddresses.registryAddress.toString(); -const inboxAddress = nodeInfo.l1ContractAddresses.inboxAddress.toString(); -// docs:end:setup - -// docs:start:deploy_l1 -console.log("Deploying L1 contracts...\n"); - -// Deploy MockERC20 (underlying token, e.g. DAI) -const { address: underlyingAddress } = await deployL1Contract( - l1Client, - MockERC20.abi, - MockERC20.bytecode.object as `0x${string}`, - ["Mock DAI", "mDAI"], -); - -// Deploy MockAToken (Aave's yield-bearing token) -const { address: aTokenAddress } = await deployL1Contract( - l1Client, - MockAToken.abi, - MockAToken.bytecode.object as `0x${string}`, - ["Aave Mock DAI", "amDAI"], -); - -// Deploy MockAavePool with 10% yield (1000 basis points) -const { address: poolAddress } = await deployL1Contract( - l1Client, - MockAavePool.abi, - MockAavePool.bytecode.object as `0x${string}`, - [underlyingAddress.toString(), aTokenAddress.toString(), 1000n], -); - -// Deploy AavePortal -const { address: portalAddress } = await deployL1Contract( - l1Client, - AavePortal.abi, - AavePortal.bytecode.object as `0x${string}`, -); - -console.log(`MockERC20 (DAI): ${underlyingAddress}`); -console.log(`MockAToken (aDAI): ${aTokenAddress}`); -console.log(`MockAavePool: ${poolAddress}`); -console.log(`AavePortal: ${portalAddress}\n`); -// docs:end:deploy_l1 - -// docs:start:deploy_l2 -console.log("Deploying L2 contracts...\n"); - -// Deploy the Token contract on L2 (this is the standard Aztec token) -const { contract: l2Token } = await TokenContract.deploy( - aztecWallet, - account.address, // admin - "Bridged DAI", - "bDAI", - 18, -).send({ from: account.address }); - -// Deploy the AaveBridge on L2 -const { contract: l2Bridge } = await AaveBridgeContract.deploy( - aztecWallet, - l2Token.address, - EthAddress.fromString(portalAddress.toString()), -).send({ from: account.address }); - -console.log(`L2 Token: ${l2Token.address.toString()}`); -console.log(`L2 Bridge: ${l2Bridge.address.toString()}\n`); -// docs:end:deploy_l2 - -// docs:start:initialize -console.log("Initializing contracts..."); - -// Initialize the L1 portal -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const initHash = await l1Client.writeContract({ - address: portalAddress.toString() as `0x${string}`, - abi: AavePortal.abi, - functionName: "initialize", - args: [ - registryAddress, - underlyingAddress.toString(), - aTokenAddress.toString(), - poolAddress.toString(), - l2Bridge.address.toString(), - ], -}); -await l1Client.waitForTransactionReceipt({ hash: initHash }); - -// Set the bridge as a minter on the L2 token so it can mint when claiming -await l2Token.methods - .set_minter(l2Bridge.address, true) - .send({ from: account.address }); - -console.log("All contracts initialized\n"); -// docs:end:initialize - -// docs:start:fund_user -// Pre-fund the portal with L1 tokens and mint L2 tokens to the user -// In a real scenario, tokens would already exist on L2 from a prior bridge -console.log("Funding user with tokens on L2..."); - -const depositAmount = 1000n * 10n ** 18n; // 1000 DAI - -// Mint underlying tokens on L1 -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const mintHash = await l1Client.writeContract({ - address: underlyingAddress.toString() as `0x${string}`, - abi: MockERC20.abi, - functionName: "mint", - args: [portalAddress.toString(), depositAmount], -}); -await l1Client.waitForTransactionReceipt({ hash: mintHash }); - -// Also mint tokens directly to the user on L2 (admin mints for simplicity) -await l2Token.methods - .mint_to_public(account.address, depositAmount) - .send({ from: account.address }); - -console.log(`User funded with ${depositAmount / 10n ** 18n} tokens on L2\n`); -// docs:end:fund_user - -// docs:start:mine_blocks -// On the local network, L2 blocks are only produced when transactions are submitted. -// L1-to-L2 messages require 2 L2 blocks before they can be consumed, so we deploy -// two dummy contracts (with random salts for unique addresses) to force block production. -async function mine2Blocks( - aztecWallet: EmbeddedWallet, - accountAddress: AztecAddress, -) { - await AaveBridgeContract.deploy( - aztecWallet, - accountAddress, - EthAddress.ZERO, - ).send({ - from: accountAddress, - }); - await AaveBridgeContract.deploy( - aztecWallet, - accountAddress, - EthAddress.ZERO, - ).send({ - from: accountAddress, - }); -} -// docs:end:mine_blocks - -// docs:start:deposit_to_aave -// ============================================================ -// STEP 1: Deposit to Aave (L2 -> L1 flow) -// ============================================================ -console.log("=== Depositing to Aave ===\n"); - -const amountToDeposit = 500n * 10n ** 18n; // 500 DAI - -// Create authwit for the bridge to burn tokens on our behalf. -// The bridge calls Token::burn_public(user, amount, nonce), where msg_sender -// is the bridge, so the token contract requires a public authwit. -const burnNonce = Fr.random(); -const burnAuthwit = await SetPublicAuthwitContractInteraction.create( - aztecWallet, - account.address, - { - caller: l2Bridge.address, - action: l2Token.methods.burn_public( - account.address, - amountToDeposit, - burnNonce, - ), - }, - true, -); -await burnAuthwit.send(); - -// On L2: burn tokens and send L2->L1 message. -// exit_to_l1_public sends tokens to the portal as the L1 recipient, -// and caller_on_l1 is set to ZERO so anyone can relay the message. -const { receipt: exitReceipt } = await l2Bridge.methods - .exit_to_l1_public( - EthAddress.fromString(portalAddress.toString()), // recipient on L1 (the portal itself) - amountToDeposit, - EthAddress.ZERO, // caller_on_l1: anyone can relay - burnNonce, // authwit nonce authorizing the bridge to burn on our behalf - ) - .send({ from: account.address }); - -console.log(`Exit sent (block: ${exitReceipt.blockNumber})`); -// docs:end:deposit_to_aave - -// docs:start:get_deposit_witness -// Compute the L2->L1 content hash for the withdrawal witness. -// This must match what the L1 portal reconstructs via abi.encodeWithSignature. -// toFunctionSelector computes keccak256 of the signature and takes the first 4 bytes. -const portalEthAddress = EthAddress.fromString(portalAddress.toString()); -const withdrawContent = sha256ToField([ - Buffer.from( - toFunctionSelector("withdraw(address,uint256,address)").substring(2), - "hex", - ), - portalEthAddress.toBuffer32(), - new Fr(amountToDeposit).toBuffer(), - EthAddress.ZERO.toBuffer32(), -]); - -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const version = (await l1Client.readContract({ - address: portalAddress.toString() as `0x${string}`, - abi: AavePortal.abi, - functionName: "rollupVersion", -})) as bigint; - -const msgLeaf = computeL2ToL1MessageHash({ - l2Sender: l2Bridge.address, - l1Recipient: portalEthAddress, - content: withdrawContent, - rollupVersion: new Fr(version), - chainId: new Fr(foundry.id), -}); - -// Wait for the block to be proven -if (!exitReceipt.blockNumber) { - throw new Error("Exit transaction was not included in a block"); -} -const exitBlockNumber = exitReceipt.blockNumber; -console.log("Waiting for block to be proven..."); -let provenBlockNumber = await node.getBlockNumber("proven"); -while (provenBlockNumber < exitBlockNumber) { - console.log( - ` Waiting... (proven: ${provenBlockNumber}, needed: ${exitBlockNumber})`, - ); - await new Promise((resolve) => setTimeout(resolve, 10000)); - provenBlockNumber = await node.getBlockNumber("proven"); -} -console.log("Block proven!\n"); - -// Compute the membership witness using the message hash and the L2 tx hash -const witness = await computeL2ToL1MembershipWitness( - node, - msgLeaf, - exitReceipt.txHash, -); -const epoch = witness!.epochNumber; - -const siblingPathHex = witness!.siblingPath - .toBufferArray() - .map((buf: Buffer) => `0x${buf.toString("hex")}` as `0x${string}`); -// docs:end:get_deposit_witness - -// docs:start:execute_deposit_l1 -// On L1: consume the outbox message and deposit into Aave -console.log("Depositing into Aave on L1..."); -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const depositToAaveHash = await l1Client.writeContract({ - address: portalAddress.toString() as `0x${string}`, - abi: AavePortal.abi, - functionName: "depositToAave", - args: [ - portalAddress.toString(), // recipient (matches L2 exit) - amountToDeposit, - false, // withCaller = false (matches caller_on_l1 = address(0)) - BigInt(epoch), - BigInt(witness!.leafIndex), - siblingPathHex, - ], -}); -await l1Client.waitForTransactionReceipt({ hash: depositToAaveHash }); -console.log("Tokens deposited into Aave!\n"); -// docs:end:execute_deposit_l1 - -// docs:start:claim_from_aave_l1 -// ============================================================ -// STEP 2: Claim from Aave with yield (L1 -> L2 flow) -// ============================================================ -console.log("=== Claiming from Aave (with yield) ===\n"); - -const secret = Fr.random(); -const secretHash = await computeSecretHash(secret); - -// On L1: withdraw from Aave and send L1->L2 message -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const claimHash = await l1Client.writeContract({ - address: portalAddress.toString() as `0x${string}`, - abi: AavePortal.abi, - functionName: "claimFromAavePublic", - args: [ - amountToDeposit, // aToken amount to withdraw - pad(account.address.toString() as `0x${string}`, { dir: "left", size: 32 }), // L2 recipient - pad(secretHash.toString() as `0x${string}`, { dir: "left", size: 32 }), - ], -}); -const claimReceipt = await l1Client.waitForTransactionReceipt({ - hash: claimHash, -}); -console.log("Aave withdrawal complete, L1->L2 message sent"); -// docs:end:claim_from_aave_l1 - -// docs:start:get_claim_leaf_index -// Extract the message leaf index from the MessageSent event -const INBOX_ABI = [ - { - type: "event", - name: "MessageSent", - inputs: [ - { name: "checkpointNumber", type: "uint256", indexed: true }, - { name: "index", type: "uint256", indexed: false }, - { name: "hash", type: "bytes32", indexed: true }, - { name: "rollingHash", type: "bytes16", indexed: false }, - ], - }, -] as const; - -const messageSentLogs = claimReceipt.logs - .filter((log) => log.address.toLowerCase() === inboxAddress.toLowerCase()) - .map((log: any) => { - try { - const decoded = decodeEventLog({ - abi: INBOX_ABI, - data: log.data, - topics: log.topics, - }); - return { log, decoded }; - } catch { - return null; - } - }) - .filter( - (item): item is { log: any; decoded: any } => - item !== null && (item.decoded as any).eventName === "MessageSent", - ); - -const messageLeafIndex = new Fr(messageSentLogs[0].decoded.args.index); -console.log(`Message leaf index: ${messageLeafIndex}\n`); -// docs:end:get_claim_leaf_index - -// docs:start:claim_on_l2 -// Mine blocks so the L1->L2 message is available -await mine2Blocks(aztecWallet, account.address); - -// The mock Aave pool returns 10% yield, so 500 DAI becomes 550 DAI -const expectedWithYield = amountToDeposit + (amountToDeposit * 1000n) / 10000n; -console.log( - `Expected amount with yield: ${expectedWithYield / 10n ** 18n} tokens`, -); - -// On L2: consume the L1->L2 message and mint tokens (with yield) -console.log("Claiming tokens on L2..."); -await l2Bridge.methods - .claim_public(account.address, expectedWithYield, secret, messageLeafIndex) - .send({ from: account.address }); -console.log("Tokens claimed on L2!\n"); -// docs:end:claim_on_l2 - -// docs:start:verify -// Verify the user's balance includes yield -console.log("=== Verifying balances ===\n"); - -const { result: finalBalance } = await l2Token.methods - .balance_of_public(account.address) - .simulate({ from: account.address }); - -const initialRemaining = depositAmount - amountToDeposit; // 500 DAI not deposited -const expectedFinal = initialRemaining + expectedWithYield; // 500 + 550 = 1050 DAI - -console.log(`Initial deposit: ${depositAmount / 10n ** 18n} tokens`); -console.log(`Deposited to Aave: ${amountToDeposit / 10n ** 18n} tokens`); -console.log( - `Yield earned (10%): ${(expectedWithYield - amountToDeposit) / 10n ** 18n} tokens`, -); -console.log(`Expected balance: ${expectedFinal / 10n ** 18n} tokens`); -console.log(`Actual balance: ${finalBalance / 10n ** 18n} tokens`); -console.log( - `\nYield earned successfully: ${finalBalance >= expectedFinal ? "YES" : "NO"}`, -); -// docs:end:verify diff --git a/docs/examples/ts/example_swap/index.ts b/docs/examples/ts/example_swap/index.ts deleted file mode 100644 index 883c120c5bad..000000000000 --- a/docs/examples/ts/example_swap/index.ts +++ /dev/null @@ -1,594 +0,0 @@ -// docs:start:setup -import { getInitialTestAccountsData } from "@aztec/accounts/testing"; -import { AztecAddress, EthAddress } from "@aztec/aztec.js/addresses"; -import { SetPublicAuthwitContractInteraction } from "@aztec/aztec.js/authorization"; -import { Fr } from "@aztec/aztec.js/fields"; -import { createAztecNodeClient, waitForNode } from "@aztec/aztec.js/node"; -import { createExtendedL1Client } from "@aztec/ethereum/client"; -import { deployL1Contract } from "@aztec/ethereum/deploy-l1-contract"; -import { sha256ToField } from "@aztec/foundation/crypto/sha256"; -import { TokenContract } from "@aztec/noir-contracts.js/Token"; -import { TokenBridgeContract } from "@aztec/noir-contracts.js/TokenBridge"; -import { - computeL2ToL1MessageHash, - computeSecretHash, -} from "@aztec/stdlib/hash"; -import { computeL2ToL1MembershipWitness } from "@aztec/stdlib/messaging"; -import { decodeEventLog, encodeFunctionData, pad } from "@aztec/viem"; -import { EmbeddedWallet } from "@aztec/wallets/embedded"; -import { foundry } from "@aztec/viem/chains"; -import ExampleERC20 from "../../../target/solidity/example_swap/ExampleERC20.sol/ExampleERC20.json" with { type: "json" }; -import ExampleTokenPortal from "../../../target/solidity/example_swap/ExampleTokenPortal.sol/ExampleTokenPortal.json" with { type: "json" }; -import ExampleUniswapPortal from "../../../target/solidity/example_swap/ExampleUniswapPortal.sol/ExampleUniswapPortal.json" with { type: "json" }; -import { ExampleUniswapContract } from "./artifacts/ExampleUniswap.js"; - -// Setup L1 client -const MNEMONIC = "test test test test test test test test test test test junk"; -const l1RpcUrl = process.env.ETHEREUM_HOST ?? "http://localhost:8545"; -const l1Client = createExtendedL1Client([l1RpcUrl], MNEMONIC); -const ownerEthAddress = l1Client.account.address; - -// Setup L2 client -console.log("Setting up L2...\n"); -const nodeUrl = process.env.AZTEC_NODE_URL ?? "http://localhost:8080"; -const node = createAztecNodeClient(nodeUrl); -await waitForNode(node); -const wallet = await EmbeddedWallet.create(node, { ephemeral: true }); -const [accData] = await getInitialTestAccountsData(); -const account = await wallet.createSchnorrAccount( - accData.secret, - accData.salt, - accData.signingKey, -); -console.log(`Account: ${account.address.toString()}\n`); - -const nodeInfo = await node.getNodeInfo(); -const registryAddress = nodeInfo.l1ContractAddresses.registryAddress.toString(); -const inboxAddress = nodeInfo.l1ContractAddresses.inboxAddress.toString(); -// docs:end:setup - -// docs:start:deploy_l1 -console.log("Deploying L1 contracts...\n"); - -// Deploy two ERC20 tokens: WETH (input) and DAI (output) -const { address: wethAddress } = await deployL1Contract( - l1Client, - ExampleERC20.abi, - ExampleERC20.bytecode.object as `0x${string}`, - ["Wrapped Ether", "WETH"], -); - -const { address: daiAddress } = await deployL1Contract( - l1Client, - ExampleERC20.abi, - ExampleERC20.bytecode.object as `0x${string}`, - ["Dai Stablecoin", "DAI"], -); - -// Deploy two token portals (one per token) -const { address: wethPortalAddress } = await deployL1Contract( - l1Client, - ExampleTokenPortal.abi, - ExampleTokenPortal.bytecode.object as `0x${string}`, -); - -const { address: daiPortalAddress } = await deployL1Contract( - l1Client, - ExampleTokenPortal.abi, - ExampleTokenPortal.bytecode.object as `0x${string}`, -); - -// Deploy the uniswap portal -const { address: uniswapPortalAddress } = await deployL1Contract( - l1Client, - ExampleUniswapPortal.abi, - ExampleUniswapPortal.bytecode.object as `0x${string}`, -); - -console.log(`WETH: ${wethAddress}`); -console.log(`DAI: ${daiAddress}`); -console.log(`WETH Portal: ${wethPortalAddress}`); -console.log(`DAI Portal: ${daiPortalAddress}`); -console.log(`Uniswap Portal: ${uniswapPortalAddress}\n`); -// docs:end:deploy_l1 - -// docs:start:deploy_l2 -console.log("Deploying L2 contracts...\n"); - -// Deploy L2 tokens (using the standard TokenContract from @aztec/noir-contracts.js) -const { contract: l2Weth } = await TokenContract.deploy( - wallet, - account.address, - "Wrapped Ether", - "WETH", - 18, -).send({ from: account.address }); - -const { contract: l2Dai } = await TokenContract.deploy( - wallet, - account.address, - "Dai Stablecoin", - "DAI", - 18, -).send({ from: account.address }); - -// Deploy L2 token bridges -const { contract: l2WethBridge } = await TokenBridgeContract.deploy( - wallet, - l2Weth.address, - wethPortalAddress, -).send({ from: account.address }); - -const { contract: l2DaiBridge } = await TokenBridgeContract.deploy( - wallet, - l2Dai.address, - daiPortalAddress, -).send({ from: account.address }); - -// Deploy L2 uniswap contract -const { contract: l2Uniswap } = await ExampleUniswapContract.deploy( - wallet, - EthAddress.fromString(uniswapPortalAddress.toString()), -).send({ from: account.address }); - -console.log(`L2 WETH: ${l2Weth.address}`); -console.log(`L2 DAI: ${l2Dai.address}`); -console.log(`L2 WETH Bridge: ${l2WethBridge.address}`); -console.log(`L2 DAI Bridge: ${l2DaiBridge.address}`); -console.log(`L2 Uniswap: ${l2Uniswap.address}\n`); -// docs:end:deploy_l2 - -// docs:start:initialize -console.log("Initializing contracts...\n"); - -// Make bridges minters on their respective tokens -await l2Weth.methods - .set_minter(l2WethBridge.address, true) - .send({ from: account.address }); -await l2Dai.methods - .set_minter(l2DaiBridge.address, true) - .send({ from: account.address }); - -// Initialize L1 portals with registry, underlying token, and L2 bridge addresses -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const initWethPortal = await l1Client.writeContract({ - address: wethPortalAddress.toString() as `0x${string}`, - abi: ExampleTokenPortal.abi, - functionName: "initialize", - args: [ - registryAddress, - wethAddress.toString(), - l2WethBridge.address.toString(), - ], -}); -await l1Client.waitForTransactionReceipt({ hash: initWethPortal }); - -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const initDaiPortal = await l1Client.writeContract({ - address: daiPortalAddress.toString() as `0x${string}`, - abi: ExampleTokenPortal.abi, - functionName: "initialize", - args: [ - registryAddress, - daiAddress.toString(), - l2DaiBridge.address.toString(), - ], -}); -await l1Client.waitForTransactionReceipt({ hash: initDaiPortal }); - -// Initialize uniswap portal -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const initUniswapPortal = await l1Client.writeContract({ - address: uniswapPortalAddress.toString() as `0x${string}`, - abi: ExampleUniswapPortal.abi, - functionName: "initialize", - args: [registryAddress, l2Uniswap.address.toString()], -}); -await l1Client.waitForTransactionReceipt({ hash: initUniswapPortal }); - -console.log("All contracts initialized\n"); -// docs:end:initialize - -// docs:start:fund -console.log("Funding accounts...\n"); - -const SWAP_AMOUNT = 100n * 10n ** 18n; // 100 tokens - -// Mint WETH on L1 for the user -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const mintWethHash = await l1Client.writeContract({ - address: wethAddress.toString() as `0x${string}`, - abi: ExampleERC20.abi, - functionName: "mint", - args: [ownerEthAddress, SWAP_AMOUNT], -}); -await l1Client.waitForTransactionReceipt({ hash: mintWethHash }); - -// Pre-fund the uniswap portal with DAI (for the mock 1:1 swap) -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const mintDaiHash = await l1Client.writeContract({ - address: daiAddress.toString() as `0x${string}`, - abi: ExampleERC20.abi, - functionName: "mint", - args: [uniswapPortalAddress.toString(), SWAP_AMOUNT * 2n], -}); -await l1Client.waitForTransactionReceipt({ hash: mintDaiHash }); - -console.log(`Minted ${SWAP_AMOUNT} WETH to user`); -console.log(`Pre-funded uniswap portal with ${SWAP_AMOUNT * 2n} DAI\n`); -// docs:end:fund - -// docs:start:deposit_to_l2 -console.log("Depositing WETH to Aztec (L1 -> L2)...\n"); - -const depositSecret = Fr.random(); -const depositSecretHash = await computeSecretHash(depositSecret); - -// Approve WETH portal to take tokens -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const approveHash = await l1Client.writeContract({ - address: wethAddress.toString() as `0x${string}`, - abi: ExampleERC20.abi, - functionName: "approve", - args: [wethPortalAddress.toString(), SWAP_AMOUNT], -}); -await l1Client.waitForTransactionReceipt({ hash: approveHash }); - -// Deposit to Aztec publicly -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const depositHash = await l1Client.writeContract({ - address: wethPortalAddress.toString() as `0x${string}`, - abi: ExampleTokenPortal.abi, - functionName: "depositToAztecPublic", - args: [ - account.address.toString(), - SWAP_AMOUNT, - pad(depositSecretHash.toString() as `0x${string}`, { - dir: "left", - size: 32, - }), - ], -}); -const depositReceipt = await l1Client.waitForTransactionReceipt({ - hash: depositHash, -}); - -// Extract message leaf index from Inbox event -const INBOX_ABI = [ - { - type: "event", - name: "MessageSent", - inputs: [ - { name: "checkpointNumber", type: "uint256", indexed: true }, - { name: "index", type: "uint256", indexed: false }, - { name: "hash", type: "bytes32", indexed: true }, - { name: "rollingHash", type: "bytes16", indexed: false }, - ], - }, -] as const; - -const messageSentLogs = depositReceipt.logs - .filter((log) => log.address.toLowerCase() === inboxAddress.toLowerCase()) - .map((log: any) => { - try { - const decoded = decodeEventLog({ - abi: INBOX_ABI, - data: log.data, - topics: log.topics, - }); - return { log, decoded }; - } catch { - return null; - } - }) - .filter( - (item): item is { log: any; decoded: any } => - item !== null && (item.decoded as any).eventName === "MessageSent", - ); - -if (messageSentLogs.length === 0) { - throw new Error("No MessageSent events found in deposit transaction"); -} -const depositLeafIndex = new Fr(messageSentLogs[0].decoded.args.index); -console.log(`Deposit message leaf index: ${depositLeafIndex}\n`); -// docs:end:deposit_to_l2 - -// docs:start:mine_blocks -// Utility: mine 2 blocks (required before L1->L2 messages can be consumed) -async function mine2Blocks( - wallet: EmbeddedWallet, - accountAddress: AztecAddress, -) { - await TokenContract.deploy(wallet, accountAddress, "T", "T", 18).send({ - from: accountAddress, - }); - await TokenContract.deploy(wallet, accountAddress, "T", "T", 18).send({ - from: accountAddress, - }); -} -// docs:end:mine_blocks - -// docs:start:claim_on_l2 -console.log("Claiming WETH on L2...\n"); - -await mine2Blocks(wallet, account.address); - -await l2WethBridge.methods - .claim_public(account.address, SWAP_AMOUNT, depositSecret, depositLeafIndex) - .send({ from: account.address }); - -const { result: wethBalanceBefore } = await l2Weth.methods - .balance_of_public(account.address) - .simulate({ from: account.address }); -console.log(`L2 WETH balance after claim: ${wethBalanceBefore}\n`); -if (wethBalanceBefore !== SWAP_AMOUNT) { - throw new Error( - `Expected WETH balance ${SWAP_AMOUNT}, got ${wethBalanceBefore}`, - ); -} -console.log("✓ WETH claimed successfully on L2\n"); -// docs:end:claim_on_l2 - -// docs:start:public_swap -console.log("=== PUBLIC SWAP FLOW ===\n"); -console.log("Initiating public swap on L2 (WETH -> DAI)...\n"); - -// Force L2 block production so the claim message is included in a block before the swap -await mine2Blocks(wallet, account.address); - -const swapSecret = Fr.random(); -const swapSecretHash = await computeSecretHash(swapSecret); - -// Create authwit for the uniswap contract to transfer WETH on our behalf -const transferAction = l2Weth.methods.transfer_in_public( - account.address, - l2Uniswap.address, - SWAP_AMOUNT, - 0xdeadbeefn, -); -const authwit = await SetPublicAuthwitContractInteraction.create( - wallet, - account.address, - { caller: l2Uniswap.address, action: transferAction }, - true, -); -await authwit.send(); - -// Call swap_public on the L2 uniswap contract -const { receipt: swapReceipt } = await l2Uniswap.methods - .swap_public( - account.address, - l2WethBridge.address, - SWAP_AMOUNT, - l2DaiBridge.address, - 3000n, // fee tier - 0n, // minimum output - account.address, // recipient - swapSecretHash, - ) - .send({ from: account.address }); - -console.log(`Swap tx sent (block: ${swapReceipt.blockNumber})\n`); - -// Verify WETH was spent (balance should be 0 after swap) -const { result: wethAfterSwap } = await l2Weth.methods - .balance_of_public(account.address) - .simulate({ from: account.address }); -if (wethAfterSwap !== 0n) { - throw new Error(`Expected WETH balance 0 after swap, got ${wethAfterSwap}`); -} -console.log("✓ WETH transferred to bridge for swap\n"); -// docs:end:public_swap - -// docs:start:wait_for_proof -console.log("Waiting for block to be proven...\n"); - -let provenBlockNumber = await node.getBlockNumber("proven"); -while (provenBlockNumber < swapReceipt.blockNumber!) { - console.log( - ` Waiting... (proven: ${provenBlockNumber}, needed: ${swapReceipt.blockNumber})`, - ); - await new Promise((resolve) => setTimeout(resolve, 10000)); - provenBlockNumber = await node.getBlockNumber("proven"); -} - -console.log("Block proven!\n"); -// docs:end:wait_for_proof - -// docs:start:consume_l1_messages_setup -console.log("Consuming L2->L1 messages on L1...\n"); - -// The swap generates 2 L2->L1 messages: -// 1. Token bridge exit (withdraw WETH to uniswap portal) -// 2. Uniswap swap intent - -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const portalRollupVersion = (await l1Client.readContract({ - address: wethPortalAddress.toString() as `0x${string}`, - abi: ExampleTokenPortal.abi, - functionName: "rollupVersion", -})) as bigint; - -// Compute message 1: token bridge exit -// Encode using the same approach as Solidity's abi.encodeWithSignature("withdraw(address,uint256,address)", ...) -const withdrawContentEncoded = encodeFunctionData({ - abi: [ - { - name: "withdraw", - type: "function", - inputs: [ - { name: "", type: "address" }, - { name: "", type: "uint256" }, - { name: "", type: "address" }, - ], - outputs: [], - }, - ], - args: [ - uniswapPortalAddress.toString() as `0x${string}`, - SWAP_AMOUNT, - uniswapPortalAddress.toString() as `0x${string}`, - ], -}); -const withdrawContentHash = sha256ToField([ - Buffer.from(withdrawContentEncoded.slice(2), "hex"), -]); - -// Message 1: Token bridge exit message -const exitMsgLeaf = computeL2ToL1MessageHash({ - l2Sender: l2WethBridge.address, - l1Recipient: wethPortalAddress, - content: withdrawContentHash, - rollupVersion: new Fr(portalRollupVersion), - chainId: new Fr(foundry.id), -}); -// docs:end:consume_l1_messages_setup - -// docs:start:consume_l1_messages_witnesses -const exitWitness = await computeL2ToL1MembershipWitness( - node, - exitMsgLeaf, - swapReceipt.txHash, -); -const exitSiblingPath = exitWitness!.siblingPath - .toBufferArray() - .map((buf: Buffer) => `0x${buf.toString("hex")}` as `0x${string}`); - -// Message 2: Uniswap swap intent message -// Compute using the same encoding as ExampleUniswapPortal.sol -const swapContentEncoded = encodeFunctionData({ - abi: [ - { - name: "swap_public", - type: "function", - inputs: [ - { name: "", type: "address" }, - { name: "", type: "uint256" }, - { name: "", type: "uint24" }, - { name: "", type: "address" }, - { name: "", type: "uint256" }, - { name: "", type: "bytes32" }, - { name: "", type: "bytes32" }, - ], - outputs: [], - }, - ], - args: [ - wethPortalAddress.toString() as `0x${string}`, - SWAP_AMOUNT, - 3000, - daiPortalAddress.toString() as `0x${string}`, - 0n, - account.address.toString() as `0x${string}`, - pad(swapSecretHash.toString() as `0x${string}`, { - dir: "left", - size: 32, - }), - ], -}); - -const swapContentHash = sha256ToField([ - Buffer.from(swapContentEncoded.slice(2), "hex"), -]); - -const swapMsgLeaf = computeL2ToL1MessageHash({ - l2Sender: l2Uniswap.address, - l1Recipient: uniswapPortalAddress, - content: swapContentHash, - rollupVersion: new Fr(portalRollupVersion), - chainId: new Fr(foundry.id), -}); - -const swapWitness = await computeL2ToL1MembershipWitness( - node, - swapMsgLeaf, - swapReceipt.txHash, -); -const swapSiblingPath = swapWitness!.siblingPath - .toBufferArray() - .map((buf: Buffer) => `0x${buf.toString("hex")}` as `0x${string}`); -// docs:end:consume_l1_messages_witnesses - -// docs:start:consume_l1_messages_execute -// Execute the swap on L1 (consumes both messages) -// @ts-expect-error - viem type inference doesn't work with JSON-imported ABIs -const l1SwapHash = await l1Client.writeContract({ - address: uniswapPortalAddress.toString() as `0x${string}`, - abi: ExampleUniswapPortal.abi, - functionName: "swapPublic", - args: [ - wethPortalAddress.toString(), - SWAP_AMOUNT, - 3000, - daiPortalAddress.toString(), - 0n, - account.address.toString(), - pad(swapSecretHash.toString() as `0x${string}`, { - dir: "left", - size: 32, - }), - [BigInt(exitWitness!.epochNumber), BigInt(swapWitness!.epochNumber)], - [BigInt(exitWitness!.leafIndex), BigInt(swapWitness!.leafIndex)], - [exitSiblingPath, swapSiblingPath], - ], -}); -const l1SwapReceipt = await l1Client.waitForTransactionReceipt({ - hash: l1SwapHash, -}); -console.log(`L1 swap executed! Tx: ${l1SwapHash}\n`); -// docs:end:consume_l1_messages_execute - -// docs:start:claim_output -console.log("Claiming DAI output on L2...\n"); - -// Extract the deposit message leaf index from the L1 swap receipt -const daiDepositLogs = l1SwapReceipt.logs - .filter((log) => log.address.toLowerCase() === inboxAddress.toLowerCase()) - .map((log: any) => { - try { - const decoded = decodeEventLog({ - abi: INBOX_ABI, - data: log.data, - topics: log.topics, - }); - return { log, decoded }; - } catch { - return null; - } - }) - .filter( - (item): item is { log: any; decoded: any } => - item !== null && (item.decoded as any).eventName === "MessageSent", - ); - -if (daiDepositLogs.length === 0) { - throw new Error("No MessageSent events found in L1 swap transaction"); -} -const daiDepositLeafIndex = new Fr(daiDepositLogs[0].decoded.args.index); - -// Mine blocks and claim -await mine2Blocks(wallet, account.address); - -await l2DaiBridge.methods - .claim_public(account.address, SWAP_AMOUNT, swapSecret, daiDepositLeafIndex) - .send({ from: account.address }); - -const { result: daiBalance } = await l2Dai.methods - .balance_of_public(account.address) - .simulate({ from: account.address }); - -const { result: wethBalanceAfter } = await l2Weth.methods - .balance_of_public(account.address) - .simulate({ from: account.address }); - -console.log(`L2 WETH balance: ${wethBalanceAfter}`); -console.log(`L2 DAI balance: ${daiBalance}`); - -if (wethBalanceAfter !== 0n) { - throw new Error(`Expected final WETH balance 0, got ${wethBalanceAfter}`); -} -if (daiBalance !== SWAP_AMOUNT) { - throw new Error(`Expected DAI balance ${SWAP_AMOUNT}, got ${daiBalance}`); -} -console.log("\n✓ All checks passed — public swap complete!\n"); -// docs:end:claim_output diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index 405fa3ea7404..f7f5cc546537 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -20,7 +20,6 @@ import type { ContractBase } from './contract_base.js'; import { ContractFunctionInteraction } from './contract_function_interaction.js'; import { getGasLimits } from './get_gas_limits.js'; import { - type InteractionWaitOptions, NO_FROM, NO_WAIT, type NoWait, @@ -112,7 +111,7 @@ export type DeployOptionsWithoutWait = RequestDeployOptions & /** * Extends the deployment options with the required parameters to send the transaction. */ -export type DeployOptions = DeployOptionsWithoutWait & { +export type DeployOptions = DeployOptionsWithoutWait & { /** * Options for waiting for the transaction to be mined. * - undefined (default): wait with default options and return the contract instance @@ -169,7 +168,7 @@ export type DeployResultMined = { } & OffchainOutput; /** Conditional return type for deploy based on wait options. */ -export type DeployReturn = W extends NoWait +export type DeployReturn = W extends NoWait ? TxSendResultImmediate : W extends WaitWithReturnReceipt ? TxSendResultMined> @@ -326,7 +325,7 @@ export class DeployMethod extends * @param options - Deploy options with wait parameter * @returns Send options with wait parameter */ - protected convertDeployOptionsToSendOptions( + protected convertDeployOptionsToSendOptions( options: DeployOptions, // eslint-disable-next-line jsdoc/require-jsdoc ): SendOptions { @@ -446,11 +445,11 @@ export class DeployMethod extends // Overload for when wait is not specified at all - returns the contract public override send(options: DeployOptionsWithoutWait): Promise>; // eslint-disable-next-line jsdoc/require-jsdoc - public override send( + public override send( options: DeployOptions, ): Promise>; // eslint-disable-next-line jsdoc/require-jsdoc - public override async send(options: DeployOptions): Promise { + public override async send(options: DeployOptions): Promise { this.lockDeployerFromSendOptions(options.from); const executionPayload = await this.request(options); const sendOptions = this.convertDeployOptionsToSendOptions(options); diff --git a/yarn-project/aztec.js/src/wallet/deploy_account_method.ts b/yarn-project/aztec.js/src/wallet/deploy_account_method.ts index 25669633be9b..08c40d9cc932 100644 --- a/yarn-project/aztec.js/src/wallet/deploy_account_method.ts +++ b/yarn-project/aztec.js/src/wallet/deploy_account_method.ts @@ -11,6 +11,7 @@ import type { Account } from '../account/account.js'; import type { Contract } from '../contract/contract.js'; import type { ContractBase } from '../contract/contract_base.js'; import { + type DeployInteractionWaitOptions, DeployMethod, type DeployOptions, type DeployOptionsWithoutWait, @@ -19,7 +20,6 @@ import { } from '../contract/deploy_method.js'; import { type FeePaymentMethodOption, - type InteractionWaitOptions, NO_FROM, type NoFrom, type ProfileInteractionOptions, @@ -54,7 +54,7 @@ export type RequestDeployAccountOptions = Omit & { /** * The configuration options for the send/prove methods. */ -export type DeployAccountOptions = DeployOptionsWithoutWait & { +export type DeployAccountOptions = DeployOptionsWithoutWait & { /** * Whether to wait for the transaction to be mined. * - undefined (default): wait with default options and return TxReceipt @@ -167,7 +167,7 @@ export class DeployAccountMethod exte } } - protected override convertDeployOptionsToSendOptions( + protected override convertDeployOptionsToSendOptions( options: DeployOptions, // eslint-disable-next-line jsdoc/require-jsdoc ): SendOptions { diff --git a/yarn-project/end-to-end/src/fixtures/setup.ts b/yarn-project/end-to-end/src/fixtures/setup.ts index 136b725ba9fc..3b785184226c 100644 --- a/yarn-project/end-to-end/src/fixtures/setup.ts +++ b/yarn-project/end-to-end/src/fixtures/setup.ts @@ -7,8 +7,8 @@ import { BatchCall, type ContractFunctionInteraction, type ContractMethod, + type DeployInteractionWaitOptions, type DeployOptions, - type InteractionWaitOptions, getContractClassFromArtifact, waitForProven, } from '@aztec/aztec.js/contracts'; @@ -867,7 +867,7 @@ export async function ensureAccountContractsPublished(wallet: Wallet, accountsTo * Returns deployed account data that can be used by tests. */ export const deployAccounts = - (numberOfAccounts: number, logger: Logger, deployOptions?: Partial>) => + (numberOfAccounts: number, logger: Logger, deployOptions?: Partial>) => async ({ wallet, initialFundedAccounts }: { wallet: TestWallet; initialFundedAccounts: InitialAccountData[] }) => { if (initialFundedAccounts.length < numberOfAccounts) { throw new Error(`Cannot deploy more than ${initialFundedAccounts.length} initial accounts.`); @@ -886,6 +886,7 @@ export const deployAccounts = await deployMethod.send({ from: NO_FROM, skipClassPublication: i !== 0, // Publish the contract class at most once. + ...deployOptions, }); } From bd7471f80adc1784e7cd5facaee66d470286161c Mon Sep 17 00:00:00 2001 From: thunkar Date: Fri, 8 May 2026 09:12:23 +0000 Subject: [PATCH 10/30] fine, i'll do it myself --- yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts b/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts index 6b985b3a0242..8a4e2934cbc7 100644 --- a/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts +++ b/yarn-project/end-to-end/src/devnet/e2e_smoke.test.ts @@ -255,9 +255,8 @@ describe('End-to-end tests for devnet', () => { async function advanceChainWithEmptyBlocks(wallet: TestWallet) { const [fundedAccountAddress] = await registerInitialLocalNetworkAccountsInWallet(wallet); - const { contract: test } = await TestContract.deploy(wallet).send({ + const { contract: test } = await TestContract.deploy(wallet, { universalDeploy: true }).send({ from: fundedAccountAddress, - universalDeploy: true, skipClassPublication: true, }); From b0e3c52b78be5d62d91d7ae64ccf3d1cd6f342ec Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Fri, 8 May 2026 07:22:17 -0300 Subject: [PATCH 11/30] refactor(pxe): deduplicate tx hash lookups in MessageContextService (#23075) --- .../messages/message_context_service.test.ts | 24 ++++++++- .../src/messages/message_context_service.ts | 49 ++++++++++--------- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/yarn-project/pxe/src/messages/message_context_service.test.ts b/yarn-project/pxe/src/messages/message_context_service.test.ts index 6860dc7f438c..170b25bb17a9 100644 --- a/yarn-project/pxe/src/messages/message_context_service.test.ts +++ b/yarn-project/pxe/src/messages/message_context_service.test.ts @@ -3,7 +3,7 @@ import { Fr } from '@aztec/foundation/curves/bn254'; import { BlockHash } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; import { MessageContext } from '@aztec/stdlib/logs'; -import { TxHash } from '@aztec/stdlib/tx'; +import { TxEffect, TxHash } from '@aztec/stdlib/tx'; import { mock } from 'jest-mock-extended'; @@ -123,4 +123,26 @@ describe('MessageContextService', () => { // Zero hash should not trigger getTxEffect expect(aztecNode.getTxEffect).toHaveBeenCalledTimes(3); }); + + it('deduplicates repeated tx hashes so each is fetched only once', async () => { + const txEffect = TxEffect.from({ + ...(await TxEffect.random({ numNoteHashes: 1, numNullifiers: 1 })), + }); + + aztecNode.getTxEffect.mockResolvedValue({ + l2BlockNumber: BlockNumber(anchorBlockNumber - 1), + l2BlockHash: BlockHash.random(), + txIndexInBlock: 0, + data: txEffect, + }); + + const results = await service.getMessageContextsByTxHash( + [txEffect.txHash.hash, txEffect.txHash.hash, txEffect.txHash.hash], + anchorBlockNumber, + ); + + const expected = new MessageContext(txEffect.txHash, txEffect.noteHashes, txEffect.nullifiers[0]); + expect(results).toEqual([expected, expected, expected]); + expect(aztecNode.getTxEffect).toHaveBeenCalledTimes(1); + }); }); diff --git a/yarn-project/pxe/src/messages/message_context_service.ts b/yarn-project/pxe/src/messages/message_context_service.ts index d5c269408f8b..5a6a529fc1c8 100644 --- a/yarn-project/pxe/src/messages/message_context_service.ts +++ b/yarn-project/pxe/src/messages/message_context_service.ts @@ -1,7 +1,8 @@ +import { uniqueBy } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/curves/bn254'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; import { MessageContext } from '@aztec/stdlib/logs'; -import { TxHash } from '@aztec/stdlib/tx'; +import { type IndexedTxEffect, TxHash } from '@aztec/stdlib/tx'; /** Resolves transaction hashes into the context needed to process messages. */ export class MessageContextService { @@ -14,31 +15,31 @@ export class MessageContextService { * process messages that originated from that transaction. Returns `null` for tx hashes that are zero, not yet * available, or in blocks beyond the anchor block. */ - getMessageContextsByTxHash(txHashes: Fr[], anchorBlockNumber: number): Promise<(MessageContext | null)[]> { - // TODO: optimize, we might be hitting the node to get the same txHash repeatedly - return Promise.all( - txHashes.map(async txHashField => { - // A zero tx hash indicates a tx-less offchain message (e.g. one not tied to any onchain transaction). - // These messages don't have a transaction context to resolve, so we return null. - if (txHashField.isZero()) { - return null; - } + async getMessageContextsByTxHash(txHashes: Fr[], anchorBlockNumber: number): Promise<(MessageContext | null)[]> { + const nonZeroTxHashes = txHashes.filter(h => !h.isZero()).map(h => TxHash.fromField(h)); + const uniqueTxHashes = uniqueBy(nonZeroTxHashes, h => h.toString()); + const fetched = await Promise.all(uniqueTxHashes.map(h => this.aztecNode.getTxEffect(h))); + const txEffects = new Map( + uniqueTxHashes + .map((h, i): [string, IndexedTxEffect | undefined] => [h.toString(), fetched[i]]) + .filter((entry): entry is [string, IndexedTxEffect] => entry[1] !== undefined), + ); - const txHash = TxHash.fromField(txHashField); - const txEffect = await this.aztecNode.getTxEffect(txHash); - if (!txEffect || txEffect.l2BlockNumber > anchorBlockNumber) { - return null; - } + return txHashes.map(txHashField => { + const txHash = TxHash.fromField(txHashField); + const txEffect = txEffects.get(txHash.toString()); + if (!txEffect || txEffect.l2BlockNumber > anchorBlockNumber) { + return null; + } - // Every tx has at least one nullifier (the first nullifier derived from the tx hash). Hitting this condition - // would mean a buggy node, but since we need to access data.nullifiers[0], the defensive check does no harm. - const data = txEffect.data; - if (data.nullifiers.length === 0) { - throw new Error(`Tx effect for ${txHash} has no nullifiers`); - } + // Every tx has at least one nullifier (the first nullifier derived from the tx hash). Hitting this condition + // would mean a buggy node, but since we need to access data.nullifiers[0], the defensive check does no harm. + const data = txEffect.data; + if (data.nullifiers.length === 0) { + throw new Error(`Tx effect for ${txHash} has no nullifiers`); + } - return new MessageContext(data.txHash, data.noteHashes, data.nullifiers[0]); - }), - ); + return new MessageContext(data.txHash, data.noteHashes, data.nullifiers[0]); + }); } } From 6690ae38b6bdf3dbf209bd23e099aff69fcb562b Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Fri, 8 May 2026 07:22:38 -0300 Subject: [PATCH 12/30] refactor(pxe): batch tagged private log queries across all secrets (#23048) --- .../oracle/private_execution.test.ts | 2 +- yarn-project/pxe/src/logs/log_service.ts | 38 +-- .../pxe/src/tagging/get_all_logs_by_tags.ts | 4 + yarn-project/pxe/src/tagging/index.ts | 4 +- ...ate_logs_for_sender_recipient_pair.test.ts | 189 ------------ ..._private_logs_for_sender_recipient_pair.ts | 130 --------- .../sync_tagged_private_logs.test.ts | 275 ++++++++++++++++++ .../sync_tagged_private_logs.ts | 236 +++++++++++++++ .../utils/load_logs_for_range.test.ts | 223 -------------- .../utils/load_logs_for_range.ts | 44 --- 10 files changed, 530 insertions(+), 615 deletions(-) delete mode 100644 yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.test.ts delete mode 100644 yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts create mode 100644 yarn-project/pxe/src/tagging/recipient_sync/sync_tagged_private_logs.test.ts create mode 100644 yarn-project/pxe/src/tagging/recipient_sync/sync_tagged_private_logs.ts delete mode 100644 yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.test.ts delete mode 100644 yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.ts diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts index 9519e36cb15a..2d5d51751a7c 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution.test.ts @@ -358,7 +358,7 @@ describe('Private Execution test suite', () => { // on the input. aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => Promise.resolve(tags.map(() => []))); - // Mock getL2Tips and getBlockHeader for loadPrivateLogsForSenderRecipientPair + // Mock getL2Tips and getBlockHeader for syncTaggedPrivateLogs l2TipsStore.getL2Tips.mockResolvedValue(makeL2Tips(anchorBlockHeader.globalVariables.blockNumber)); // TODO: refactor. Maybe it's worth stubbing a key store diff --git a/yarn-project/pxe/src/logs/log_service.ts b/yarn-project/pxe/src/logs/log_service.ts index 6f8fe80bf49f..1b28eb5aed24 100644 --- a/yarn-project/pxe/src/logs/log_service.ts +++ b/yarn-project/pxe/src/logs/log_service.ts @@ -14,7 +14,7 @@ import type { SenderAddressBookStore } from '../storage/tagging_store/sender_add import { getAllPrivateLogsByTags, getAllPublicLogsByTagsFromContract, - loadPrivateLogsForSenderRecipientPair, + syncTaggedPrivateLogs, } from '../tagging/index.js'; export class LogService { @@ -116,37 +116,23 @@ export class LogService { public async fetchTaggedLogs(contractAddress: AztecAddress, recipient: AztecAddress): Promise { this.log.verbose(`Fetching tagged logs for ${contractAddress.toString()}`); - // We only load logs from block up to and including the anchor block number - const anchorBlockNumber = this.anchorBlockHeader.getBlockNumber(); - const anchorBlockHash = await this.anchorBlockHeader.hash(); - const l2Tips = await this.l2TipsStore.getL2Tips(); - const currentTimestamp = this.anchorBlockHeader.globalVariables.timestamp; // Get all secrets for this recipient (one per sender) const secrets = await this.#getSecretsForSenders(contractAddress, recipient); - // Load logs for all sender-recipient pairs in parallel - const logArrays = await Promise.all( - secrets.map(secret => - loadPrivateLogsForSenderRecipientPair( - secret, - this.aztecNode, - this.recipientTaggingStore, - anchorBlockNumber, - anchorBlockHash, - currentTimestamp, - l2Tips.finalized.block.number, - this.jobId, - ), - ), + const logs = await syncTaggedPrivateLogs( + secrets, + this.aztecNode, + this.recipientTaggingStore, + this.anchorBlockHeader, + l2Tips.finalized.block.number, + this.jobId, ); - return logArrays - .flat() - .map( - scopedLog => - new PendingTaggedLog(scopedLog.logData, scopedLog.txHash, scopedLog.noteHashes, scopedLog.firstNullifier), - ); + return logs.map( + scopedLog => + new PendingTaggedLog(scopedLog.logData, scopedLog.txHash, scopedLog.noteHashes, scopedLog.firstNullifier), + ); } async #getSecretsForSenders( diff --git a/yarn-project/pxe/src/tagging/get_all_logs_by_tags.ts b/yarn-project/pxe/src/tagging/get_all_logs_by_tags.ts index fca567621567..a3c832d2a25b 100644 --- a/yarn-project/pxe/src/tagging/get_all_logs_by_tags.ts +++ b/yarn-project/pxe/src/tagging/get_all_logs_by_tags.ts @@ -39,6 +39,10 @@ async function getAllPagesInBatches( tags: Tag[], fetchAllPagesForBatch: (batch: Tag[]) => Promise, ): Promise { + if (tags.length === 0) { + return []; + } + if (tags.length <= MAX_RPC_LEN) { return fetchAllPagesForBatch(tags); } diff --git a/yarn-project/pxe/src/tagging/index.ts b/yarn-project/pxe/src/tagging/index.ts index 6b812a8f0a47..7ac229dbaebf 100644 --- a/yarn-project/pxe/src/tagging/index.ts +++ b/yarn-project/pxe/src/tagging/index.ts @@ -4,12 +4,12 @@ * The objective of the sender sync algorithm is to determine which tags have already been used by a sender, thereby * deciding which tag should be used next. * - * The objective of the recipient sync algorithm is to load and process the corresponding logs. + * The objective of the recipient sync algorithm is to fetch and sync the corresponding logs. * * @module tagging */ -export { loadPrivateLogsForSenderRecipientPair } from './recipient_sync/load_private_logs_for_sender_recipient_pair.js'; +export { syncTaggedPrivateLogs } from './recipient_sync/sync_tagged_private_logs.js'; export { syncSenderTaggingIndexes } from './sender_sync/sync_sender_tagging_indexes.js'; export { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from './constants.js'; export { getAllPrivateLogsByTags, getAllPublicLogsByTagsFromContract } from './get_all_logs_by_tags.js'; diff --git a/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.test.ts b/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.test.ts deleted file mode 100644 index 5a8838e4b566..000000000000 --- a/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.test.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { MAX_TX_LIFETIME } from '@aztec/constants'; -import { BlockNumber } from '@aztec/foundation/branded-types'; -import { Fr } from '@aztec/foundation/curves/bn254'; -import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; -import { BlockHash } from '@aztec/stdlib/block'; -import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { type ExtendedDirectionalAppTaggingSecret, SiloedTag } from '@aztec/stdlib/logs'; -import { randomExtendedDirectionalAppTaggingSecret, randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; - -import { type MockProxy, mock } from 'jest-mock-extended'; - -import { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js'; -import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../index.js'; -import { loadPrivateLogsForSenderRecipientPair } from './load_private_logs_for_sender_recipient_pair.js'; - -// In this test suite we don't care about the anchor block behavior as that is sufficiently tested by -// the loadLogsForRange test suite, so we use a high block number to ensure it occurs after all logs. -const FAR_FUTURE_BLOCK_NUMBER = BlockNumber(100); -const MOCK_ANCHOR_BLOCK_HASH = BlockHash.random(); - -describe('loadPrivateLogsForSenderRecipientPair', () => { - let secret: ExtendedDirectionalAppTaggingSecret; - - let aztecNode: MockProxy; - let taggingStore: RecipientTaggingStore; - - const currentTimestamp = BigInt(Math.floor(Date.now() / 1000)); - - function computeSiloedTagForIndex(index: number) { - return SiloedTag.compute({ extendedSecret: secret, index }); - } - - function makeLog(blockNumber: number, blockTimestamp: bigint, tag: Fr) { - return randomTxScopedPrivateL2Log({ blockNumber, blockTimestamp, tag }); - } - - beforeAll(async () => { - secret = await randomExtendedDirectionalAppTaggingSecret(); - aztecNode = mock(); - }); - - beforeEach(async () => { - aztecNode.getPrivateLogsByTags.mockReset(); - taggingStore = new RecipientTaggingStore(await openTmpStore('test')); - }); - - it('returns empty array when no logs found', async () => { - const finalizedBlockNumber = BlockNumber(10); - - // no logs found for any tag - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - return Promise.resolve(tags.map((_tag: SiloedTag) => [])); - }); - - const logs = await loadPrivateLogsForSenderRecipientPair( - secret, - aztecNode, - taggingStore, - FAR_FUTURE_BLOCK_NUMBER, - MOCK_ANCHOR_BLOCK_HASH, - currentTimestamp, - finalizedBlockNumber, - 'test', - ); - - expect(logs).toHaveLength(0); - expect(await taggingStore.getHighestAgedIndex(secret, 'test')).toBeUndefined(); - expect(await taggingStore.getHighestFinalizedIndex(secret, 'test')).toBeUndefined(); - }); - - it('loads log and updates highest finalized index but not highest aged index', async () => { - const finalizedBlockNumber = BlockNumber(10); - - const logBlockTimestamp = currentTimestamp - 5000n; // not aged - const logIndex = 5; - const logTag = await computeSiloedTagForIndex(logIndex); - - // The log is finalized - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - return Promise.resolve( - tags.map((t: SiloedTag) => - t.equals(logTag) ? [makeLog(Number(finalizedBlockNumber), logBlockTimestamp, logTag.value)] : [], - ), - ); - }); - - const logs = await loadPrivateLogsForSenderRecipientPair( - secret, - aztecNode, - taggingStore, - FAR_FUTURE_BLOCK_NUMBER, - MOCK_ANCHOR_BLOCK_HASH, - currentTimestamp, - finalizedBlockNumber, - 'test', - ); - - expect(logs).toHaveLength(1); - expect(await taggingStore.getHighestFinalizedIndex(secret, 'test')).toBe(logIndex); - expect(await taggingStore.getHighestAgedIndex(secret, 'test')).toBeUndefined(); - }); - - it('loads log and updates both highest aged and highest finalized indexes', async () => { - const finalizedBlockNumber = BlockNumber(10); - - const logBlockTimestamp = currentTimestamp - BigInt(MAX_TX_LIFETIME) - 1000n; // aged - const logIndex = 7; - const logTag = await computeSiloedTagForIndex(logIndex); - - // The log is finalized - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - return Promise.resolve( - tags.map((t: SiloedTag) => - t.equals(logTag) ? [makeLog(Number(finalizedBlockNumber), logBlockTimestamp, logTag.value)] : [], - ), - ); - }); - - const logs = await loadPrivateLogsForSenderRecipientPair( - secret, - aztecNode, - taggingStore, - FAR_FUTURE_BLOCK_NUMBER, - MOCK_ANCHOR_BLOCK_HASH, - currentTimestamp, - finalizedBlockNumber, - 'test', - ); - - expect(logs).toHaveLength(1); - expect(await taggingStore.getHighestAgedIndex(secret, 'test')).toBe(logIndex); - expect(await taggingStore.getHighestFinalizedIndex(secret, 'test')).toBe(logIndex); - }); - - it('logs at boundaries are properly loaded, window and highest indexes advance as expected', async () => { - const finalizedBlockNumber = BlockNumber(10); - - const log1BlockTimestamp = currentTimestamp - BigInt(MAX_TX_LIFETIME) - 1000n; // Aged - const log2BlockTimestamp = currentTimestamp - 5000n; // Not aged - const highestAgedIndex = 3; - const highestFinalizedIndex = 5; - const log1Index = highestAgedIndex + 1; // At the beginning of the range - const log2Index = highestFinalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN; // At the window boundary - const log1Tag = await computeSiloedTagForIndex(log1Index); - const log2Tag = await computeSiloedTagForIndex(log2Index); - - // Set existing highest aged index and highest finalized index - await taggingStore.updateHighestAgedIndex(secret, highestAgedIndex, 'test'); - await taggingStore.updateHighestFinalizedIndex(secret, highestFinalizedIndex, 'test'); - - // We record the number of queried tags to be able to verify that the window was moved forward correctly. - let numQueriedTags = 0; - - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - numQueriedTags += tags.length; - return Promise.resolve( - tags.map((t: SiloedTag) => { - if (t.equals(log1Tag)) { - return [makeLog(Number(finalizedBlockNumber), log1BlockTimestamp, log1Tag.value)]; - } else if (t.equals(log2Tag)) { - return [makeLog(Number(finalizedBlockNumber), log2BlockTimestamp, log2Tag.value)]; - } - return []; - }), - ); - }); - - const logs = await loadPrivateLogsForSenderRecipientPair( - secret, - aztecNode, - taggingStore, - FAR_FUTURE_BLOCK_NUMBER, - MOCK_ANCHOR_BLOCK_HASH, - currentTimestamp, - finalizedBlockNumber, - 'test', - ); - - // Verify that both logs at the boundaries of the range were found and processed - expect(logs).toHaveLength(2); - expect(await taggingStore.getHighestFinalizedIndex(secret, 'test')).toBe(log2Index); - expect(await taggingStore.getHighestAgedIndex(secret, 'test')).toBe(log1Index); - - // Verify that the window was moved forward correctly - // Total range queried: from (highestAgedIndex + 1) to (log2Index + WINDOW_LEN + 1) exclusive - const expectedNumQueriedTags = log2Index + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN - highestAgedIndex; - expect(numQueriedTags).toBe(expectedNumQueriedTags); - }); -}); diff --git a/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts b/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts deleted file mode 100644 index feed4773fa54..000000000000 --- a/yarn-project/pxe/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +++ /dev/null @@ -1,130 +0,0 @@ -import type { BlockNumber } from '@aztec/foundation/branded-types'; -import type { BlockHash } from '@aztec/stdlib/block'; -import type { AztecNode } from '@aztec/stdlib/interfaces/client'; -import type { ExtendedDirectionalAppTaggingSecret, TxScopedL2Log } from '@aztec/stdlib/logs'; - -import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js'; -import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../constants.js'; -import { findHighestIndexes } from './utils/find_highest_indexes.js'; -import { loadLogsForRange } from './utils/load_logs_for_range.js'; - -/** - * Loads private logs for the app-sender-recipient triplet defined by `secret` and updates the highest aged and - * finalized indexes in the db. At most load logs from blocks up to and including `anchorBlockNumber`. - * - * @dev This function can be safely executed "in parallel" for other sender-recipient pairs because the data in - * in the tagging data provider is indexed by the secret and hence completely disjoint. - */ -export async function loadPrivateLogsForSenderRecipientPair( - secret: ExtendedDirectionalAppTaggingSecret, - aztecNode: AztecNode, - taggingStore: RecipientTaggingStore, - anchorBlockNumber: BlockNumber, - anchorBlockHash: BlockHash, - currentTimestamp: bigint, - finalizedBlockNumber: BlockNumber, - jobId: string, -): Promise { - // # Explanation of how the algorithm works - // When we perform the sync we will look at logs that correspond to the tagging index range - // (highestAgedIndex, highestFinalizedIndex + WINDOW_LEN] - // - // highestAgedIndex is the highest index that was used in a tx that is included in a block at least - // `MAX_TX_LIFETIME` seconds ago. - // highestFinalizedIndex is the highest index that was used in a tx that is included in a finalized block. - // - // "(" denotes an open end of the range - the index is not included in the range. - // "]" denotes a closed end of the range - the index is included in the range. - // - // ## Explanation of highestAgedIndex - // - // highestAgedIndex is chosen such that for all tagging indexes `i <= highestAgedIndex` we know that no new logs can - // ever appear. - // - // This relies on the "maximum inclusion timestamp" rule enforced by the kernel and rollup circuits: - // - a transaction's maximum inclusion timestamp is at most `MAX_TX_LIFETIME` seconds after - // the timestamp of its anchor block; and - // - a rollup only includes transactions whose inclusion timestamp is >= the L2 block's timestamp. - // - // Suppose some device used index `I` in a transaction anchored to block `B_N` at time `N`, and that block is now at - // least `MAX_TX_LIFETIME` seconds in the past. Then there is no possibility of any *other* device - // trying to use an index <= `I` while anchoring to a *newer* block than `B_N` because if we were anchoring to - // a newer block than `B_N` then we would already have seen the log with index `I` and hence the device would have - // chosen a larger index. - // If that *other* device would anchor to a block older than `B_N` then that tx could never be included in a block - // because it would already have been expired. - // - // Therefore, once we see that index `I` has been used in a block that is at least `MAX_TX_LIFETIME` - // seconds old, we can safely stop syncing logs for all indexes <= `I` and set highestAgedIndex = `I`. - // - // ## Explanation of the upper bound `highestFinalizedIndex + WINDOW_LEN` - // - // When a sender chooses a tagging index, they will select an index that is at most `WINDOW_LEN` greater than - // the highest finalized index. If that index was already used, they will throw an error. For this reason we - // don't have to look further than `highestFinalizedIndex + WINDOW_LEN`. - - let start: number, end: number; - { - const currentHighestAgedIndex = await taggingStore.getHighestAgedIndex(secret, jobId); - const currentHighestFinalizedIndex = await taggingStore.getHighestFinalizedIndex(secret, jobId); - - // We don't want to include the highest aged index so we start from `currentHighestAgedIndex + 1` (or 0 if not set) - start = currentHighestAgedIndex === undefined ? 0 : currentHighestAgedIndex + 1; - - // The highest index a sender can choose is "highest finalized index + window length" but given that - // `loadLogsForRange` expects an exclusive `end` we add 1. - end = (currentHighestFinalizedIndex ?? 0) + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN + 1; - } - - const logs: TxScopedL2Log[] = []; - - while (true) { - // Get private logs with their block timestamps and corresponding tagging indexes - const privateLogsWithIndexes = await loadLogsForRange( - secret, - aztecNode, - start, - end, - anchorBlockNumber, - anchorBlockHash, - ); - - if (privateLogsWithIndexes.length === 0) { - break; - } - - logs.push(...privateLogsWithIndexes.map(({ log }) => log)); - - const { highestAgedIndex, highestFinalizedIndex } = findHighestIndexes( - privateLogsWithIndexes, - currentTimestamp, - finalizedBlockNumber, - ); - - // Store updates in data provider and update local variables - if (highestAgedIndex !== undefined) { - await taggingStore.updateHighestAgedIndex(secret, highestAgedIndex, jobId); - } - - if (highestFinalizedIndex === undefined) { - // We have not found a new highest finalized index, so there is no need to move the window forward. - break; - } - - if (highestAgedIndex !== undefined && highestAgedIndex > highestFinalizedIndex) { - // This is just a sanity check as this should never happen. - throw new Error( - `Highest aged index (${highestAgedIndex}) must not exceed highest finalized index (${highestFinalizedIndex})`, - ); - } - - await taggingStore.updateHighestFinalizedIndex(secret, highestFinalizedIndex, jobId); - - // For the next iteration we want to look only at indexes for which we have not attempted to load logs yet while - // ensuring that we do not look further than WINDOW_LEN ahead of the highest finalized index. - start = end; - end = highestFinalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN + 1; // `end` is exclusive so we add 1. - } - - return logs; -} diff --git a/yarn-project/pxe/src/tagging/recipient_sync/sync_tagged_private_logs.test.ts b/yarn-project/pxe/src/tagging/recipient_sync/sync_tagged_private_logs.test.ts new file mode 100644 index 000000000000..1a17d2c552e0 --- /dev/null +++ b/yarn-project/pxe/src/tagging/recipient_sync/sync_tagged_private_logs.test.ts @@ -0,0 +1,275 @@ +import { MAX_TX_LIFETIME } from '@aztec/constants'; +import { BlockNumber } from '@aztec/foundation/branded-types'; +import { Fr } from '@aztec/foundation/curves/bn254'; +import { openTmpStore } from '@aztec/kv-store/lmdb-v2'; +import type { AztecNode } from '@aztec/stdlib/interfaces/server'; +import { type ExtendedDirectionalAppTaggingSecret, SiloedTag } from '@aztec/stdlib/logs'; +import { randomExtendedDirectionalAppTaggingSecret, randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; +import { BlockHeader } from '@aztec/stdlib/tx'; + +import { type MockProxy, mock } from 'jest-mock-extended'; + +import { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js'; +import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN, syncTaggedPrivateLogs } from '../index.js'; + +const FAR_FUTURE_BLOCK_NUMBER = BlockNumber(100); +const CURRENT_TIMESTAMP = BigInt(Math.floor(Date.now() / 1000)); +const ANCHOR_BLOCK_HEADER = BlockHeader.random({ blockNumber: FAR_FUTURE_BLOCK_NUMBER, timestamp: CURRENT_TIMESTAMP }); +const JOB_ID = 'test-job'; + +describe('syncTaggedPrivateLogs', () => { + const aztecNode: MockProxy = mock(); + let taggingStore: RecipientTaggingStore; + + function computeSiloedTagForIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number) { + return SiloedTag.compute({ extendedSecret: secret, index }); + } + + function makeLog(blockNumber: number, blockTimestamp: bigint, tag: Fr) { + return randomTxScopedPrivateL2Log({ blockNumber, blockTimestamp, tag }); + } + + beforeEach(async () => { + aztecNode.getPrivateLogsByTags.mockReset(); + taggingStore = new RecipientTaggingStore(await openTmpStore('test')); + }); + + it('returns empty array when given no secrets', async () => { + const logs = await syncTaggedPrivateLogs([], aztecNode, taggingStore, ANCHOR_BLOCK_HEADER, BlockNumber(10), JOB_ID); + + expect(logs).toHaveLength(0); + expect(aztecNode.getPrivateLogsByTags).not.toHaveBeenCalled(); + }); + + it('returns empty array when no logs found for any secret', async () => { + const secrets = await makeSecrets(3); + aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { + return Promise.resolve(tags.map(() => [])); + }); + + const logs = await syncTaggedPrivateLogs( + secrets, + aztecNode, + taggingStore, + ANCHOR_BLOCK_HEADER, + BlockNumber(10), + JOB_ID, + ); + + expect(logs).toHaveLength(0); + }); + + it('batches tags from multiple secrets into a single RPC call', async () => { + const secrets = await makeSecrets(3); + const finalizedBlockNumber = BlockNumber(10); + + aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { + return Promise.resolve(tags.map(() => [])); + }); + + await syncTaggedPrivateLogs(secrets, aztecNode, taggingStore, ANCHOR_BLOCK_HEADER, finalizedBlockNumber, JOB_ID); + + expect(aztecNode.getPrivateLogsByTags).toHaveBeenCalledTimes(1); + }); + + it('syncs logs and updates store independently per secret', async () => { + const secrets = await makeSecrets(3); + const finalizedBlockNumber = BlockNumber(10); + const logBlockTimestamp = CURRENT_TIMESTAMP - BigInt(MAX_TX_LIFETIME) - 1000n; + + const log1Index = 3; + const log2Index = 7; + const log1Tag = await computeSiloedTagForIndex(secrets[0], log1Index); + const log2Tag = await computeSiloedTagForIndex(secrets[1], log2Index); + + aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { + return Promise.resolve( + tags.map((t: SiloedTag) => { + if (t.equals(log1Tag)) { + return [makeLog(Number(finalizedBlockNumber), logBlockTimestamp, log1Tag.value)]; + } else if (t.equals(log2Tag)) { + return [makeLog(Number(finalizedBlockNumber), logBlockTimestamp, log2Tag.value)]; + } + return []; + }), + ); + }); + + const logs = await syncTaggedPrivateLogs( + secrets, + aztecNode, + taggingStore, + ANCHOR_BLOCK_HEADER, + finalizedBlockNumber, + JOB_ID, + ); + + expect(logs).toHaveLength(2); + expect(await taggingStore.getHighestAgedIndex(secrets[0], JOB_ID)).toBe(log1Index); + expect(await taggingStore.getHighestFinalizedIndex(secrets[0], JOB_ID)).toBe(log1Index); + expect(await taggingStore.getHighestAgedIndex(secrets[1], JOB_ID)).toBe(log2Index); + expect(await taggingStore.getHighestFinalizedIndex(secrets[1], JOB_ID)).toBe(log2Index); + // secrets[2] found nothing, so its store must be untouched + expect(await taggingStore.getHighestAgedIndex(secrets[2], JOB_ID)).toBeUndefined(); + expect(await taggingStore.getHighestFinalizedIndex(secrets[2], JOB_ID)).toBeUndefined(); + }); + + it('does not advance aged index for recent logs', async () => { + const [secret] = await makeSecrets(1); + const finalizedBlockNumber = BlockNumber(10); + const logBlockTimestamp = CURRENT_TIMESTAMP - 5000n; // not aged + + const logIndex = 5; + const logTag = await computeSiloedTagForIndex(secret, logIndex); + + aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { + return Promise.resolve( + tags.map((t: SiloedTag) => + t.equals(logTag) ? [makeLog(Number(finalizedBlockNumber), logBlockTimestamp, logTag.value)] : [], + ), + ); + }); + + await syncTaggedPrivateLogs([secret], aztecNode, taggingStore, ANCHOR_BLOCK_HEADER, finalizedBlockNumber, JOB_ID); + + expect(await taggingStore.getHighestFinalizedIndex(secret, JOB_ID)).toBe(logIndex); + expect(await taggingStore.getHighestAgedIndex(secret, JOB_ID)).toBeUndefined(); + }); + + it('updates store correctly when multiple iterations are needed', async () => { + const [secret] = await makeSecrets(1); + const finalizedBlockNumber = BlockNumber(10); + const agedBlockTimestamp = CURRENT_TIMESTAMP - BigInt(MAX_TX_LIFETIME) - 1000n; + + // A log at the last index of the initial window [0, WINDOW_LEN] moves the finalized index to WINDOW_LEN, + // which shifts the next window forward and triggers a second iteration. + const lastIndexInInitialWindow = UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN; + const log1Tag = await computeSiloedTagForIndex(secret, lastIndexInInitialWindow); + + // A second log sits in the advanced window, only reachable in the second iteration. + const newWindowIndex = lastIndexInInitialWindow + 3; + const log2Tag = await computeSiloedTagForIndex(secret, newWindowIndex); + + aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { + return Promise.resolve( + tags.map((t: SiloedTag) => { + if (t.equals(log1Tag)) { + return [makeLog(Number(finalizedBlockNumber), agedBlockTimestamp, log1Tag.value)]; + } else if (t.equals(log2Tag)) { + return [makeLog(Number(finalizedBlockNumber), agedBlockTimestamp, log2Tag.value)]; + } + return []; + }), + ); + }); + + const logs = await syncTaggedPrivateLogs( + [secret], + aztecNode, + taggingStore, + ANCHOR_BLOCK_HEADER, + finalizedBlockNumber, + JOB_ID, + ); + + expect(logs).toHaveLength(2); + expect(await taggingStore.getHighestAgedIndex(secret, JOB_ID)).toBe(newWindowIndex); + expect(await taggingStore.getHighestFinalizedIndex(secret, JOB_ID)).toBe(newWindowIndex); + }); + + it('respects pre-existing store indexes', async () => { + const [secret] = await makeSecrets(1); + const finalizedBlockNumber = BlockNumber(10); + + const existingAgedIndex = 5; + const existingFinalizedIndex = 8; + await taggingStore.updateHighestAgedIndex(secret, existingAgedIndex, JOB_ID); + await taggingStore.updateHighestFinalizedIndex(secret, existingFinalizedIndex, JOB_ID); + + aztecNode.getPrivateLogsByTags.mockResolvedValue([]); + + await syncTaggedPrivateLogs([secret], aztecNode, taggingStore, ANCHOR_BLOCK_HEADER, finalizedBlockNumber, JOB_ID); + + const calledTags = aztecNode.getPrivateLogsByTags.mock.calls[0][0]; + + // The query window must start at existingAgedIndex+1 and end at existingFinalizedIndex+WINDOW_LEN (inclusive). + const expectedStart = existingAgedIndex + 1; + const expectedEnd = existingFinalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN; + const expectedTags = await Promise.all( + Array.from({ length: expectedEnd - expectedStart + 1 }, (_, i) => + computeSiloedTagForIndex(secret, expectedStart + i), + ), + ); + + expect(calledTags).toEqual(expectedTags); + }); + + it('handles multiple logs at the same tag index', async () => { + const [secret] = await makeSecrets(1); + const finalizedBlockNumber = BlockNumber(10); + const logBlockTimestamp = CURRENT_TIMESTAMP - BigInt(MAX_TX_LIFETIME) - 1000n; + + const logIndex = 3; + const logTag = await computeSiloedTagForIndex(secret, logIndex); + + // Two logs returned for the same tag + aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { + return Promise.resolve( + tags.map((t: SiloedTag) => + t.equals(logTag) + ? [ + makeLog(Number(finalizedBlockNumber), logBlockTimestamp, logTag.value), + makeLog(Number(finalizedBlockNumber), logBlockTimestamp, logTag.value), + ] + : [], + ), + ); + }); + + const logs = await syncTaggedPrivateLogs( + [secret], + aztecNode, + taggingStore, + ANCHOR_BLOCK_HEADER, + finalizedBlockNumber, + JOB_ID, + ); + + expect(logs).toHaveLength(2); + }); + + it('filters out logs from blocks after the anchor block', async () => { + const [secret] = await makeSecrets(1); + const anchorBlock = BlockNumber(10); + const header = BlockHeader.random({ blockNumber: anchorBlock, timestamp: CURRENT_TIMESTAMP }); + const finalizedBlockNumber = BlockNumber(10); + const logBlockTimestamp = CURRENT_TIMESTAMP - BigInt(MAX_TX_LIFETIME) - 1000n; + + const logIndex = 3; + const logTag = await computeSiloedTagForIndex(secret, logIndex); + + // Three logs: one before anchor, one at anchor, one after anchor + aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { + return Promise.resolve( + tags.map((t: SiloedTag) => + t.equals(logTag) + ? [ + makeLog(Number(anchorBlock) - 1, logBlockTimestamp, logTag.value), + makeLog(Number(anchorBlock), logBlockTimestamp, logTag.value), + makeLog(Number(anchorBlock) + 1, logBlockTimestamp, logTag.value), + ] + : [], + ), + ); + }); + + const logs = await syncTaggedPrivateLogs([secret], aztecNode, taggingStore, header, finalizedBlockNumber, JOB_ID); + + // Only logs at or before the anchor block should be included + expect(logs).toHaveLength(2); + }); +}); + +function makeSecrets(count: number): Promise { + return Promise.all(Array.from({ length: count }, () => randomExtendedDirectionalAppTaggingSecret())); +} diff --git a/yarn-project/pxe/src/tagging/recipient_sync/sync_tagged_private_logs.ts b/yarn-project/pxe/src/tagging/recipient_sync/sync_tagged_private_logs.ts new file mode 100644 index 000000000000..6e904ad6c012 --- /dev/null +++ b/yarn-project/pxe/src/tagging/recipient_sync/sync_tagged_private_logs.ts @@ -0,0 +1,236 @@ +import type { BlockNumber } from '@aztec/foundation/branded-types'; +import { isDefined } from '@aztec/foundation/types'; +import type { BlockHash } from '@aztec/stdlib/block'; +import type { AztecNode } from '@aztec/stdlib/interfaces/client'; +import type { ExtendedDirectionalAppTaggingSecret, TxScopedL2Log } from '@aztec/stdlib/logs'; +import { SiloedTag } from '@aztec/stdlib/logs'; +import type { BlockHeader } from '@aztec/stdlib/tx'; + +import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js'; +import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../constants.js'; +import { getAllPrivateLogsByTags } from '../get_all_logs_by_tags.js'; +import { findHighestIndexes } from './utils/find_highest_indexes.js'; + +/** + * Fetches and syncs tagged private logs for multiple sender-recipient pairs, batching tag queries across all secrets + * into shared RPC calls. + * + * # Explanation of how the algorithm works + * + * For each secret we sync logs that correspond to the tagging index range + * (highestAgedIndex, highestFinalizedIndex + WINDOW_LEN] + * + * highestAgedIndex is the highest index that was used in a tx that is included in a block at least + * `MAX_TX_LIFETIME` seconds ago. + * highestFinalizedIndex is the highest index that was used in a tx that is included in a finalized block. + * + * "(" denotes an open end of the range - the index is not included in the range. + * "]" denotes a closed end of the range - the index is included in the range. + * + * ## Explanation of highestAgedIndex + * + * highestAgedIndex is chosen such that for all tagging indexes `i <= highestAgedIndex` we know that no new logs can + * ever appear. + * + * This relies on the "maximum inclusion timestamp" rule enforced by the kernel and rollup circuits: + * - a transaction's maximum inclusion timestamp is at most `MAX_TX_LIFETIME` seconds after + * the timestamp of its anchor block; and + * - a rollup only includes transactions whose inclusion timestamp is >= the L2 block's timestamp. + * + * Suppose some device used index `I` in a transaction anchored to block `B_N` at time `N`, and that block is now at + * least `MAX_TX_LIFETIME` seconds in the past. Then there is no possibility of any *other* device + * trying to use an index <= `I` while anchoring to a *newer* block than `B_N` because if we were anchoring to + * a newer block than `B_N` then we would already have seen the log with index `I` and hence the device would have + * chosen a larger index. + * If that *other* device would anchor to a block older than `B_N` then that tx could never be included in a block + * because it would already have been expired. + * + * Therefore, once we see that index `I` has been used in a block that is at least `MAX_TX_LIFETIME` + * seconds old, we can safely stop syncing logs for all indexes <= `I` and set highestAgedIndex = `I`. + * + * ## Explanation of the upper bound `highestFinalizedIndex + WINDOW_LEN` + * + * When a sender chooses a tagging index, they will select an index that is at most `WINDOW_LEN` greater than + * the highest finalized index. If that index was already used, they will throw an error. For this reason we + * don't have to look further than `highestFinalizedIndex + WINDOW_LEN`. + * + * ## Batching across secrets + * + * Instead of running one RPC call per secret, we merge tags from all pending secrets into a single flat array, + * make one batched `getAllPrivateLogsByTags` call (which internally chunks at MAX_RPC_LEN), then split results + * back per secret using tracked offsets. Only secrets whose window advanced are kept for the next iteration. + */ +export async function syncTaggedPrivateLogs( + secrets: ExtendedDirectionalAppTaggingSecret[], + aztecNode: AztecNode, + taggingStore: RecipientTaggingStore, + anchorBlockHeader: BlockHeader, + finalizedBlockNumber: BlockNumber, + jobId: string, +): Promise { + if (secrets.length === 0) { + return []; + } + + const anchorBlockNumber = anchorBlockHeader.getBlockNumber(); + const anchorBlockHash = await anchorBlockHeader.hash(); + const currentTimestamp = anchorBlockHeader.globalVariables.timestamp; + + // Read stored indexes from the db and compute the initial [start, end) range for each secret + let pending = await getIndexRangesForSecrets(secrets, taggingStore, jobId); + const allLogs: TxScopedL2Log[] = []; + + while (pending.length > 0) { + // Compute tags for all pending secrets and fetch logs in batched RPC calls + const logsPerSecret = await fetchLogsForSecrets(pending, aztecNode, anchorBlockNumber, anchorBlockHash); + + const nextRound = await Promise.all( + pending.map(async (pendingSecret, i) => { + const logsFoundWithSecret = logsPerSecret[i]; + if (logsFoundWithSecret.length === 0) { + // No logs found, no need to update indexes or advance window. + return undefined; + } + + allLogs.push(...logsFoundWithSecret.map(({ log }) => log)); + + // Persist new indexes. If the finalized index moved forward, the window advances + // and we need another round for this secret. + return await updateIndexesAndAdvanceWindow( + pendingSecret, + logsFoundWithSecret, + taggingStore, + currentTimestamp, + finalizedBlockNumber, + jobId, + ); + }), + ); + + pending = nextRound.filter(isDefined); + } + + return allLogs; +} + +/** Reads stored indexes for each secret and computes the initial index range to query. */ +function getIndexRangesForSecrets( + secrets: ExtendedDirectionalAppTaggingSecret[], + taggingStore: RecipientTaggingStore, + jobId: string, +): Promise { + return Promise.all( + secrets.map(async secret => { + const [currentHighestAgedIndex, currentHighestFinalizedIndex] = await Promise.all([ + taggingStore.getHighestAgedIndex(secret, jobId), + taggingStore.getHighestFinalizedIndex(secret, jobId), + ]); + + const start = currentHighestAgedIndex === undefined ? 0 : currentHighestAgedIndex + 1; + const end = (currentHighestFinalizedIndex ?? 0) + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN + 1; + + return { secret, start, end }; + }), + ); +} + +/** + * Computes siloed tags for all pending secrets' index ranges, fetches logs in one batched RPC call, + * and returns the results grouped back per secret. + */ +async function fetchLogsForSecrets( + pending: PendingSecret[], + aztecNode: AztecNode, + anchorBlockNumber: BlockNumber, + anchorBlockHash: BlockHash, +): Promise { + // Determine the index range for each secret + const indexesPerSecret = pending.map(({ start, end }) => Array.from({ length: end - start }, (_, i) => start + i)); + + // Compute siloed tags for all indexes + const tagsPerSecret = await Promise.all( + pending.map(({ secret }, i) => + Promise.all(indexesPerSecret[i].map(index => SiloedTag.compute({ extendedSecret: secret, index }))), + ), + ); + + const allTags = tagsPerSecret.flat(); + + // getAllPrivateLogsByTags handles MAX_RPC_LEN chunking internally + const allResults = await getAllPrivateLogsByTags(aztecNode, allTags, anchorBlockHash); + + // Split flat results back per secret using the known lengths + const logsPerSecret: LogWithIndex[][] = []; + let offset = 0; + for (const indexes of indexesPerSecret) { + const logsForSecret: LogWithIndex[] = []; + for (let i = 0; i < indexes.length; i++) { + for (const log of allResults[offset + i]) { + if (log.blockNumber <= anchorBlockNumber) { + logsForSecret.push({ log, taggingIndex: indexes[i] }); + } + } + } + logsPerSecret.push(logsForSecret); + offset += indexes.length; + } + + return logsPerSecret; +} + +/** + * Processes a single secret's fetched logs: updates stored indexes and returns a new PendingSecret + * if the window needs to advance, or undefined if this secret is done. + */ +async function updateIndexesAndAdvanceWindow( + pending: PendingSecret, + logsWithIndexes: LogWithIndex[], + taggingStore: RecipientTaggingStore, + currentTimestamp: bigint, + finalizedBlockNumber: BlockNumber, + jobId: string, +): Promise { + const { highestAgedIndex, highestFinalizedIndex } = findHighestIndexes( + logsWithIndexes, + currentTimestamp, + finalizedBlockNumber, + ); + + // Store updates in data provider and update local variables + if (highestAgedIndex !== undefined) { + await taggingStore.updateHighestAgedIndex(pending.secret, highestAgedIndex, jobId); + } + + if (highestFinalizedIndex === undefined) { + // We have not found a new highest finalized index, so there is no need to move the window forward. + return undefined; + } + + if (highestAgedIndex !== undefined && highestAgedIndex > highestFinalizedIndex) { + // This is just a sanity check as this should never happen. + throw new Error( + `Highest aged index (${highestAgedIndex}) must not exceed highest finalized index (${highestFinalizedIndex})`, + ); + } + + await taggingStore.updateHighestFinalizedIndex(pending.secret, highestFinalizedIndex, jobId); + + // For the next iteration we want to look only at indexes for which we have not yet fetched logs while + // ensuring that we do not look further than WINDOW_LEN ahead of the highest finalized index. + return { + secret: pending.secret, + start: pending.end, + end: highestFinalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN + 1, + }; +} + +type PendingSecret = { + secret: ExtendedDirectionalAppTaggingSecret; + start: number; + end: number; +}; + +type LogWithIndex = { + log: TxScopedL2Log; + taggingIndex: number; +}; diff --git a/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.test.ts b/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.test.ts deleted file mode 100644 index 89134335968d..000000000000 --- a/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.test.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { BlockNumber } from '@aztec/foundation/branded-types'; -import { BlockHash } from '@aztec/stdlib/block'; -import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { type ExtendedDirectionalAppTaggingSecret, SiloedTag } from '@aztec/stdlib/logs'; -import { randomExtendedDirectionalAppTaggingSecret, randomTxScopedPrivateL2Log } from '@aztec/stdlib/testing'; -import { TxHash } from '@aztec/stdlib/tx'; - -import { type MockProxy, mock } from 'jest-mock-extended'; - -import { loadLogsForRange } from './load_logs_for_range.js'; - -// In tests where the anchor block behavior is not under examination, we use a high block number to ensure it occurs -// after all logs. -const FAR_FUTURE_BLOCK_NUMBER = BlockNumber(100); -const MOCK_ANCHOR_BLOCK_HASH = BlockHash.random(); - -describe('loadLogsForRange', () => { - // App contract address and secret to be used on the input of the loadLogsForRange function. - let secret: ExtendedDirectionalAppTaggingSecret; - - let aztecNode: MockProxy; - - function computeSiloedTagForIndex(index: number) { - return SiloedTag.compute({ extendedSecret: secret, index }); - } - - function makeLog(txHash: TxHash, blockNumber: number, blockTimestamp: bigint, tag: SiloedTag) { - return randomTxScopedPrivateL2Log({ txHash, blockNumber, blockTimestamp, tag: tag.value }); - } - - beforeAll(async () => { - secret = await randomExtendedDirectionalAppTaggingSecret(); - aztecNode = mock(); - }); - - beforeEach(() => { - aztecNode.getPrivateLogsByTags.mockReset(); - }); - - it('returns empty array when no logs found for the given window', async () => { - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - // No log found for any tag - return Promise.resolve(tags.map((_tag: SiloedTag) => [])); - }); - - expect( - await loadLogsForRange(secret, aztecNode, 0, 10, FAR_FUTURE_BLOCK_NUMBER, MOCK_ANCHOR_BLOCK_HASH), - ).toHaveLength(0); - }); - - it('handles multiple logs at different indexes', async () => { - const txHash1 = TxHash.random(); - const txHash2 = TxHash.random(); - const blockNumber1 = 5; - const blockNumber2 = 6; - const index1 = 2; - const index2 = 7; - const timestamp1 = 1000n; - const timestamp2 = 2000n; - const tag1 = await computeSiloedTagForIndex(index1); - const tag2 = await computeSiloedTagForIndex(index2); - - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - return Promise.all( - tags.map((t: SiloedTag) => { - if (t.equals(tag1)) { - return [makeLog(txHash1, blockNumber1, timestamp1, tag1)]; - } else if (t.equals(tag2)) { - return [makeLog(txHash2, blockNumber2, timestamp2, tag2)]; - } - return []; - }), - ); - }); - - const result = await loadLogsForRange(secret, aztecNode, 0, 10, FAR_FUTURE_BLOCK_NUMBER, MOCK_ANCHOR_BLOCK_HASH); - - expect(result).toHaveLength(2); - const resultByIndex = result.sort((a, b) => a.taggingIndex - b.taggingIndex); - expect(resultByIndex[0].taggingIndex).toBe(index1); - expect(resultByIndex[0].log.blockTimestamp).toBe(timestamp1); - expect(resultByIndex[0].log.txHash.equals(txHash1)).toBe(true); - expect(resultByIndex[1].taggingIndex).toBe(index2); - expect(resultByIndex[1].log.blockTimestamp).toBe(timestamp2); - expect(resultByIndex[1].log.txHash.equals(txHash2)).toBe(true); - }); - - it('handles multiple logs at the same index', async () => { - const txHash1 = TxHash.random(); - const txHash2 = TxHash.random(); - const blockNumber1 = 5; - const blockNumber2 = 6; - const index = 4; - const timestamp1 = 1000n; - const timestamp2 = 2000n; - const tag = await computeSiloedTagForIndex(index); - - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - return Promise.resolve( - tags.map((t: SiloedTag) => - t.equals(tag) - ? [makeLog(txHash1, blockNumber1, timestamp1, tag), makeLog(txHash2, blockNumber2, timestamp2, tag)] - : [], - ), - ); - }); - - const result = await loadLogsForRange(secret, aztecNode, 0, 10, FAR_FUTURE_BLOCK_NUMBER, MOCK_ANCHOR_BLOCK_HASH); - - expect(result).toHaveLength(2); - expect(result[0].taggingIndex).toBe(index); - expect(result[1].taggingIndex).toBe(index); - const txHashes = result.map(r => r.log.txHash.toString()); - expect(txHashes).toContain(txHash1.toString()); - expect(txHashes).toContain(txHash2.toString()); - }); - - it('handles multiple logs in the same block', async () => { - const txHash1 = TxHash.random(); - const txHash2 = TxHash.random(); - const blockNumber = 5; - const index1 = 2; - const index2 = 3; - const timestamp = 1000n; - const tag1 = await computeSiloedTagForIndex(index1); - const tag2 = await computeSiloedTagForIndex(index2); - - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - return Promise.resolve( - tags.map((t: SiloedTag) => { - if (t.equals(tag1)) { - return [makeLog(txHash1, blockNumber, timestamp, tag1)]; - } else if (t.equals(tag2)) { - return [makeLog(txHash2, blockNumber, timestamp, tag2)]; - } - return []; - }), - ); - }); - - const result = await loadLogsForRange(secret, aztecNode, 0, 10, FAR_FUTURE_BLOCK_NUMBER, MOCK_ANCHOR_BLOCK_HASH); - - expect(result).toHaveLength(2); - - const resultByIndex = result.sort((a, b) => a.taggingIndex - b.taggingIndex); - expect(resultByIndex[0].taggingIndex).toBe(index1); - expect(resultByIndex[0].log.blockTimestamp).toBe(timestamp); - expect(resultByIndex[1].taggingIndex).toBe(index2); - expect(resultByIndex[1].log.blockTimestamp).toBe(timestamp); - }); - - it('respects start (inclusive) and end (exclusive) boundaries', async () => { - const start = 5; - const end = 10; - - const txHashAtStart = TxHash.random(); - const txHashAtEnd = TxHash.random(); - const timestamp = 1000n; - const tagAtStart = await computeSiloedTagForIndex(start); - const tagAtEnd = await computeSiloedTagForIndex(end); - - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - return Promise.resolve( - tags.map((t: SiloedTag) => { - if (t.equals(tagAtStart)) { - return [makeLog(txHashAtStart, 5, timestamp, tagAtStart)]; - } else if (t.equals(tagAtEnd)) { - return [makeLog(txHashAtEnd, 6, timestamp, tagAtEnd)]; - } - return []; - }), - ); - }); - - const result = await loadLogsForRange( - secret, - aztecNode, - start, - end, - FAR_FUTURE_BLOCK_NUMBER, - MOCK_ANCHOR_BLOCK_HASH, - ); - - // Should only include log at start (inclusive), not at end (exclusive) - expect(result).toHaveLength(1); - expect(result[0].taggingIndex).toBe(start); - expect(result[0].log.txHash.equals(txHashAtStart)).toBe(true); - }); - - it('filters out logs from blocks after anchor block', async () => { - const anchorBlockNumber = 10; - - const index = 3; - const timestamp = 1000n; - const tag = await computeSiloedTagForIndex(index); - - aztecNode.getPrivateLogsByTags.mockImplementation((tags: SiloedTag[]) => { - return Promise.resolve( - tags.map((t: SiloedTag) => - t.equals(tag) - ? [ - makeLog(TxHash.random(), anchorBlockNumber - 1, timestamp, tag), - makeLog(TxHash.random(), anchorBlockNumber, timestamp, tag), - makeLog(TxHash.random(), anchorBlockNumber + 1, timestamp, tag), - ] - : [], - ), - ); - }); - - const result = await loadLogsForRange( - secret, - aztecNode, - 0, - 10, - BlockNumber(anchorBlockNumber), - MOCK_ANCHOR_BLOCK_HASH, - ); - - // Should only include logs from blocks at or before the anchor block number - expect(result).toHaveLength(2); - }); -}); diff --git a/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.ts b/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.ts deleted file mode 100644 index c8e3bfa575b7..000000000000 --- a/yarn-project/pxe/src/tagging/recipient_sync/utils/load_logs_for_range.ts +++ /dev/null @@ -1,44 +0,0 @@ -import type { BlockNumber } from '@aztec/foundation/branded-types'; -import type { BlockHash } from '@aztec/stdlib/block'; -import type { AztecNode } from '@aztec/stdlib/interfaces/client'; -import type { ExtendedDirectionalAppTaggingSecret, TxScopedL2Log } from '@aztec/stdlib/logs'; -import { SiloedTag } from '@aztec/stdlib/logs'; - -import { getAllPrivateLogsByTags } from '../../get_all_logs_by_tags.js'; - -/** - * Gets private logs with their corresponding block timestamps and tagging indexes for the given index range and - * `extendedSecret`. At most load logs from blocks up to and including `anchorBlockNumber`. `start` is inclusive and - * `end` is exclusive. - */ -export async function loadLogsForRange( - extendedSecret: ExtendedDirectionalAppTaggingSecret, - aztecNode: AztecNode, - start: number, - end: number, - anchorBlockNumber: BlockNumber, - anchorBlockHash: BlockHash, -): Promise> { - // Derive siloed tags for the window - const siloedTags = await Promise.all( - Array.from({ length: end - start }, (_, i) => SiloedTag.compute({ extendedSecret, index: start + i })), - ); - - // We use the utility function below to retrieve all logs for the tags across all pages, so we don't need to handle - // pagination here. - const logs = await getAllPrivateLogsByTags(aztecNode, siloedTags, anchorBlockHash); - - // Pair logs with their corresponding tagging indexes - const logsWithIndexes: Array<{ log: TxScopedL2Log; taggingIndex: number }> = []; - for (let i = 0; i < logs.length; i++) { - const logsForTag = logs[i]; - const taggingIndex = start + i; - for (const log of logsForTag) { - if (log.blockNumber <= anchorBlockNumber) { - logsWithIndexes.push({ log, taggingIndex }); - } - } - } - - return logsWithIndexes; -} From 18b40a14b74e92f959c485b1971f562b4e918c74 Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Fri, 8 May 2026 09:55:49 -0300 Subject: [PATCH 13/30] refactor(pxe): batch log RPC calls in LogService.fetchLogsByTag (#23088) --- yarn-project/pxe/src/logs/log_service.test.ts | 35 ++++++++ yarn-project/pxe/src/logs/log_service.ts | 79 ++++++++----------- 2 files changed, 69 insertions(+), 45 deletions(-) diff --git a/yarn-project/pxe/src/logs/log_service.test.ts b/yarn-project/pxe/src/logs/log_service.test.ts index 2f8e05c4f1ef..764559a9d42b 100644 --- a/yarn-project/pxe/src/logs/log_service.test.ts +++ b/yarn-project/pxe/src/logs/log_service.test.ts @@ -147,5 +147,40 @@ describe('LogService', () => { /Got a log retrieval request from/, ); }); + + it('batches multiple requests into single RPC calls', async () => { + const tag1 = Tag.random(); + const tag2 = Tag.random(); + const tag3 = Tag.random(); + + const publicLog1 = randomTxScopedPrivateL2Log(); + const privateLog2 = randomTxScopedPrivateL2Log(); + + aztecNode.getPublicLogsByTagsFromContract.mockResolvedValue([[publicLog1], [], []]); + aztecNode.getPrivateLogsByTags.mockResolvedValue([[], [privateLog2], []]); + + const requests = [ + new LogRetrievalRequest(contractAddress, tag1), + new LogRetrievalRequest(contractAddress, tag2), + new LogRetrievalRequest(contractAddress, tag3), + ]; + + const responses = await logService.fetchLogsByTag(contractAddress, requests); + + expect(responses).toHaveLength(3); + expect(responses[0]).toEqual(expect.objectContaining({ txHash: publicLog1.txHash })); + expect(responses[1]).toEqual(expect.objectContaining({ txHash: privateLog2.txHash })); + expect(responses[2]).toBeNull(); + + expect(aztecNode.getPublicLogsByTagsFromContract).toHaveBeenCalledTimes(1); + expect(aztecNode.getPrivateLogsByTags).toHaveBeenCalledTimes(1); + }); + + it('returns empty array for empty requests', async () => { + const responses = await logService.fetchLogsByTag(contractAddress, []); + expect(responses).toEqual([]); + expect(aztecNode.getPublicLogsByTagsFromContract).not.toHaveBeenCalled(); + expect(aztecNode.getPrivateLogsByTags).not.toHaveBeenCalled(); + }); }); }); diff --git a/yarn-project/pxe/src/logs/log_service.ts b/yarn-project/pxe/src/logs/log_service.ts index 1b28eb5aed24..6edd28fae40f 100644 --- a/yarn-project/pxe/src/logs/log_service.ts +++ b/yarn-project/pxe/src/logs/log_service.ts @@ -3,7 +3,12 @@ import type { KeyStore } from '@aztec/key-store'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; import type { L2TipsProvider } from '@aztec/stdlib/block'; import type { AztecNode } from '@aztec/stdlib/interfaces/server'; -import { ExtendedDirectionalAppTaggingSecret, PendingTaggedLog, SiloedTag, Tag } from '@aztec/stdlib/logs'; +import { + ExtendedDirectionalAppTaggingSecret, + PendingTaggedLog, + SiloedTag, + type TxScopedL2Log, +} from '@aztec/stdlib/logs'; import type { BlockHeader } from '@aztec/stdlib/tx'; import type { LogRetrievalRequest } from '../contract_function_simulator/noir-structs/log_retrieval_request.js'; @@ -44,62 +49,46 @@ export class LogService { } } - return await Promise.all( - logRetrievalRequests.map(async request => { - const [publicLog, privateLog] = await Promise.all([ - this.#getPublicLogByTag(request.tag, request.contractAddress), - this.#getPrivateLogByTag(await SiloedTag.computeFromTagAndApp(request.tag, request.contractAddress)), - ]); - - if (publicLog !== null && privateLog !== null) { - this.log.warn( - `Found both a public and private log for tag ${request.tag} from contract ${request.contractAddress}. This may indicate a contract bug. Returning the public log.`, - ); - } - - return publicLog ?? privateLog; - }), - ); - } + if (logRetrievalRequests.length === 0) { + return []; + } - async #getPublicLogByTag(tag: Tag, contractAddress: AztecAddress): Promise { const anchorBlockHash = await this.anchorBlockHeader.hash(); - const allLogsPerTag = await getAllPublicLogsByTagsFromContract( - this.aztecNode, - contractAddress, - [tag], - anchorBlockHash, + const tags = logRetrievalRequests.map(r => r.tag); + const siloedTags = await Promise.all( + logRetrievalRequests.map(r => SiloedTag.computeFromTagAndApp(r.tag, r.contractAddress)), ); - const logsForTag = allLogsPerTag[0]; - if (logsForTag.length === 0) { - return null; - } else if (logsForTag.length > 1) { - this.log.warn( - `Expected at most 1 public log for tag ${tag} and contract ${contractAddress.toString()}, got ${logsForTag.length}. This may indicate a contract bug. Returning the first log.`, + const [allPublicLogsPerTag, allPrivateLogsPerTag] = await Promise.all([ + getAllPublicLogsByTagsFromContract(this.aztecNode, contractAddress, tags, anchorBlockHash), + getAllPrivateLogsByTags(this.aztecNode, siloedTags, anchorBlockHash), + ]); + + return logRetrievalRequests.map((request, i) => { + const publicLog = this.#extractSingleLog( + allPublicLogsPerTag[i], + `public log for tag ${request.tag} and contract ${request.contractAddress.toString()}`, ); - } + const privateLog = this.#extractSingleLog(allPrivateLogsPerTag[i], `private log for tag ${siloedTags[i]}`); - const scopedLog = logsForTag[0]; + if (publicLog !== null && privateLog !== null) { + this.log.warn( + `Found both a public and private log for tag ${request.tag} from contract ${request.contractAddress}. This may indicate a contract bug. Returning the public log.`, + ); + } - return new LogRetrievalResponse( - scopedLog.logData.slice(1), // Skip the tag - scopedLog.txHash, - scopedLog.noteHashes, - scopedLog.firstNullifier, - ); + return publicLog ?? privateLog; + }); } - async #getPrivateLogByTag(siloedTag: SiloedTag): Promise { - const anchorBlockHash = await this.anchorBlockHeader.hash(); - const allLogsPerTag = await getAllPrivateLogsByTags(this.aztecNode, [siloedTag], anchorBlockHash); - const logsForTag = allLogsPerTag[0]; - + #extractSingleLog(logsForTag: TxScopedL2Log[], description: string): LogRetrievalResponse | null { if (logsForTag.length === 0) { return null; - } else if (logsForTag.length > 1) { + } + + if (logsForTag.length > 1) { this.log.warn( - `Expected at most 1 private log for tag ${siloedTag}, got ${logsForTag.length}. This may indicate a contract bug. Returning the first log.`, + `Expected at most 1 ${description}, got ${logsForTag.length}. This may indicate a contract bug. Returning the first log.`, ); } From b168b4645859459a5d7037f6a0fc526902e1f94b Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Wed, 6 May 2026 11:14:38 -0400 Subject: [PATCH 14/30] feat(aztec-nr): Initial handshake registry contract with non interactive handshake function (#22854) cherry-pick of e67f943399 with unresolved conflicts (markers preserved in history) --- noir-projects/noir-contracts/Nargo.toml | 1 + .../handshake_registry_contract/Nargo.toml | 8 + .../src/handshake_note.nr | 43 +++ .../handshake_registry_contract/src/main.nr | 111 ++++++++ .../handshake_registry_contract/src/test.nr | 247 ++++++++++++++++++ .../crates/types/src/constants.nr | 7 + .../crates/types/src/constants_tests.nr | 25 ++ yarn-project/constants/src/constants.gen.ts | 2 + 8 files changed, 444 insertions(+) create mode 100644 noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/Nargo.toml create mode 100644 noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr create mode 100644 noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/main.nr create mode 100644 noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/test.nr diff --git a/noir-projects/noir-contracts/Nargo.toml b/noir-projects/noir-contracts/Nargo.toml index 9c27bb799841..218e7469ef6c 100644 --- a/noir-projects/noir-contracts/Nargo.toml +++ b/noir-projects/noir-contracts/Nargo.toml @@ -26,6 +26,7 @@ members = [ "contracts/app/simple_token_contract", "contracts/fees/fpc_contract", "contracts/fees/sponsored_fpc_contract", + "contracts/message_discovery/handshake_registry_contract", "contracts/protocol/auth_registry_contract", "contracts/protocol/contract_class_registry_contract", "contracts/protocol/contract_instance_registry_contract", diff --git a/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/Nargo.toml new file mode 100644 index 000000000000..9ce353b45066 --- /dev/null +++ b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "handshake_registry_contract" +authors = [""] +compiler_version = ">=0.25.0" +type = "contract" + +[dependencies] +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr new file mode 100644 index 000000000000..1dcab11ae235 --- /dev/null +++ b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/handshake_note.nr @@ -0,0 +1,43 @@ +use aztec::{ + macros::notes::note, + protocol::{ + address::AztecAddress, + constants::DOM_SEP__HANDSHAKE_SECRET_HASH, + hash::poseidon2_hash_with_separator, + point::Point, + traits::{Deserialize, Packable, Serialize}, + }, +}; + +/// A record of a handshake established by the note's owner (the sender). +/// +/// Stored in [`crate::HandshakeRegistry`]'s `handshakes` set. Holds the **hash** of the master shared secret. +/// A contract that wants to use this handshake will later prove the note's existence and +/// use the kernel key-validation mechanism to derive its own app-siloed secret from the master, so +/// the master is never exposed to dependent contracts. +#[derive(Deserialize, Eq, Packable, Serialize)] +#[note] +pub struct HandshakeNote { + /// Hash of the master shared secret: `poseidon2_hash_with_separator([S.x, S.y], DOM_SEP__HANDSHAKE_SECRET_HASH)` + /// over the raw ECDH point `S = eph_sk * recipient_address_point`. + pub secret_hash: Field, + /// Stored so contracts can constrain the kind of handshake they accept (e.g. an app may want to require interactive + /// handshakes only). + pub handshake_type: u8, + /// The recipient this handshake authorizes. Part of the note preimage so a contract proving note + /// existence can bind the proof to the intended recipient. + pub recipient: AztecAddress, +} + +impl HandshakeNote { + pub fn new(shared_secret: Point, handshake_type: u8, recipient: AztecAddress) -> Self { + Self { + secret_hash: poseidon2_hash_with_separator( + [shared_secret.x, shared_secret.y], + DOM_SEP__HANDSHAKE_SECRET_HASH, + ), + handshake_type, + recipient, + } + } +} diff --git a/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/main.nr b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/main.nr new file mode 100644 index 000000000000..08523cf279ec --- /dev/null +++ b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/main.nr @@ -0,0 +1,111 @@ +use aztec::macros::aztec; +mod handshake_note; +mod test; + +/// Handshake type identifier for non-interactive handshakes (sender-generated random shared secret, no recipient +/// signature). See [`HandshakeRegistry::non_interactive_handshake`]. +pub(crate) global NON_INTERACTIVE_HANDSHAKE: u8 = 1; + +/// Registry for the constrained-delivery shared-secret handshake protocol. +/// +/// The registry's job is to establish a master shared secret between a sender and a recipient, and to store a +/// per-sender note recording that the handshake happened. A contract that later wants to use this +/// handshake retrieves the note via the [`HandshakeRegistry::get_handshake`] utility, asserts it exists in the +/// registry, +/// and uses the kernel key-validation mechanism to derive its own app-siloed shared secret from the master hash stored +/// in the note. +/// +/// Currently only implements the non-interactive flow (see [`HandshakeRegistry::non_interactive_handshake`]). +#[aztec] +pub contract HandshakeRegistry { + use crate::handshake_note::HandshakeNote; + use crate::NON_INTERACTIVE_HANDSHAKE; + use aztec::{ + keys::{ecdh_shared_secret::derive_ecdh_shared_secret, ephemeral::generate_positive_ephemeral_key_pair}, + macros::{functions::external, storage::storage}, + messages::message_delivery::MessageDelivery, + note::note_viewer_options::NoteViewerOptions, + oracle::notes::set_sender_for_tags, + protocol::{ + address::AztecAddress, constants::DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, hash::compute_log_tag, + traits::ToField, + }, + state_vars::{Owned, PrivateSet}, + }; + + #[storage] + struct Storage { + /// Per-sender set of [`HandshakeNote`]s. The sender is chosen by the caller and is unconstrained throughout the + /// constrained-delivery protocol. + handshakes: Owned, Context>, + } + + /// Performs a non-interactive handshake from `sender` to `recipient`. + /// + /// Generates a fresh ephemeral key pair `(eph_sk, eph_pk)`, computes the raw ECDH shared secret point + /// `S = eph_sk * recipient_address_point`, and produces two effects: + /// + /// 1. Inserts a [`HandshakeNote`] owned by `sender`. + /// 2. Emits a 1-field private log under a recipient-keyed tag with payload `[eph_pk.x]`. The recipient + /// discovers handshakes addressed to them by scanning their tag and recovers the master shared secret + /// from `eph_pk` via their own ECDH (`recipient_isk * eph_pk`). `eph_pk.y` is fixed positive by the + /// [`generate_positive_ephemeral_key_pair`] convention, so only `eph_pk.x` is transmitted. + /// + /// # Panics + /// If `recipient` is not a valid curve point. There are no upstream side effects in this call frame to + /// protect, and a fallback would insert a permanent note recording a handshake with an invalid recipient, + /// polluting registry state. + #[external("private")] + fn non_interactive_handshake(sender: AztecAddress, recipient: AztecAddress) { + let recipient_point = recipient.to_address_point().expect(f"recipient address is not on the curve"); + + let (eph_sk, eph_pk) = generate_positive_ephemeral_key_pair(); + let s_raw = derive_ecdh_shared_secret(eph_sk, recipient_point.inner); + + let note = HandshakeNote::new(s_raw, NON_INTERACTIVE_HANDSHAKE, recipient); + + // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs, so it + // is safe to set from a constrained context. + unsafe { set_sender_for_tags(sender) }; + // Delivery is `ONCHAIN_UNCONSTRAINED`. The recipient is not involved in this note's delivery. They + // discover the handshake via the recipient-keyed log emitted below, not via the sender's note. + // We use onchain unconstrained delivery rather than `OFFCHAIN` so the note is + // discoverable via normal PXE sync. + self.storage.handshakes.at(sender).insert(note).deliver(MessageDelivery.ONCHAIN_UNCONSTRAINED); + + let log_tag = compute_log_tag( + recipient.to_field(), + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + ); + self.context.emit_private_log_vec_unsafe(log_tag, BoundedVec::from_array([eph_pk.x])); + } + + /// Returns the most recently inserted [`HandshakeNote`] held for `sender` matching + /// `(recipient, handshake_type)`, or `None` if no such note exists. + /// + /// Returning the latest (rather than the first) lets a sender re-initiate by issuing a fresh handshake; e.g. + /// if the previous secret was leaked. + /// + /// This is the discovery surface a contract uses to obtain a note hint before asserting existence + /// of the note at this registry's address. + #[external("utility")] + unconstrained fn get_handshake( + sender: AztecAddress, + recipient: AztecAddress, + handshake_type: u8, + ) -> Option { + // We pull all notes for `sender` and filter (recipient, handshake_type) below, walking from the end so the + // first hit is the most recently inserted match. + let notes = self.storage.handshakes.at(sender).view_notes(NoteViewerOptions::new()); + let mut found = Option::none(); + let len = notes.len(); + for i in 0..len { + let note = notes.get(len - 1 - i); + if (note.recipient == recipient) & (note.handshake_type == handshake_type) { + found = Option::some(note); + break; + } + } + found + } +} diff --git a/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/test.nr b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/test.nr new file mode 100644 index 000000000000..53ce5d2731cc --- /dev/null +++ b/noir-projects/noir-contracts/contracts/message_discovery/handshake_registry_contract/src/test.nr @@ -0,0 +1,247 @@ +use crate::{HandshakeRegistry, NON_INTERACTIVE_HANDSHAKE}; + +use aztec::{ + protocol::{ + address::AztecAddress, + constants::DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + hash::{compute_log_tag, compute_siloed_private_log_first_field}, + traits::{FromField, ToField}, + }, + test::helpers::{test_environment::TestEnvironment, txe_oracles}, +}; + +unconstrained fn setup() -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress) { + let mut env = TestEnvironment::new(); + + let sender = env.create_light_account(); + let other_sender = env.create_light_account(); + let recipient = env.create_light_account(); + + let registry_address = env.deploy("HandshakeRegistry").without_initializer(); + + (env, registry_address, sender, other_sender, recipient) +} + +unconstrained fn setup_with_two_recipients() -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress) { + let mut env = TestEnvironment::new(); + + let sender = env.create_light_account(); + let recipient_a = env.create_light_account(); + let recipient_b = env.create_light_account(); + + let registry_address = env.deploy("HandshakeRegistry").without_initializer(); + + (env, registry_address, sender, recipient_a, recipient_b) +} + +#[test] +unconstrained fn non_interactive_handshake_stores_recipient_bound_note_at_sender() { + let (env, registry_address, sender, _, recipient) = setup(); + let registry = HandshakeRegistry::at(registry_address); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient)); + + let note = env.execute_utility(registry.get_handshake(sender, recipient, NON_INTERACTIVE_HANDSHAKE)).expect( + f"handshake note should be present", + ); + assert_eq(note.handshake_type, NON_INTERACTIVE_HANDSHAKE); + assert_eq(note.recipient, recipient); + // TODO: `secret_hash` is the hash of the raw ECDH point components. Without an storing the raw point in an oracle + // we + // can't reconstruct it from the recipient's side here, so we just check that something non-zero was stored. + assert(note.secret_hash != 0, "secret_hash should be set"); +} + +#[test] +unconstrained fn handshakes_are_isolated_per_sender() { + let (env, registry_address, sender, other_sender, recipient) = setup(); + let registry = HandshakeRegistry::at(registry_address); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient)); + assert( + env.execute_utility(registry.get_handshake(other_sender, recipient, NON_INTERACTIVE_HANDSHAKE)).is_none(), + "other sender should not see primary sender's handshake", + ); + + env.call_private(other_sender, registry.non_interactive_handshake(other_sender, recipient)); + + let sender_note = env.execute_utility(registry.get_handshake(sender, recipient, NON_INTERACTIVE_HANDSHAKE)).expect( + f"primary sender should see its handshake", + ); + let other_sender_note = env + .execute_utility(registry.get_handshake(other_sender, recipient, NON_INTERACTIVE_HANDSHAKE)) + .expect(f"other sender should see its handshake"); + + assert( + sender_note.secret_hash != other_sender_note.secret_hash, + "senders should not resolve to the same handshake", + ); +} + +// The DH-direct flow lifts `recipient` to a curve point and fails loud if the address has no +// corresponding point. We deliberately do not replicate AES128's "king of the hill" fallback here; see +// the doc comment on [`HandshakeRegistry::non_interactive_handshake`] for the rationale. +#[test(should_fail_with = "recipient address is not on the curve")] +unconstrained fn handshake_to_invalid_recipient_panics() { + let (env, registry_address, sender, _, _) = setup(); + let registry = HandshakeRegistry::at(registry_address); + + // x = 3 is a non-residue for the curve, so this address has no corresponding address point. + let invalid_recipient = AztecAddress::from_field(3); + assert(!invalid_recipient.is_valid()); + + env.call_private(sender, registry.non_interactive_handshake(sender, invalid_recipient)); +} + +// A recipient who knows only their own address can compute the +// expected tag, find the log under it, and recover `eph_pk.x` from the payload. +#[test] +unconstrained fn non_interactive_handshake_emits_recipient_discoverable_log() { + let (env, registry_address, sender, _, recipient) = setup(); + let registry = HandshakeRegistry::at(registry_address); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient)); + + // The function emits two private logs in order: log 0 is the encrypted note delivered via + // `MessageDelivery.ONCHAIN_UNCONSTRAINED`, log 1 is the recipient-keyed announcement carrying + // `eph_pk.x` under a recipient-derivable tag. + let logs = txe_oracles::get_last_tx_effects().private_logs; + assert_eq(logs.len(), 2); + + let raw_tag = compute_log_tag( + recipient.to_field(), + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + ); + let expected_siloed_tag = compute_siloed_private_log_first_field(registry_address, raw_tag); + + // siloed tag (1) + eph_pk.x (1) = 2 fields. + let log_data = logs.get(1); + assert_eq(log_data.len(), 2); + assert_eq(log_data.get(0), expected_siloed_tag); + let eph_pk_x = log_data.get(1); + assert(eph_pk_x != 0, "eph_pk.x should be non-zero"); +} + +// The handshake tag depends only on the recipient, so multiple senders posting to the same recipient +// land under one key. Each emitted log carries its own ephemeral key. +#[test] +unconstrained fn two_senders_to_same_recipient_share_tag_with_distinct_payloads() { + let (env, registry_address, sender, other_sender, recipient) = setup(); + let registry = HandshakeRegistry::at(registry_address); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient)); + let logs_first = txe_oracles::get_last_tx_effects().private_logs; + assert_eq(logs_first.len(), 2); + + env.call_private(other_sender, registry.non_interactive_handshake(other_sender, recipient)); + let logs_second = txe_oracles::get_last_tx_effects().private_logs; + assert_eq(logs_second.len(), 2); + + let raw_tag = compute_log_tag( + recipient.to_field(), + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + ); + let expected_siloed_tag = compute_siloed_private_log_first_field(registry_address, raw_tag); + assert_eq(logs_first.get(1).get(0), expected_siloed_tag); + assert_eq(logs_second.get(1).get(0), expected_siloed_tag); + + let eph_pk_x_0 = logs_first.get(1).get(1); + let eph_pk_x_1 = logs_second.get(1).get(1); + assert(eph_pk_x_0 != eph_pk_x_1, "ephemeral keys should differ in handshakes from different senders"); +} + +// Two handshakes from the same sender to the same `(recipient, type)` are not deduplicated. +// Each call generates a fresh ephemeral key, so the registry accumulates distinct notes and emits +// distinct logs under the recipient's tag. +#[test] +unconstrained fn duplicate_handshake_accumulates_distinct_secrets_and_returns_latest() { + let (env, registry_address, sender, _, recipient) = setup(); + let registry = HandshakeRegistry::at(registry_address); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient)); + let logs_first = txe_oracles::get_last_tx_effects().private_logs; + assert_eq(logs_first.len(), 2); + let first = env.execute_utility(registry.get_handshake(sender, recipient, NON_INTERACTIVE_HANDSHAKE)).expect( + f"first handshake note should be present", + ); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient)); + let logs_second = txe_oracles::get_last_tx_effects().private_logs; + assert_eq(logs_second.len(), 2); + let latest = env.execute_utility(registry.get_handshake(sender, recipient, NON_INTERACTIVE_HANDSHAKE)).expect( + f"second handshake note should be present", + ); + + let raw_tag = compute_log_tag( + recipient.to_field(), + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + ); + let expected_siloed_tag = compute_siloed_private_log_first_field(registry_address, raw_tag); + assert_eq(logs_first.get(1).get(0), expected_siloed_tag); + assert_eq(logs_second.get(1).get(0), expected_siloed_tag); + + assert( + logs_first.get(1).get(1) != logs_second.get(1).get(1), + "ephemeral keys should differ across repeated handshakes", + ); + + assert(first.secret_hash != latest.secret_hash, "should return the most recent note, not the first"); +} + +#[test] +unconstrained fn different_recipients_have_different_tags() { + let (env, registry_address, sender, recipient_a, recipient_b) = setup_with_two_recipients(); + let registry = HandshakeRegistry::at(registry_address); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient_a)); + let logs_a = txe_oracles::get_last_tx_effects().private_logs; + assert_eq(logs_a.len(), 2); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient_b)); + let logs_b = txe_oracles::get_last_tx_effects().private_logs; + assert_eq(logs_b.len(), 2); + + let tag_a = compute_log_tag( + recipient_a.to_field(), + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + ); + let tag_b = compute_log_tag( + recipient_b.to_field(), + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + ); + assert(tag_a != tag_b, "recipient-keyed tags must differ"); + + assert(logs_a.get(1).get(0) != logs_b.get(1).get(0), "tags in logs differ"); +} + +#[test] +unconstrained fn get_handshake_returns_none_for_wrong_sender() { + let (env, registry_address, sender, other_sender, recipient) = setup(); + let registry = HandshakeRegistry::at(registry_address); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient)); + + assert(env.execute_utility(registry.get_handshake(other_sender, recipient, NON_INTERACTIVE_HANDSHAKE)).is_none()); +} + +#[test] +unconstrained fn get_handshake_returns_none_for_wrong_recipient() { + let (env, registry_address, sender, recipient_a, recipient_b) = setup_with_two_recipients(); + let registry = HandshakeRegistry::at(registry_address); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient_a)); + + assert(env.execute_utility(registry.get_handshake(sender, recipient_b, NON_INTERACTIVE_HANDSHAKE)).is_none()); +} + +#[test] +unconstrained fn get_handshake_returns_none_for_wrong_handshake_type() { + let (env, registry_address, sender, _, recipient) = setup(); + let registry = HandshakeRegistry::at(registry_address); + + env.call_private(sender, registry.non_interactive_handshake(sender, recipient)); + + // Claim it was something other than the only currently-defined handshake type. + let unknown_handshake_type: u8 = NON_INTERACTIVE_HANDSHAKE + 1; + assert(env.execute_utility(registry.get_handshake(sender, recipient, unknown_handshake_type)).is_none()); +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 16fd271a96b6..3a83149db68e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -680,6 +680,9 @@ pub global DOM_SEP__EVENT_LOG_TAG: u32 = 926040838; pub global DOM_SEP__NOTE_COMPLETION_LOG_TAG: u32 = 3372669888; /// Domain separator for unconstrained message delivery log tags. Used by [`crate::hash::compute_log_tag`]. pub global DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG: u32 = 1485357192; +/// Domain separator for non-interactive handshake log tags emitted by the handshake registry contract. Used by +/// [`crate::hash::compute_log_tag`]. +pub global DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG: u32 = 4046403018; /// Domain separator for private log tags. /// /// Used by [`crate::hash::compute_siloed_private_log_first_field`]. @@ -762,6 +765,10 @@ pub global DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER: u32 = 3990889078; /// Domain separator for L1 to L2 message secret hashes. pub global DOM_SEP__SECRET_HASH: u32 = 4199652938; +/// Domain separator for the secret hash stored in handshake notes produced by the handshake registry contract. +/// Kept distinct from [`DOM_SEP__SECRET_HASH`] (which is specifically for L1 to L2 messages). +pub global DOM_SEP__HANDSHAKE_SECRET_HASH: u32 = 3596796143; + /// Domain separator for transaction nullifiers. /// /// Used to produce cancellable (replaceable) transactions. diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr index 8ade1f4e9cbb..39acd55f9389 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr @@ -10,6 +10,7 @@ use crate::{ DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__CONTRACT_ADDRESS_V1, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY, DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FUNCTION_ARGS, +<<<<<<< HEAD DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, DOM_SEP__IVSK_M, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, DOM_SEP__OVSK_M, @@ -17,6 +18,18 @@ use crate::{ DOM_SEP__PRIVATE_FUNCTION_LEAF, DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, DOM_SEP__PRIVATE_LOG_FIRST_FIELD, DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, DOM_SEP__PUBLIC_BYTECODE, DOM_SEP__PUBLIC_CALLDATA, +======= + DOM_SEP__HANDSHAKE_SECRET_HASH, DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, + DOM_SEP__IVSK_M, DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_COMPLETION_LOG_TAG, + DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, + DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS, + DOM_SEP__PARTIAL_NOTE_COMMITMENT, + DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, DOM_SEP__PRIVATE_FUNCTION_LEAF, + DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, DOM_SEP__PRIVATE_LOG_FIRST_FIELD, + DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, DOM_SEP__PUBLIC_BYTECODE, + DOM_SEP__PUBLIC_CALLDATA, DOM_SEP__PUBLIC_DATA_MERKLE, +>>>>>>> e67f943399 (feat(aztec-nr): Initial handshake registry contract with non interactive handshake function (#22854)) DOM_SEP__PUBLIC_INITIALIZATION_NULLIFIER, DOM_SEP__PUBLIC_KEYS_HASH, DOM_SEP__PUBLIC_LEAF_SLOT, DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, DOM_SEP__PUBLIC_TX_HASH, DOM_SEP__SECRET_HASH, DOM_SEP__SIGNATURE_PAYLOAD, DOM_SEP__SILOED_NOTE_HASH, @@ -133,7 +146,11 @@ impl HashedValueTester::new(); +======= + let mut tester = HashedValueTester::<71, 64>::new(); +>>>>>>> e67f943399 (feat(aztec-nr): Initial handshake registry contract with non interactive handshake function (#22854)) // ----------------- // Domain separators @@ -166,6 +183,14 @@ fn hashed_values_match_derived() { DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, "unconstrained_msg_log_tag", ); + tester.assert_dom_sep_matches_derived( + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + "non_interactive_handshake_log_tag", + ); + tester.assert_dom_sep_matches_derived( + DOM_SEP__HANDSHAKE_SECRET_HASH, + "handshake_secret_hash", + ); tester.assert_dom_sep_matches_derived(DOM_SEP__MESSAGE_NULLIFIER, "message_nullifier"); tester.assert_dom_sep_matches_derived(DOM_SEP__PRIVATE_FUNCTION_LEAF, "private_function_leaf"); tester.assert_dom_sep_matches_derived(DOM_SEP__PUBLIC_BYTECODE, "public_bytecode"); diff --git a/yarn-project/constants/src/constants.gen.ts b/yarn-project/constants/src/constants.gen.ts index 44ba1b92873b..c47f9a4bf878 100644 --- a/yarn-project/constants/src/constants.gen.ts +++ b/yarn-project/constants/src/constants.gen.ts @@ -506,6 +506,7 @@ export enum DomainSeparator { EVENT_LOG_TAG = 926040838, NOTE_COMPLETION_LOG_TAG = 3372669888, UNCONSTRAINED_MSG_LOG_TAG = 1485357192, + NON_INTERACTIVE_HANDSHAKE_LOG_TAG = 4046403018, PRIVATE_LOG_FIRST_FIELD = 2769976252, PUBLIC_LEAF_SLOT = 1247650290, PUBLIC_STORAGE_MAP_SLOT = 4015149901, @@ -539,6 +540,7 @@ export enum DomainSeparator { PUBLIC_INITIALIZATION_NULLIFIER = 3342006647, PRIVATE_INITIALIZATION_NULLIFIER = 3990889078, SECRET_HASH = 4199652938, + HANDSHAKE_SECRET_HASH = 3596796143, TX_NULLIFIER = 1025801951, SIGNATURE_PAYLOAD = 463525807, } \ No newline at end of file From e62e1752072fe4f4e8a3924751d330a2261d3c80 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Thu, 7 May 2026 20:16:36 +0000 Subject: [PATCH 15/30] fix: resolve cherry-pick conflicts in constants_tests.nr Drop incoming entries that don't exist on v4-next (DOM_SEP__MERKLE_HASH, DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__PARTIAL_NOTE_COMMITMENT, DOM_SEP__PUBLIC_DATA_MERKLE) while keeping the two new ones added by #22854 (DOM_SEP__HANDSHAKE_SECRET_HASH, DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG). HashedValueTester sized <58, 51> = v4-next baseline <56, 49> + 2 new dom seps. --- .../crates/types/src/constants_tests.nr | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr index 39acd55f9389..e51bbd44c54a 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr @@ -10,26 +10,14 @@ use crate::{ DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__CONTRACT_ADDRESS_V1, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY, DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FUNCTION_ARGS, -<<<<<<< HEAD - DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, DOM_SEP__IVSK_M, - DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, DOM_SEP__NOTE_COMPLETION_LOG_TAG, + DOM_SEP__HANDSHAKE_SECRET_HASH, DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, + DOM_SEP__IVSK_M, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS, DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, DOM_SEP__PRIVATE_FUNCTION_LEAF, DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, DOM_SEP__PRIVATE_LOG_FIRST_FIELD, DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, DOM_SEP__PUBLIC_BYTECODE, DOM_SEP__PUBLIC_CALLDATA, -======= - DOM_SEP__HANDSHAKE_SECRET_HASH, DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, - DOM_SEP__IVSK_M, DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__NHK_M, - DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_COMPLETION_LOG_TAG, - DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, - DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS, - DOM_SEP__PARTIAL_NOTE_COMMITMENT, - DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, DOM_SEP__PRIVATE_FUNCTION_LEAF, - DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, DOM_SEP__PRIVATE_LOG_FIRST_FIELD, - DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, DOM_SEP__PUBLIC_BYTECODE, - DOM_SEP__PUBLIC_CALLDATA, DOM_SEP__PUBLIC_DATA_MERKLE, ->>>>>>> e67f943399 (feat(aztec-nr): Initial handshake registry contract with non interactive handshake function (#22854)) DOM_SEP__PUBLIC_INITIALIZATION_NULLIFIER, DOM_SEP__PUBLIC_KEYS_HASH, DOM_SEP__PUBLIC_LEAF_SLOT, DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, DOM_SEP__PUBLIC_TX_HASH, DOM_SEP__SECRET_HASH, DOM_SEP__SIGNATURE_PAYLOAD, DOM_SEP__SILOED_NOTE_HASH, @@ -146,11 +134,7 @@ impl HashedValueTester::new(); -======= - let mut tester = HashedValueTester::<71, 64>::new(); ->>>>>>> e67f943399 (feat(aztec-nr): Initial handshake registry contract with non interactive handshake function (#22854)) + let mut tester = HashedValueTester::<58, 51>::new(); // ----------------- // Domain separators From ffa6184b34ddd58d307fe9f49c8eb7fd8748200d Mon Sep 17 00:00:00 2001 From: AztecBot Date: Thu, 7 May 2026 21:06:05 +0000 Subject: [PATCH 16/30] chore: nargo fmt protocol-circuits constants --- .../noir-protocol-circuits/crates/types/src/constants.nr | 2 +- .../crates/types/src/constants_tests.nr | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 3a83149db68e..e03a2b0a79e0 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -765,7 +765,7 @@ pub global DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER: u32 = 3990889078; /// Domain separator for L1 to L2 message secret hashes. pub global DOM_SEP__SECRET_HASH: u32 = 4199652938; -/// Domain separator for the secret hash stored in handshake notes produced by the handshake registry contract. +/// Domain separator for the secret hash stored in handshake notes produced by the handshake registry contract. /// Kept distinct from [`DOM_SEP__SECRET_HASH`] (which is specifically for L1 to L2 messages). pub global DOM_SEP__HANDSHAKE_SECRET_HASH: u32 = 3596796143; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr index e51bbd44c54a..6656218d0eb3 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants_tests.nr @@ -171,10 +171,7 @@ fn hashed_values_match_derived() { DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, "non_interactive_handshake_log_tag", ); - tester.assert_dom_sep_matches_derived( - DOM_SEP__HANDSHAKE_SECRET_HASH, - "handshake_secret_hash", - ); + tester.assert_dom_sep_matches_derived(DOM_SEP__HANDSHAKE_SECRET_HASH, "handshake_secret_hash"); tester.assert_dom_sep_matches_derived(DOM_SEP__MESSAGE_NULLIFIER, "message_nullifier"); tester.assert_dom_sep_matches_derived(DOM_SEP__PRIVATE_FUNCTION_LEAF, "private_function_leaf"); tester.assert_dom_sep_matches_derived(DOM_SEP__PUBLIC_BYTECODE, "public_bytecode"); From ffa85e45b14c43ee256c029a86112ce7aaa3a3a1 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 13:27:42 +0000 Subject: [PATCH 17/30] fix: backport Tag.random() to fix log_service.test.ts build --- yarn-project/stdlib/src/logs/tag.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/yarn-project/stdlib/src/logs/tag.ts b/yarn-project/stdlib/src/logs/tag.ts index c16771da9f8c..6fd4dad8b198 100644 --- a/yarn-project/stdlib/src/logs/tag.ts +++ b/yarn-project/stdlib/src/logs/tag.ts @@ -1,5 +1,5 @@ import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon'; -import type { Fr } from '@aztec/foundation/curves/bn254'; +import { Fr } from '@aztec/foundation/curves/bn254'; import type { ZodFor } from '@aztec/foundation/schemas'; import { schemas } from '../schemas/schemas.js'; @@ -36,6 +36,10 @@ export class Tag { return this.value.equals(other.value); } + static random(): Tag { + return new Tag(Fr.random()); + } + static get schema(): ZodFor { return schemas.Fr.transform((fr: Fr) => new Tag(fr)); } From 216c87ed0bc2c0857de7e20d0ff2796bb9ff6614 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 13:30:30 +0000 Subject: [PATCH 18/30] fix: add Tag.random() helper required by backported #23088 tests --- yarn-project/stdlib/src/logs/tag.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/yarn-project/stdlib/src/logs/tag.ts b/yarn-project/stdlib/src/logs/tag.ts index c16771da9f8c..6fd4dad8b198 100644 --- a/yarn-project/stdlib/src/logs/tag.ts +++ b/yarn-project/stdlib/src/logs/tag.ts @@ -1,5 +1,5 @@ import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon'; -import type { Fr } from '@aztec/foundation/curves/bn254'; +import { Fr } from '@aztec/foundation/curves/bn254'; import type { ZodFor } from '@aztec/foundation/schemas'; import { schemas } from '../schemas/schemas.js'; @@ -36,6 +36,10 @@ export class Tag { return this.value.equals(other.value); } + static random(): Tag { + return new Tag(Fr.random()); + } + static get schema(): ZodFor { return schemas.Fr.transform((fr: Fr) => new Tag(fr)); } From e03f5658608da81db1d049cd26d654dfc520654e Mon Sep 17 00:00:00 2001 From: critesjosh Date: Fri, 8 May 2026 12:30:49 -0400 Subject: [PATCH 19/30] docs: complete backport of #22543 with script improvements and skill updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original cherry-pick of 6fd76de513 carried only the first commit of PR #22543's five-commit feature branch, leaving the script using the pre-22543 build-required check and missing the SKILL.md/CLAUDE.md/README.md documentation that landed alongside. Bring this backport in line with PR #22543's final merged state: - Replace the .sh `stdlib/dest/` build check with source-file + node_modules checks (no yarn-project build needed). - Apply the .ts generator improvements: optional handling order, array parenthesization, BlockHash in BlockParameterSchema, JSDoc index fix, name-aware example params, remarks rendering, fallback warnings. - Add Step 5a (Regenerate Node API Reference) to release-network-docs SKILL.md plus the matching Key Points entry. - Document `yarn generate:node-api-reference` in docs/CLAUDE.md and add the Node JSON-RPC API Reference section to docs/README.md. - Regenerate docs-operate/.../node-api-reference.md against this branch's yarn-project interfaces (64 methods, 55 node + 9 admin). METHOD_GROUPS adjustments for this branch's API surface: re-add getSlashPayloads to the admin group (still present in aztec-node-admin.ts here) and drop getPredictedMinFees from the fees group (not yet present here). The version-v2.1.11-ignition snapshot is left untouched — its content reflects that release's API and would be corrupted by regenerating against HEAD. --- .claude/skills/release-network-docs/SKILL.md | 33 ++++++- docs/CLAUDE.md | 2 + docs/README.md | 38 ++++++++ .../operators/reference/node-api-reference.md | 95 ++++++++----------- .../generate_node_api_reference.sh | 20 +++- .../generate_node_api_reference.ts | 78 +++++++++------ 6 files changed, 181 insertions(+), 85 deletions(-) diff --git a/.claude/skills/release-network-docs/SKILL.md b/.claude/skills/release-network-docs/SKILL.md index 7476f89631fc..0307e1c2f4d6 100644 --- a/.claude/skills/release-network-docs/SKILL.md +++ b/.claude/skills/release-network-docs/SKILL.md @@ -21,12 +21,15 @@ self-identify its release type, ask the user to confirm. **This skill does NOT:** -- Generate API docs (aztec-nr or TypeScript) +- Generate developer API docs (aztec-nr or TypeScript) - Generate CLI reference docs - Update developer version config or cut developer versioned docs - Update migration notes - Require aztec CLI, nargo, or yarn-project build +**This skill DOES** regenerate the Node JSON-RPC API reference for the +versioned docs (see Step 5a). + ## Usage ``` @@ -165,7 +168,29 @@ Ask the user if any content changes are needed in `docs/docs-operate/`: - Operator changelog updates (if not handled by `/updating-changelog`) If the user has content changes, apply them to the source files in -`docs/docs-operate/`. If no content changes are needed, skip to Step 6. +`docs/docs-operate/`. If no content changes are needed, skip to Step 5a. + +### Step 5a: Regenerate Node API Reference + +The Node JSON-RPC API reference is auto-generated from TypeScript source. It +must be regenerated from the release tag's source files to ensure the versioned +docs reflect the actual API at that release. + +```bash +cd docs +yarn generate:node-api-reference +``` + +This writes to `docs/docs-operate/operators/reference/node-api-reference.md` +using the source files from the currently checked-out tag. The generator parses +`yarn-project/stdlib/src/interfaces/aztec-node.ts` and +`yarn-project/stdlib/src/interfaces/aztec-node-admin.ts` directly (no +yarn-project build needed, but `yarn-project/node_modules/` must be installed +so `npx tsx` can resolve `typescript` — run `yarn install` from `yarn-project` +if needed). + +Verify the output lists the expected number of methods and has no ungrouped +methods warnings. ### Step 6: Build and Validate @@ -284,6 +309,10 @@ Check for stash conflicts. Then report to the user: - **No heavy prerequisites**: This skill does not require aztec CLI, nargo, or a yarn-project build. Only `yarn` (for the docs build), `curl`/`jq` (for the RPC query), and `cast` (for on-chain address queries) are needed. +- **Node API reference is auto-generated**: Run `yarn generate:node-api-reference` + (Step 5a) before building. The generator parses TypeScript source directly, so + no yarn-project build is required — but `yarn-project/node_modules/` must exist + (run `yarn install` from `yarn-project` if missing). - **Build must pass**: Do not cut versioned docs until `yarn build` succeeds. - **COMMIT_TAG needs `v` prefix**: The preprocessor uses COMMIT_TAG for GitHub URLs and git tag references. Omitting the `v` will break links in versioned diff --git a/docs/CLAUDE.md b/docs/CLAUDE.md index c39fe15835ef..107ff5502d51 100644 --- a/docs/CLAUDE.md +++ b/docs/CLAUDE.md @@ -29,6 +29,8 @@ This project uses Yarn 4.5.2 as specified in the `packageManager` field of packa - `yarn generate:typescript-api` - Generate TypeScript API docs (requires yarn-project to be built) - `yarn generate:typescript-api v3.0.0-devnet.6` - Generate for a specific version - `RELEASE_TYPE=mainnet yarn generate:typescript-api v4.2.0` - Generate with explicit release type +- `yarn generate:node-api-reference` - Generate Node JSON-RPC API reference (requires yarn-project source files and yarn-project/node_modules; no build needed) +- `yarn generate:node-api-reference --target-dir ` - Generate into a specific versioned docs directory The `RELEASE_TYPE` env var overrides version string pattern matching for output folder selection. This is useful when the version string doesn't self-identify its release type. diff --git a/docs/README.md b/docs/README.md index ba2a1e4de1d8..158de3509dee 100644 --- a/docs/README.md +++ b/docs/README.md @@ -270,6 +270,44 @@ yarn generate:typescript-api v3.0.0-devnet.6 The generated docs are linked from the [TypeScript API Reference](/developers/docs/aztec-js/typescript_api_reference) page. +### Node JSON-RPC API Reference + +The Node JSON-RPC API reference is auto-generated from the TypeScript interface definitions and Zod schemas in `yarn-project/stdlib/src/interfaces/`. The generator parses the source AST to extract method names, JSDoc comments, and parameter/return types. + +**Source files:** + +- `yarn-project/stdlib/src/interfaces/aztec-node.ts` — `AztecNode` interface (`node_` methods) +- `yarn-project/stdlib/src/interfaces/aztec-node-admin.ts` — `AztecNodeAdmin` interface (`nodeAdmin_` methods) +- `yarn-project/stdlib/src/block/l2_block_source.ts` — `L2BlockSource` interface (JSDoc for inherited methods) + +**Prerequisites:** `yarn-project` must have `node_modules/` installed so `npx tsx` can resolve `typescript`. Run `yarn install` from `yarn-project` if needed. No build is required — the generator parses source `.ts` files via the TypeScript Compiler API, not compiled output. + +**Generate the reference doc:** + +```bash +yarn generate:node-api-reference +``` + +This writes to `docs-operate/operators/reference/node-api-reference.md`. + +**Generate for a specific versioned docs directory:** + +```bash +yarn generate:node-api-reference --target-dir network_versioned_docs/version-v4.1.3/operators/reference +``` + +**How it works:** + +1. Parses TypeScript interfaces with the TS Compiler API to extract JSDoc comments +2. Parses Zod schema object literals from source AST to enumerate methods and extract types +3. Generates markdown with method grouping, curl examples, and admin API security warnings + +**When to regenerate:** + +- When interface methods or Zod schemas change in `yarn-project/stdlib/src/interfaces/` +- When cutting a new versioned snapshot of network docs (pass `--target-dir` to write into the versioned directory) +- The source doc (`docs-operate/`) should be kept in sync with the latest code + ## Macros As mentioned above, Aztec docs pull code from the source files. This makes it easy to include sections of the source code in tutorials and other examples. diff --git a/docs/docs-operate/operators/reference/node-api-reference.md b/docs/docs-operate/operators/reference/node-api-reference.md index d2a6e90e3313..cb51c1f26fa3 100644 --- a/docs/docs-operate/operators/reference/node-api-reference.md +++ b/docs/docs-operate/operators/reference/node-api-reference.md @@ -109,9 +109,9 @@ Get a block specified by its block number or 'latest'. **Parameters**: -1. `blockParameter` - `number | "latest"` - The block parameter (block number, block hash, or 'latest'). +1. `blockParameter` - `BlockHash | number | "latest"` - The block parameter (block number, block hash, or 'latest'). -**Returns**: `L2Block` - The requested block. +**Returns**: `L2Block | undefined` - The requested block. **Example**: @@ -129,7 +129,7 @@ Get a block specified by its hash. 1. `blockHash` - `BlockHash` - The block hash being requested. -**Returns**: `L2Block` - The requested block. +**Returns**: `L2Block | undefined` - The requested block. **Example**: @@ -147,7 +147,7 @@ Get a block specified by its archive root. 1. `archive` - `Fr` - The archive root being requested. -**Returns**: `L2Block` - The requested block. +**Returns**: `L2Block | undefined` - The requested block. **Example**: @@ -173,7 +173,7 @@ Method to request blocks. Will attempt to return all requested blocks but will r ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getBlocks","params":[12345,12345],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getBlocks","params":[1,100],"id":1}' ``` ### node_getBlockHeader @@ -182,9 +182,9 @@ Returns the block header for a given block number, block hash, or 'latest'. **Parameters**: -1. `block` - `number | "latest" | undefined` - The block parameter (block number, block hash, or 'latest'). Defaults to 'latest'. +1. `block` - `BlockHash | number | "latest" | undefined` - The block parameter (block number, block hash, or 'latest'). Defaults to 'latest'. -**Returns**: `BlockHeader` - The requested block header. +**Returns**: `BlockHeader | undefined` - The requested block header. **Example**: @@ -202,7 +202,7 @@ Get a block header specified by its archive root. 1. `archive` - `Fr` - The archive root being requested. -**Returns**: `BlockHeader` - The requested block header. +**Returns**: `BlockHeader | undefined` - The requested block header. **Example**: @@ -228,7 +228,7 @@ Retrieves a collection of checkpoints. ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getCheckpoints","params":[12345,12345],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getCheckpoints","params":[1,100],"id":1}' ``` ### node_getCheckpointedBlocks @@ -245,7 +245,7 @@ curl -X POST http://localhost:8080 \ ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getCheckpointedBlocks","params":[12345,12345],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getCheckpointedBlocks","params":[1,100],"id":1}' ``` ### node_getCheckpointsDataForEpoch @@ -332,7 +332,7 @@ Method to retrieve a single pending tx. 1. `txHash` - `TxHash` - The transaction hash to return. -**Returns**: `Tx` - The pending tx if it exists. +**Returns**: `Tx | undefined` - The pending tx if it exists. **Example**: @@ -376,7 +376,7 @@ Method to retrieve pending txs. ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPendingTxs","params":[12345,"0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPendingTxs","params":[100,"0x1234..."],"id":1}' ``` ### node_getPendingTxCount @@ -442,9 +442,12 @@ curl -X POST http://localhost:8080 \ Gets the storage value at the given contract storage slot. +**Remarks**: The storage slot here refers to the slot as it is defined in Noir not the index in the merkle tree. +Aztec's version of `eth_getStorageAt`. + **Parameters**: -1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +1. `referenceBlock` - `BlockHash | number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. 2. `contract` - `AztecAddress` - Address of the contract to query. 3. `slot` - `Fr` - Slot to query. @@ -483,11 +486,11 @@ the leaves were inserted. **Parameters**: -1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +1. `referenceBlock` - `BlockHash | number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. 2. `treeId` - `MerkleTreeId` - The tree to search in. 3. `leafValues` - `Fr[]` - The values to search for. -**Returns**: `DataInBlock | undefined[]` - The indices of leaves and the block metadata of a block in which the leaves were inserted. +**Returns**: `(DataInBlock | undefined)[]` - The indices of leaves and the block metadata of a block in which the leaves were inserted. **Example**: @@ -503,10 +506,10 @@ Returns a nullifier membership witness for a given nullifier at a given block. **Parameters**: -1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +1. `referenceBlock` - `BlockHash | number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. 2. `nullifier` - `Fr` - Nullifier we try to find witness for. -**Returns**: `NullifierMembershipWitness` - The nullifier membership witness (if found). +**Returns**: `NullifierMembershipWitness | undefined` - The nullifier membership witness (if found). **Example**: @@ -520,12 +523,16 @@ curl -X POST http://localhost:8080 \ Returns a low nullifier membership witness for a given nullifier at a given block. +**Remarks**: Low nullifier witness can be used to perform a nullifier non-inclusion proof by leveraging the "linked +list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier +we are trying to prove non-inclusion for. + **Parameters**: -1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +1. `referenceBlock` - `BlockHash | number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. 2. `nullifier` - `Fr` - Nullifier we try to find the low nullifier witness for. -**Returns**: `NullifierMembershipWitness` - The low nullifier membership witness (if found). +**Returns**: `NullifierMembershipWitness | undefined` - The low nullifier membership witness (if found). **Example**: @@ -539,12 +546,16 @@ curl -X POST http://localhost:8080 \ Returns a public data tree witness for a given leaf slot at a given block. +**Remarks**: The witness can be used to compute the current value of the public data tree leaf. If the low leaf preimage corresponds to an +"in range" slot, means that the slot doesn't exist and the value is 0. If the low leaf preimage corresponds to the exact slot, the current value +is contained in the leaf preimage. + **Parameters**: -1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +1. `referenceBlock` - `BlockHash | number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. 2. `leafSlot` - `Fr` - The leaf slot we try to find the witness for. -**Returns**: `PublicDataWitness` - The public data witness (if found). +**Returns**: `PublicDataWitness | undefined` - The public data witness (if found). **Example**: @@ -565,7 +576,7 @@ a specific block exists in the chain's history. **Parameters**: -1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data +1. `referenceBlock` - `BlockHash | number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data (which contains the root of the archive tree in which we are searching for the block hash). 2. `blockHash` - `BlockHash` - The block hash to find in the archive tree. @@ -585,7 +596,7 @@ Returns a membership witness for a given note hash at a given block. **Parameters**: -1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +1. `referenceBlock` - `BlockHash | number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. 2. `noteHash` - `Fr` - The note hash we try to find the witness for. **Returns**: `MembershipWitness | undefined` @@ -606,7 +617,7 @@ Returns the index and a sibling path for a leaf in the committed l1 to l2 data t **Parameters**: -1. `referenceBlock` - `number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. +1. `referenceBlock` - `BlockHash | number | "latest"` - The block parameter (block number, block hash, or 'latest') at which to get the data. 2. `l1ToL2Message` - `Fr` - The l1ToL2Message to get the index / sibling path for. **Returns**: `[bigint, SiblingPath] | undefined` - A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found). @@ -736,7 +747,7 @@ for a tag, the caller should fetch the next page to check for more logs. ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPrivateLogsByTags","params":[["0x1234..."],12345,"0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPrivateLogsByTags","params":[["0x1234..."],0,"0x1234..."],"id":1}' ``` ### node_getPublicLogsByTagsFromContract @@ -762,7 +773,7 @@ for a tag, the caller should fetch the next page to check for more logs. ```bash curl -X POST http://localhost:8080 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPublicLogsByTagsFromContract","params":["0x1234...",["0x1234..."],12345,"0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"node_getPublicLogsByTagsFromContract","params":["0x1234...",["0x1234..."],0,"0x1234..."],"id":1}' ``` ## Contract queries @@ -821,26 +832,6 @@ curl -X POST http://localhost:8080 \ -d '{"jsonrpc":"2.0","method":"node_getCurrentMinFees","params":[],"id":1}' ``` -### node_getPredictedMinFees - -Returns predicted min fees for the current slot and next N slots. -Each entry accounts for the L1 gas oracle transition and congestion growth based on the -given mana usage estimate. Defaults to target usage (steady state). - -**Parameters**: - -1. `manaUsage` - `ManaUsageEstimate | undefined` - Expected mana usage per checkpoint (none, target, or limit). - -**Returns**: `GasFees[]` - An array of GasFees, one per slot in the prediction window. - -**Example**: - -```bash -curl -X POST http://localhost:8080 \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"node_getPredictedMinFees","params":[1],"id":1}' -``` - ### node_getMaxPriorityFees Method to fetch the current max priority fee of txs in the mempool. @@ -1189,8 +1180,6 @@ Pauses syncing and rolls back the database to the target L2 block number. **Parameters**: 1. `targetBlockNumber` - `number` - The block number to roll back to. -2. `force` - `boolean | undefined` - If true, clears the world state db and p2p dbs if rolling back to behind the finalized block. -3. `resumeSync` - `boolean | undefined` - If true (default), resumes archiver and world state sync after rollback. **Returns**: `void` @@ -1199,7 +1188,7 @@ Pauses syncing and rolls back the database to the target L2 block number. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12345,true,true],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12345],"id":1}' ``` **Example (Docker)**: @@ -1207,7 +1196,7 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12345,true,true],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_rollbackTo","params":[12345],"id":1}' ``` ### nodeAdmin_startSnapshotUpload @@ -1238,7 +1227,7 @@ docker exec -it aztec-node curl -X POST http://localhost:8880 \ ### nodeAdmin_getSlashPayloads -Gets all monitored slash payloads for the current round. +Returns all monitored payloads by the slasher for the current round. **Parameters**: None @@ -1275,7 +1264,7 @@ Returns all offenses applicable for the given round. ```bash curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["current"],"id":1}' ``` **Example (Docker)**: @@ -1283,7 +1272,7 @@ curl -X POST http://localhost:8880 \ ```bash docker exec -it aztec-node curl -X POST http://localhost:8880 \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["0x1234..."],"id":1}' + -d '{"jsonrpc":"2.0","method":"nodeAdmin_getSlashOffenses","params":["current"],"id":1}' ``` ### nodeAdmin_reloadKeystore diff --git a/docs/scripts/node_api_reference_generation/generate_node_api_reference.sh b/docs/scripts/node_api_reference_generation/generate_node_api_reference.sh index 4a8810b18435..c9af35f766f8 100755 --- a/docs/scripts/node_api_reference_generation/generate_node_api_reference.sh +++ b/docs/scripts/node_api_reference_generation/generate_node_api_reference.sh @@ -48,9 +48,23 @@ done OUTPUT_PATH="$OUTPUT_DIR/$OUTPUT_FILE" -# Verify yarn-project is built -if [[ ! -d "$YARN_PROJECT_DIR/stdlib/dest" ]]; then - echo_error "yarn-project/stdlib/dest/ not found. Run 'yarn build' from yarn-project first." +# Verify the source files the generator parses are present. +# The generator reads .ts source via the TS Compiler API, so no build is required — +# but yarn-project must have node_modules installed so that `npx tsx` can resolve typescript. +REQUIRED_SOURCES=( + "$YARN_PROJECT_DIR/stdlib/src/interfaces/aztec-node.ts" + "$YARN_PROJECT_DIR/stdlib/src/interfaces/aztec-node-admin.ts" + "$YARN_PROJECT_DIR/stdlib/src/block/l2_block_source.ts" +) +for src in "${REQUIRED_SOURCES[@]}"; do + if [[ ! -f "$src" ]]; then + echo_error "Required source file not found: $src" + exit 1 + fi +done + +if [[ ! -d "$YARN_PROJECT_DIR/node_modules" ]]; then + echo_error "yarn-project/node_modules/ not found. Run 'yarn install' from yarn-project first." exit 1 fi diff --git a/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts b/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts index 2138d6aebd18..9b77d593942b 100644 --- a/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts +++ b/docs/scripts/node_api_reference_generation/generate_node_api_reference.ts @@ -69,7 +69,7 @@ function extractJSDocFromNode(node: ts.Node): MethodJSDoc | undefined { const jsDocs = (node as any).jsDoc as ts.JSDoc[] | undefined; if (!jsDocs || jsDocs.length === 0) return undefined; - const jsDoc = jsDocs[jsDocs.length - 1]; + const jsDoc = jsDocs[0]; const description = extractJSDocComment(jsDoc); const params: { name: string; description: string }[] = []; @@ -275,6 +275,15 @@ function splitTopLevelArgs(text: string): string[] { function simplifyZodType(expr: string): string { const e = expr.trim(); + // Optional handling must run first so `.optional()` suffixes aren't swallowed by + // broader patterns below (e.g. `^(\w+)\.schema\b` would otherwise strip the optional + // from expressions like `L2Block.schema.optional()`). + if (e.endsWith('.optional()')) { + return simplifyZodType(e.replace(/\.optional\(\)$/, '')) + ' | undefined'; + } + const optionalWrapperMatch = e.match(/^optional\(([\s\S]+)\)$/); + if (optionalWrapperMatch) return simplifyZodType(optionalWrapperMatch[1]) + ' | undefined'; + // Simple types if (e === 'z.string()') return 'string'; if (e === 'z.number()') return 'number'; @@ -295,7 +304,7 @@ function simplifyZodType(expr: string): string { if (e === 'CheckpointNumberSchema') return 'number'; if (e === 'CheckpointNumberPositiveSchema') return 'number'; if (e === 'EpochNumberSchema') return 'number'; - if (e === 'BlockParameterSchema') return 'number | "latest"'; + if (e === 'BlockParameterSchema') return 'BlockHash | number | "latest"'; // Known schema objects if (e === 'L2TipsSchema') return 'L2Tips'; @@ -322,21 +331,15 @@ function simplifyZodType(expr: string): string { const classSchemaMatch2 = e.match(/^(\w+)\.schema\b/); if (classSchemaMatch2) return classSchemaMatch2[1]; - // z.string().optional() / z.number().optional() - if (e.endsWith('.optional()')) { - return simplifyZodType(e.replace(/\.optional\(\)$/, '')) + ' | undefined'; - } - - // optional(X) - const optionalMatch = e.match(/^optional\(([\s\S]+)\)$/); - if (optionalMatch) return simplifyZodType(optionalMatch[1]) + ' | undefined'; - // z.array(...) — use balanced paren matching to extract inner type if (e.startsWith('z.array(')) { const innerEnd = findMatchingParen(e, 8 - 1); // 8 = 'z.array('.length, -1 to point at '(' if (innerEnd !== -1) { - const inner = e.substring(8, innerEnd); - return simplifyZodType(inner) + '[]'; + const inner = simplifyZodType(e.substring(8, innerEnd)); + // Parenthesize unions so `optional(Foo)` inside an array renders as `(Foo | undefined)[]`, + // not the (incorrectly parsed) `Foo | undefined[]`. + const wrapped = inner.includes('|') ? `(${inner})` : inner; + return wrapped + '[]'; } } @@ -397,16 +400,11 @@ function simplifyZodType(expr: string): string { return schemaRefMatch[1]; } - // Chained expressions with .optional() - if (e.includes('.optional()')) { - const base = e.replace(/\.optional\(\)\s*$/, ''); - return simplifyZodType(base) + ' | undefined'; - } - // Admin config schemas if (e.includes('ConfigSchema')) return 'object'; - // Fallback + // Fallback — surface unrecognized expressions so they can be added to the mapping. + console.warn(`[simplifyZodType] unrecognized expression, falling back to 'object': ${e}`); return 'object'; } @@ -496,7 +494,7 @@ const METHOD_GROUPS: { heading: string; namespace: string; methods: string[] }[] { heading: 'Fee queries', namespace: 'node', - methods: ['getCurrentMinFees', 'getPredictedMinFees', 'getMaxPriorityFees'], + methods: ['getCurrentMinFees', 'getMaxPriorityFees'], }, { heading: 'Node information', @@ -539,20 +537,33 @@ const METHOD_GROUPS: { heading: string; namespace: string; methods: string[] }[] }, ]; -function generateExampleParam(paramType: string): string { +function generateExampleParam(paramType: string, paramName?: string): string { const t = paramType.replace(/\s*\|\s*undefined$/, '').trim(); + + // Name-aware overrides for common parameter names so paired numeric args like + // (from, limit) and (page) render as more illustrative examples than `12345, 12345`. + // `from` defaults to 1 because some schemas (BlockNumberPositiveSchema) require >= 1 + // and 1 is also valid for the relaxed BlockNumberSchema. + if (paramName && (t === 'number' || t === 'bigint')) { + const stringify = (n: number) => (t === 'bigint' ? `"${n}"` : String(n)); + if (paramName === 'from' || paramName === 'fromBlock') return stringify(1); + if (paramName === 'limit') return stringify(100); + if (paramName === 'page') return stringify(0); + if (paramName === 'checkpointNumber') return stringify(1); + } + if (t === 'number') return '12345'; if (t === 'bigint') return '"100"'; if (t === 'string') return '"0x1234..."'; if (t === 'boolean') return 'true'; - if (t === 'number | "latest"') return '"latest"'; - if (t.includes('"all"') || t.includes('"current"')) return '"current"'; + if (t === 'number | "latest"' || t === 'BlockHash | number | "latest"') return '"latest"'; + if (/['"]all['"]|['"]current['"]/.test(t)) return '"current"'; if (t === 'Fr' || t === 'AztecAddress' || t === 'BlockHash') return '"0x1234..."'; if (t === 'EthAddress') return '"0x1234..."'; if (t === 'SlotNumber') return '"100"'; if (t === 'MerkleTreeId') return '1'; - if (t === 'ManaUsageEstimate') return '1'; - if (t.endsWith('[]')) return `[${generateExampleParam(t.slice(0, -2))}]`; + if (t === 'ManaUsageEstimate') return '"target"'; + if (t.endsWith('[]')) return `[${generateExampleParam(t.slice(0, -2), paramName)}]`; if (t === 'Tx') return '{"data":"0x..."}'; if (t === 'TxHash') return '"0x1234..."'; if (t === 'SiloedTag') return '"0x1234..."'; @@ -580,6 +591,11 @@ function generateMethodMarkdown(method: MethodInfo, isAdmin: boolean): string { lines.push(''); } + if (method.jsdoc.remarks) { + lines.push(`**Remarks**: ${method.jsdoc.remarks}`); + lines.push(''); + } + // Parameters if (method.paramTypes.length === 0) { lines.push('**Parameters**: None'); @@ -602,7 +618,9 @@ function generateMethodMarkdown(method: MethodInfo, isAdmin: boolean): string { lines.push(''); // Example - const exampleParams = method.paramTypes.map(t => generateExampleParam(t)).join(','); + const exampleParams = method.paramTypes + .map((t, i) => generateExampleParam(t, method.paramNames[i])) + .join(','); if (isAdmin) { lines.push('**Example (CLI)**:'); @@ -790,6 +808,9 @@ function main() { for (const name of nodeMethodNames) { const schema = nodeSchemaInfo.get(name)!; const jsdoc = mergedJSDoc.get(name) || { description: '', params: [], returns: '' }; + if (!mergedJSDoc.has(name)) { + console.warn(`WARNING: node_${name} is missing JSDoc — rendered without description`); + } const paramNames = mergedParamNames.get(name) || []; allMethods.set(`node:${name}`, { @@ -805,6 +826,9 @@ function main() { for (const name of adminMethodNames) { const schema = adminSchemaInfo.get(name)!; const jsdoc = adminInterface.jsdoc.get(name) || { description: '', params: [], returns: '' }; + if (!adminInterface.jsdoc.has(name)) { + console.warn(`WARNING: nodeAdmin_${name} is missing JSDoc — rendered without description`); + } const paramNames = adminInterface.paramNames.get(name) || []; allMethods.set(`nodeAdmin:${name}`, { From 584d7b2dfab270e841ca01ede318fdeb8197bac0 Mon Sep 17 00:00:00 2001 From: Gregorio Juliana Date: Fri, 8 May 2026 16:01:23 +0200 Subject: [PATCH 20/30] feat: deploy method refactor 2 (#23033) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Splits `DeployMethod` into an abstract umbrella type plus three concrete flavors that encode the deployer-lock state at the type level instead of branching on a nullable field. - `DeployMethod` — abstract base, the type consumers use generically (`let d: DeployMethod = ...`). - `BoundDeployMethod` — locked to a concrete `deployer`. - `UniversalDeployMethod` — locked to `AztecAddress.ZERO` (any sender). - `PendingDeployMethod` — promotes into a `Bound`/`Universal` sibling on the first `send` / `simulate` / `profile` call. The three flavor-specific decisions (`getDeployerAddress`, `lockOrAssertDeployer`, `cloneInstantiation`) are now abstract methods rather than `if (this.deployer === undefined / equals(ZERO) / else)` branches in the base. Each subclass takes a narrowed instantiation type: - `BoundInstantiationOptions` — `deployer` required, `universalDeploy: never`. - `UniversalInstantiationOptions` — `universalDeploy: true` required, `deployer: never`. - `PendingInstantiationOptions` — both `never`. `new BoundDeployMethod(..., { universalDeploy: true })` is now a TypeScript error. The runtime mutual-exclusion checks in subclass constructors are gone; the only runtime guard left is `BoundDeployMethod` rejecting `AztecAddress.ZERO` (a value-level invariant the type system can't model). Subclass constructors take named bundles instead of 9 positionals: ```ts new BoundDeployMethod(wallet, contract, instantiation, payload?) // ^ ^ ^ // { artifact, postDeployCtor, args, constructorNameOrArtifact } // { salt, publicKeys, deployer } // { authWitnesses, capsules, extraHashedArgs } ``` `DeployMethod.create` follows the same shape. `Contract.deploy(wallet, artifact, args, constructorName, instantiation)` and `MyContract.deploy(wallet, ...args, instantiation?)` (codegen) are **unchanged** — the bundle reshape stops at the `create` boundary. - `DeployAccountMethod` now extends `UniversalDeployMethod` (account contracts are always universal). --- .../components/CreateContractDialog.tsx | 15 +- yarn-project/aztec.js/src/api/contract.ts | 1 + .../aztec.js/src/contract/contract.ts | 6 +- .../src/contract/deploy_method.test.ts | 23 +- .../aztec.js/src/contract/deploy_method.ts | 494 ++++++++++++++---- .../src/deployment/contract_deployer.ts | 6 +- .../src/wallet/deploy_account_method.ts | 15 +- .../src/contract-interface-gen/typescript.ts | 22 +- 8 files changed, 432 insertions(+), 150 deletions(-) diff --git a/playground/src/components/contract/components/CreateContractDialog.tsx b/playground/src/components/contract/components/CreateContractDialog.tsx index 0b2ac8d34a6f..b98a5b2e4912 100644 --- a/playground/src/components/contract/components/CreateContractDialog.tsx +++ b/playground/src/components/contract/components/CreateContractDialog.tsx @@ -115,11 +115,16 @@ export function CreateContractDialog({ if (publiclyDeploy) { const postDeployCtor = (instance: ContractInstanceWithAddress, wallet: Wallet) => Contract.at(instance.address, contractArtifact, wallet); - deployMethod = new DeployMethod(wallet, contractArtifact, postDeployCtor, parameters, initializer?.name, { - publicKeys: contract.publicKeys, - salt: contract.salt, - deployer: from, - }); + deployMethod = DeployMethod.create( + wallet, + { + artifact: contractArtifact, + postDeployCtor, + args: parameters, + constructorNameOrArtifact: initializer?.name, + }, + { publicKeys: contract.publicKeys, salt: contract.salt, deployer: from }, + ); opts = { from, fee: { paymentMethod: feePaymentMethod }, diff --git a/yarn-project/aztec.js/src/api/contract.ts b/yarn-project/aztec.js/src/api/contract.ts index 5c659333bb35..e87c57d6b8e3 100644 --- a/yarn-project/aztec.js/src/api/contract.ts +++ b/yarn-project/aztec.js/src/api/contract.ts @@ -81,6 +81,7 @@ export { DeployMethod, type RequestDeployOptions, type SimulateDeployOptions, + UniversalDeployMethod, } from '../contract/deploy_method.js'; export { waitForProven, type WaitForProvenOpts, DefaultWaitForProvenOpts } from '../contract/wait_for_proven.js'; export { getGasLimits } from '../contract/get_gas_limits.js'; diff --git a/yarn-project/aztec.js/src/contract/contract.ts b/yarn-project/aztec.js/src/contract/contract.ts index 8f1c526667fb..403c04a852bf 100644 --- a/yarn-project/aztec.js/src/contract/contract.ts +++ b/yarn-project/aztec.js/src/contract/contract.ts @@ -43,6 +43,10 @@ export class Contract extends ContractBase { ) { const postDeployCtor = (instance: ContractInstanceWithAddress, wallet: Wallet) => Contract.at(instance.address, artifact, wallet); - return new DeployMethod(wallet, artifact, postDeployCtor, args, constructorName, instantiation); + return DeployMethod.create( + wallet, + { artifact, postDeployCtor, args, constructorNameOrArtifact: constructorName }, + instantiation, + ); } } diff --git a/yarn-project/aztec.js/src/contract/deploy_method.test.ts b/yarn-project/aztec.js/src/contract/deploy_method.test.ts index 3bc8b6458fa3..ae1bc9e9b531 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.test.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.test.ts @@ -14,7 +14,6 @@ import { NO_FROM } from './interaction_options.js'; describe('DeployMethod', () => { let wallet: MockProxy; - beforeEach(() => { wallet = mock(); wallet.registerContract.mockResolvedValue({} as ContractInstanceWithAddress); @@ -27,14 +26,10 @@ describe('DeployMethod', () => { const txSimResult = mock(); Object.defineProperty(txSimResult, 'offchainEffects', { value: offchainEffects }); Object.defineProperty(txSimResult, 'publicInputs', { - value: { - constants: { anchorBlockHeader: { globalVariables: { timestamp: anchorBlockTimestamp } } }, - }, + value: { constants: { anchorBlockHeader: { globalVariables: { timestamp: anchorBlockTimestamp } } } }, }); Object.defineProperty(txSimResult, 'stats', { value: {} }); - Object.defineProperty(txSimResult, 'gasUsed', { - value: { totalGas: Gas.empty(), teardownGas: Gas.empty() }, - }); + Object.defineProperty(txSimResult, 'gasUsed', { value: { totalGas: Gas.empty(), teardownGas: Gas.empty() } }); return txSimResult; }; @@ -43,19 +38,12 @@ describe('DeployMethod', () => { const contractAddress = await AztecAddress.random(); const msgPayload = [Fr.random(), Fr.random()]; const anchorBlockTimestamp = 42000n; - const offchainEffects: OffchainEffect[] = [ - { - data: [OFFCHAIN_MESSAGE_IDENTIFIER, recipient.toField(), ...msgPayload], - contractAddress, - }, + { data: [OFFCHAIN_MESSAGE_IDENTIFIER, recipient.toField(), ...msgPayload], contractAddress }, ]; - wallet.simulateTx.mockResolvedValue(makeSimulateResult(offchainEffects, anchorBlockTimestamp)); - const deploy = Contract.deploy(wallet, testContractArtifact, []); const result = await deploy.simulate({ from: await AztecAddress.random() }); - expect(result.offchainMessages).toHaveLength(1); expect(result.offchainMessages[0]).toEqual({ recipient, @@ -112,15 +100,11 @@ describe('DeployMethod', () => { it('keeps the address stable across simulate then send when lazy-locking from `from`', async () => { const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt }); - const expected = await expectedAddress(alice); - await deploy.simulate({ from: alice }); const afterSimulate = await deploy.getAddress(); - await deploy.send({ from: alice }); const afterSend = await deploy.getAddress(); - expect(afterSimulate).toEqual(afterSend); expect(afterSimulate).toEqual(expected); }); @@ -147,7 +131,6 @@ describe('DeployMethod', () => { it('allows any sender when locked to universal at construction, and the address is stable', async () => { const deploy = Contract.deploy(wallet, testContractArtifact, [], undefined, { salt, universalDeploy: true }); const expected = await expectedAddress(AztecAddress.ZERO); - await expect(deploy.send({ from: alice })).resolves.toBeDefined(); expect(await deploy.getAddress()).toEqual(expected); await expect(deploy.send({ from: bob })).resolves.toBeDefined(); diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index f7f5cc546537..350099767d45 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -86,10 +86,81 @@ export type DeployInstantiationOptions = { publicKeys?: PublicKeys; }; +/** + * Address-derivation inputs shared by all deploy methods. {@link BoundInstantiationOptions}, + * {@link UniversalInstantiationOptions}, and {@link PendingInstantiationOptions} narrow this + * shape to forbid the fields that don't apply to a given flavor at the type level. + */ +type SharedInstantiationOptions = { + /** Salt used to derive the contract address. Defaults to a random Fr. */ + salt?: Fr; + /** Public keys mixed into the address. Defaults to `PublicKeys.default()`. */ + publicKeys?: PublicKeys; +}; + +/** + * Narrowed `DeployInstantiationOptions` accepted by {@link BoundDeployMethod}: requires a + * concrete `deployer` and forbids `universalDeploy`. The runtime check that `deployer` is + * non-zero stays as defense in depth (it's a value-level invariant the type system can't model). + */ +export type BoundInstantiationOptions = SharedInstantiationOptions & { + /** Concrete deployer mixed into the address preimage. Required, must be non-zero. */ + deployer: AztecAddress; + /** Forbidden on `BoundDeployMethod`; use `UniversalDeployMethod` for universal deploys. */ + universalDeploy?: never; +}; + +/** + * Narrowed `DeployInstantiationOptions` accepted by {@link UniversalDeployMethod}: forbids + * `deployer` and requires `universalDeploy: true` (so the call site reads as a universal deploy). + */ +export type UniversalInstantiationOptions = SharedInstantiationOptions & { + /** Forbidden on `UniversalDeployMethod`; use `BoundDeployMethod` if you need a concrete deployer. */ + deployer?: never; + /** Marks this as a universal deploy. Required for clarity at the call site. */ + universalDeploy: true; +}; + +/** + * Narrowed `DeployInstantiationOptions` accepted by {@link PendingDeployMethod}: forbids both + * `deployer` and `universalDeploy`. The deploy is locked from the first send-time `from` instead. + */ +export type PendingInstantiationOptions = SharedInstantiationOptions & { + /** Forbidden on `PendingDeployMethod`; use `BoundDeployMethod` for a concrete deployer. */ + deployer?: never; + /** Forbidden on `PendingDeployMethod`; use `UniversalDeployMethod` for a universal deploy. */ + universalDeploy?: never; +}; + +/** + * Identifies *which contract* is being deployed and *with what initializer*. + */ +export type DeployMethodContract = { + /** Build artifact of the contract being deployed. */ + artifact: ContractArtifact; + /** Factory invoked after deployment to produce the typed contract handle. */ + postDeployCtor: (instance: ContractInstanceWithAddress, wallet: Wallet) => TContract; + /** Encoded constructor arguments for the contract. Defaults to `[]`. */ + args?: any[]; + /** Name (or full artifact) of the initializer to call. */ + constructorNameOrArtifact?: string | FunctionArtifact; +}; + +/** + * Execution-payload metadata propagated through `request` / `send` / `simulate` / `profile`. + */ +export type DeployMethodPayload = { + /** Auth witnesses propagated to the deploy interaction. */ + authWitnesses?: AuthWitness[]; + /** Capsules propagated to the deploy interaction. */ + capsules?: Capsule[]; + /** Extra hashed args propagated to the deploy interaction. */ + extraHashedArgs?: HashedValues[]; +}; + /** * Options for deploying a contract on the Aztec network. - * Controls publication and registration policy for this deployment. Address-affecting parameters - * (salt, deployer, publicKeys, constructor and args) are passed at construction time. + * Controls publication and registration policy for this deployment. */ export type RequestDeployOptions = RequestInteractionOptions & { /** Skip contract class publication. */ @@ -175,8 +246,15 @@ export type DeployReturn; /** - * Contract interaction for deployment. - * Handles class publication, instance publication, and initialization of the contract. + * Umbrella type for a contract deployment interaction. + * + * `DeployMethod` is abstract: callers always interact with one of three concrete flavors — + * {@link BoundDeployMethod}, {@link UniversalDeployMethod}, or {@link PendingDeployMethod} — + * picked by {@link DeployMethod.create} based on the supplied {@link DeployInstantiationOptions}. + * The flavors only differ in their initial deployer-lock state; the full API + * (`request` / `send` / `simulate` / `profile` / `getInstance` / `getAddress` / + * `getPartialAddress` / `register` / `with`) lives on this base, so consumers can type + * variables as `DeployMethod` and treat all three uniformly. * * The deployer (and therefore the deployed address) is locked once and never changes. Locking * happens either at construction (via `deployer` or `universalDeploy: true` in the instantiation @@ -196,101 +274,117 @@ export type DeployReturn extends BaseContractInteraction { +export abstract class DeployMethod extends BaseContractInteraction { /** Salt used in the address preimage. */ protected readonly salt: Fr; - /** - * Deployer mixed into the address preimage. `undefined` until locked, either by `deployer` / - * `universalDeploy: true` at construction, or by the first call to `request` / `send` / - * `simulate` / `profile` which locks it from `options.from` (NO_FROM/undefined → ZERO, - * AztecAddress → that address). `AztecAddress.ZERO` indicates a universal deployment. Once - * locked, never changes; subsequent calls with an incompatible `from` throw. - */ - protected deployer: AztecAddress | undefined; /** Public keys mixed into the address preimage. */ protected readonly publicKeys: PublicKeys; - /** Cached instance promise; resolved once after the deployer is locked. */ - private instancePromise?: Promise; - /** Resolved value of `instancePromise`, populated synchronously once the promise settles. */ - private resolvedInstance?: ContractInstanceWithAddress; + /** Cached instance promise; resolved once the deployer is known. */ + #instancePromise?: Promise; + /** Resolved value of `#instancePromise`, populated synchronously once the promise settles. */ + #resolvedInstance?: ContractInstanceWithAddress; /** Constructor function to call. */ protected constructorArtifact: FunctionAbi | undefined; - - constructor( + /** Build artifact of the contract being deployed. */ + protected readonly artifact: ContractArtifact; + /** Factory invoked after deployment to produce the typed contract handle. */ + protected readonly postDeployCtor: (instance: ContractInstanceWithAddress, wallet: Wallet) => TContract; + /** Encoded constructor arguments for the contract. */ + protected readonly args: any[]; + /** Extra hashed args propagated through `with(...)` and into the deploy payload. */ + protected readonly extraHashedArgs: HashedValues[]; + + protected constructor( wallet: Wallet, - protected artifact: ContractArtifact, - protected postDeployCtor: (instance: ContractInstanceWithAddress, wallet: Wallet) => TContract, - protected args: any[] = [], - constructorNameOrArtifact?: string | FunctionArtifact, - instantiation: DeployInstantiationOptions = {}, - authWitnesses: AuthWitness[] = [], - capsules: Capsule[] = [], - protected extraHashedArgs: HashedValues[] = [], + contract: DeployMethodContract, + salt: Fr | undefined, + publicKeys: PublicKeys | undefined, + payload: DeployMethodPayload = {}, ) { - super(wallet, authWitnesses, capsules); - this.constructorArtifact = getInitializer(artifact, constructorNameOrArtifact); - this.salt = instantiation.salt ?? Fr.random(); - this.publicKeys = instantiation.publicKeys ?? PublicKeys.default(); - if (instantiation.deployer !== undefined && instantiation.universalDeploy) { - throw new Error('DeployInstantiationOptions: `deployer` and `universalDeploy` are mutually exclusive.'); - } - if (instantiation.universalDeploy) { - this.deployer = AztecAddress.ZERO; - } else if (instantiation.deployer !== undefined) { - this.deployer = instantiation.deployer; - } + super(wallet, payload.authWitnesses ?? [], payload.capsules ?? []); + this.artifact = contract.artifact; + this.postDeployCtor = contract.postDeployCtor; + this.args = contract.args ?? []; + this.constructorArtifact = getInitializer(contract.artifact, contract.constructorNameOrArtifact); + this.salt = salt ?? Fr.random(); + this.publicKeys = publicKeys ?? PublicKeys.default(); + this.extraHashedArgs = payload.extraHashedArgs ?? []; } /** - * Locks the deployer from a send-time `from` value. If the deployer is already locked, this - * verifies that `from` is compatible with the locked value and throws otherwise. A locked - * universal deployer (`AztecAddress.ZERO`) is compatible with any `from`, since "universal" - * means the address does not depend on the sender. + * The address that will be mixed into the contract's address preimage. Owned returns the + * concrete deployer; Universal returns `AztecAddress.ZERO`; Pending throws unless a prior + * `send` / `simulate` / `profile` call has already locked it. + */ + public abstract getDeployerAddress(): AztecAddress; + + /** + * Reconciles a send-time `from` with the deploy's deployer. Owned asserts an exact match; + * Universal accepts anything; Pending uses the first call to lock its deployer (transitioning + * into an Owned/Universal sibling), then defers to that sibling's assertion on subsequent calls. * - * @param from - The send-time `from` value (AztecAddress, NO_FROM, or undefined). + * The "locks-or-asserts" name is intentional: only Pending mutates state, and only on its first + * invocation. Owned and Universal are pure assertions. + * + * @param from - The send-time `from` value (`AztecAddress`, `NO_FROM`, or `undefined`). */ - protected lockDeployerFromSendOptions(from: SendInteractionOptionsWithoutWait['from'] | undefined): void { - const fromAsDeployer: AztecAddress = from === undefined || from === NO_FROM ? AztecAddress.ZERO : from; - if (this.deployer === undefined) { - this.deployer = fromAsDeployer; - return; - } - if (this.deployer.equals(AztecAddress.ZERO)) { - return; + public abstract lockDeployer(from: SendInteractionOptionsWithoutWait['from'] | undefined): void; + + /** + * Returns the {@link DeployInstantiationOptions} that match this flavor. Used by `with(...)` to + * spawn a sibling instance carrying the same lock state. + */ + public abstract cloneInstantiation(): DeployInstantiationOptions; + + /** + * Constructs the right concrete `DeployMethod` flavor for the supplied instantiation options: + * - `{ deployer: }` → {@link BoundDeployMethod} + * - `{ universalDeploy: true }` → {@link UniversalDeployMethod} + * - neither set → {@link PendingDeployMethod} + * + * Mixing `deployer` and `universalDeploy` throws. Returns the umbrella `DeployMethod` type so + * callers can use the result generically without narrowing. + * + * @param wallet - Wallet used to send / simulate the deploy tx. + * @param contract - The contract being deployed (artifact, factory, args, initializer). + * @param instantiation - Address-affecting parameters (salt, deployer / universalDeploy, publicKeys). Defaults to pending. + * @param payload - Auth witnesses, capsules, and extra hashed args propagated to the deploy. Defaults to empty. + */ + public static create( + wallet: Wallet, + contract: DeployMethodContract, + instantiation: DeployInstantiationOptions = {}, + payload: DeployMethodPayload = {}, + ): DeployMethod { + if (instantiation.deployer !== undefined && instantiation.universalDeploy) { + throw new Error('DeployInstantiationOptions: `deployer` and `universalDeploy` are mutually exclusive.'); } - if (!this.deployer.equals(fromAsDeployer)) { - throw new Error( - `Deployer for this DeployMethod is locked to ${this.deployer.toString()}; cannot send from ${fromAsDeployer.toString()} ` + - `because that would imply a different deployer than the one used to derive the address. ` + - `Pass \`deployer: ${this.deployer.toString()}\` at construction if you need a different sender.`, + const { salt, publicKeys, deployer, universalDeploy } = instantiation; + if (universalDeploy) { + return new UniversalDeployMethod( + wallet, + contract, + { salt, publicKeys, universalDeploy: true }, + payload, ); } + if (deployer !== undefined) { + return new BoundDeployMethod(wallet, contract, { salt, publicKeys, deployer }, payload); + } + return new PendingDeployMethod(wallet, contract, { salt, publicKeys }, payload); } /** - * Returns the execution payload that allows this operation to happen on chain. - * - * Requires the deployer to be locked already (either at construction via `deployer` / - * `universalDeploy: true`, or as a side effect of a prior `send` / `simulate` / `profile` call, - * which lock from `options.from`). Throws otherwise — `request` is purely about payload - * construction and does not look at sender information. + * Returns the execution payload that allows this operation to happen on chain. Requires the + * deployer to be known — call `getDeployerAddress()` first; on a `PendingDeployMethod` this + * throws unless a prior `send` / `simulate` / `profile` has already locked the deployer. * * @param options - Configuration options. * @returns The execution payload for this operation */ public async request(options: RequestDeployOptions = {}): Promise { - if (this.deployer === undefined) { - throw new Error( - 'Cannot build deploy execution payload: deployer is not yet locked. Pass `deployer:
` ' + - 'or `universalDeploy: true` as the instantiation option when constructing the deploy ' + - '(e.g. `MyContract.deploy(wallet, ...args, { deployer: alice })`), or call `.send` / ' + - '`.simulate` / `.profile` first to lock the deployer from the sender. When wrapping a ' + - 'DeployMethod inside a BatchCall, lock the deployer at construction since BatchCall ' + - 'invokes `request()` directly.', - ); - } const publication = await this.getPublicationExecutionPayload(options); if (!options?.skipRegistration) { @@ -449,8 +543,13 @@ export class DeployMethod extends options: DeployOptions, ): Promise>; // eslint-disable-next-line jsdoc/require-jsdoc +<<<<<<< HEAD public override async send(options: DeployOptions): Promise { this.lockDeployerFromSendOptions(options.from); +======= + public override async send(options: DeployOptions): Promise { + this.lockDeployer(options.from); +>>>>>>> 63cc7e6e46 (feat: deploy method refactor 2 (#23033)) const executionPayload = await this.request(options); const sendOptions = this.convertDeployOptionsToSendOptions(options); @@ -482,37 +581,27 @@ export class DeployMethod extends * Builds the contract instance and returns it. The instance is computed once and cached for * the lifetime of this DeployMethod; subsequent calls return the same instance. * - * Requires the deployer to have been locked. The deployer is locked either by passing - * `deployer` / `universalDeploy: true` at construction, or by a prior call to - * `request` / `send` / `simulate` / `profile` (which lock from `options.from`). Calling - * `getInstance()` before the deployer is locked throws, because the address is otherwise - * ambiguous and would silently change once the user finally invokes a send. + * On a {@link PendingDeployMethod} this throws unless a prior `send` / `simulate` / `profile` + * call has already locked the deployer — otherwise the resolved address could silently differ + * from the eventually-deployed one. * * @returns An instance object. */ public getInstance(): Promise { - if (this.deployer === undefined) { - throw new Error( - 'Cannot resolve contract instance: deployer is not yet locked. Pass `deployer:
` ' + - 'or `universalDeploy: true` as the instantiation option when constructing the deploy ' + - '(e.g. `MyContract.deploy(wallet, ...args, { deployer: alice })`), or call `.send` / ' + - '`.simulate` / `.profile` first to lock the deployer from the sender.', - ); - } - const deployer = this.deployer; - if (!this.instancePromise) { - this.instancePromise = getContractInstanceFromInstantiationParams(this.artifact, { + const deployer = this.getDeployerAddress(); + if (!this.#instancePromise) { + this.#instancePromise = getContractInstanceFromInstantiationParams(this.artifact, { constructorArgs: this.args, salt: this.salt, publicKeys: this.publicKeys, constructorArtifact: this.constructorArtifact, deployer, }).then(instance => { - this.resolvedInstance = instance; + this.#resolvedInstance = instance; return instance; }); } - return this.instancePromise; + return this.#instancePromise; } /** @@ -523,7 +612,7 @@ export class DeployMethod extends * estimations (if requested via options), execution statistics and emitted offchain effects */ public async simulate(options: SimulateDeployOptions): Promise { - this.lockDeployerFromSendOptions(options.from); + this.lockDeployer(options.from); const executionPayload = await this.request(options); const simulatedTx = await this.wallet.simulateTx( executionPayload, @@ -552,7 +641,7 @@ export class DeployMethod extends * @returns An object containing the function return value and profile result. */ public async profile(options: DeployOptionsWithoutWait & ProfileInteractionOptions): Promise { - this.lockDeployerFromSendOptions(options.from); + this.lockDeployer(options.from); const executionPayload = await this.request(options); return await this.wallet.profileTx(executionPayload, this.convertDeployOptionsToProfileOptions(options)); } @@ -573,14 +662,17 @@ export class DeployMethod extends * been awaited (e.g. `request()` invoked it). Not part of the public API. */ protected getCachedInstanceOrThrow(): ContractInstanceWithAddress { - if (!this.resolvedInstance) { + if (!this.#resolvedInstance) { throw new Error('Contract instance has not been computed yet. Call getInstance() first.'); } - return this.resolvedInstance; + return this.#resolvedInstance; } /** - * Augments this DeployMethod with additional metadata, such as authWitnesses and capsules. + * Augments this DeployMethod with additional metadata, such as authWitnesses and capsules. The + * deployer lock is preserved: a Pending that has not yet been locked stays Pending; a Pending + * that has already locked, along with Owned and Universal, returns the matching locked flavor + * so the cloned method deploys at the same address as `this`. * @param options - An object containing the metadata to add to the interaction * @returns A new DeployMethod with the added metadata, but calling the same original function in the same manner */ @@ -592,32 +684,216 @@ export class DeployMethod extends authWitnesses?: AuthWitness[]; /** The capsules to add to the deployment */ capsules?: Capsule[]; +<<<<<<< HEAD }): DeployMethod { return new DeployMethod( +======= + /** The extra hashed args to add to the deployment */ + extraHashedArgs?: HashedValues[]; + }): DeployMethod { + return DeployMethod.create( +>>>>>>> 63cc7e6e46 (feat: deploy method refactor 2 (#23033)) this.wallet, - this.artifact, - this.postDeployCtor, - this.args, - this.constructorArtifact?.name, + { + artifact: this.artifact, + postDeployCtor: this.postDeployCtor, + args: this.args, + constructorNameOrArtifact: this.constructorArtifact?.name, + }, this.cloneInstantiation(), +<<<<<<< HEAD this.authWitnesses.concat(authWitnesses), this.capsules.concat(capsules), +======= + { + authWitnesses: this.authWitnesses.concat(authWitnesses), + capsules: this.capsules.concat(capsules), + extraHashedArgs: this.extraHashedArgs.concat(extraHashedArgs), + }, +>>>>>>> 63cc7e6e46 (feat: deploy method refactor 2 (#23033)) ); } +} + +/** + * Deploy method whose deployer is fixed at construction to a concrete {@link AztecAddress}. The + * deployer is mixed into the address preimage, so the contract address is fully determined. + * + * Sending from a different account throws — letting it through would silently produce a deployed + * address different from the one `getAddress()` reported. + */ +export class BoundDeployMethod extends DeployMethod { + /** The address baked into the address preimage. Read-only — set at construction. */ + public readonly deployer: AztecAddress; + + public constructor( + wallet: Wallet, + contract: DeployMethodContract, + instantiation: BoundInstantiationOptions, + payload: DeployMethodPayload = {}, + ) { + // `BoundInstantiationOptions` requires a `deployer` and forbids `universalDeploy` at the type + // level. We still reject `AztecAddress.ZERO` here because the type system can't model it. + if (instantiation.deployer.equals(AztecAddress.ZERO)) { + throw new Error( + 'BoundDeployMethod requires a non-zero `deployer`; use `UniversalDeployMethod` (`{ universalDeploy: true }`) for universal deploys.', + ); + } + super(wallet, contract, instantiation.salt, instantiation.publicKeys, payload); + this.deployer = instantiation.deployer; + } + + /** Returns the locked deployer baked into the address preimage. */ + public getDeployerAddress(): AztecAddress { + return this.deployer; + } + + /** + * Throws unless `from` matches the locked deployer; the deployer is part of the address. + * @param from - The send-time `from` value (`AztecAddress`, `NO_FROM`, or `undefined`). + */ + public lockDeployer(from: SendInteractionOptionsWithoutWait['from'] | undefined): void { + if (from === undefined || from === NO_FROM || !this.deployer.equals(from)) { + const sender = from === undefined ? '' : from === NO_FROM ? 'NO_FROM' : from.toString(); + throw new Error( + `Deployer for this DeployMethod is locked to ${this.deployer.toString()}; cannot send from ${sender} ` + + `because that would imply a different deployer than the one used to derive the address. ` + + `Pass \`from: ${this.deployer.toString()}\` to send from the locked deployer, or reconstruct the ` + + `deploy with a different \`deployer\` if you need a different sender.`, + ); + } + } + + /** Re-emits this method's `DeployInstantiationOptions` for `with(...)` to consume. */ + public cloneInstantiation(): DeployInstantiationOptions { + return { salt: this.salt, publicKeys: this.publicKeys, deployer: this.deployer }; + } +} + +/** + * Deploy method whose deployer is fixed at construction to {@link AztecAddress.ZERO} (universal + * deploy). The address does not depend on the sender, so any account may sign the deploy tx. + */ +export class UniversalDeployMethod extends DeployMethod { + public constructor( + wallet: Wallet, + contract: DeployMethodContract, + instantiation: UniversalInstantiationOptions, + payload: DeployMethodPayload = {}, + ) { + // `UniversalInstantiationOptions` forbids `deployer` and requires `universalDeploy: true` at + // the type level — no runtime check is needed. + super(wallet, contract, instantiation.salt, instantiation.publicKeys, payload); + } + + /** Universal deploys are anchored at `AztecAddress.ZERO`; the sender does not enter the preimage. */ + public getDeployerAddress(): AztecAddress { + return AztecAddress.ZERO; + } /** - * Returns the instantiation options to pass to a freshly-constructed copy of this DeployMethod - * (e.g. via `with(...)`). Encodes the current locked-deployer state: a locked AztecAddress.ZERO - * deployer becomes `universalDeploy: true`; an undefined deployer stays unset so the new copy can - * still infer it from the first send. + * Universal deploys accept any sender, including `NO_FROM` / `undefined`. + * @param _from - Ignored. */ - protected cloneInstantiation(): DeployInstantiationOptions { - if (this.deployer === undefined) { + public lockDeployer(_from: SendInteractionOptionsWithoutWait['from'] | undefined): void { + // No-op. + } + + /** Re-emits this method's `DeployInstantiationOptions` for `with(...)` to consume. */ + public cloneInstantiation(): DeployInstantiationOptions { + return { salt: this.salt, publicKeys: this.publicKeys, universalDeploy: true }; + } +} + +/** + * Deploy method whose deployer is not yet decided. The first `send` / `simulate` / `profile` call + * promotes this into an {@link BoundDeployMethod} or {@link UniversalDeployMethod} (depending on + * whether `options.from` is an address or `NO_FROM` / `undefined`); subsequent calls reuse that + * promotion and reject mismatching `from` values. + * + * Reading the address (`getInstance` / `getAddress` / `getPartialAddress`) or building a payload + * (`request`) before the promotion happens throws — the address would otherwise be ambiguous and + * could differ from what `send()` ends up deploying. + */ +export class PendingDeployMethod extends DeployMethod { + /** + * The locked sibling created on the first send-side call. Once set, all flavor-specific + * decisions (sender compatibility, address derivation, clone shape) delegate to it, so a second + * call with a mismatched `from` is rejected by `BoundDeployMethod.lockDeployer`. + */ + #locked?: BoundDeployMethod | UniversalDeployMethod; + + public constructor( + wallet: Wallet, + contract: DeployMethodContract, + instantiation: PendingInstantiationOptions = {}, + payload: DeployMethodPayload = {}, + ) { + super(wallet, contract, instantiation.salt, instantiation.publicKeys, payload); + } + + /** + * Returns the locked deployer once it has happened. Throws while still pending — the + * address would otherwise differ from what `send()` ends up deploying. + */ + public getDeployerAddress(): AztecAddress { + if (!this.#locked) { + throw new Error( + 'Cannot resolve contract address: deployer is not yet locked. Pass `deployer:
` ' + + 'or `universalDeploy: true` as the instantiation option when constructing the deploy ' + + '(e.g. `MyContract.deploy(wallet, ...args, { deployer: alice })`), or call `.send` / ' + + '`.simulate` / `.profile` first to lock the deployer from the sender. ', + ); + } + return this.#locked.getDeployerAddress(); + } + + /** + * On the first call, promotes this pending method into a locked sibling and remembers it. On + * subsequent calls, defers to the locked sibling — so a mismatched `from` is rejected by the + * sibling's own policy, not a duplicate one here. + * @param from - The send-time `from` value (`AztecAddress`, `NO_FROM`, or `undefined`). + */ + public lockDeployer(from: SendInteractionOptionsWithoutWait['from'] | undefined): void { + if (!this.#locked) { + this.#locked = this.#promoteFrom(from); + return; + } + this.#locked.lockDeployer(from); + } + + /** Re-emits this method's `DeployInstantiationOptions` for `with(...)` to consume. */ + public cloneInstantiation(): DeployInstantiationOptions { + if (!this.#locked) { return { salt: this.salt, publicKeys: this.publicKeys }; } - if (this.deployer.equals(AztecAddress.ZERO)) { - return { salt: this.salt, publicKeys: this.publicKeys, universalDeploy: true }; + return this.#locked.cloneInstantiation(); + } + + /** + * Builds the locked sibling implied by a send-time `from`: an `AztecAddress` becomes + * {@link BoundDeployMethod}; `NO_FROM` / `undefined` becomes {@link UniversalDeployMethod}. + * @param from - The send-time `from` value. + */ + #promoteFrom( + from: SendInteractionOptionsWithoutWait['from'] | undefined, + ): BoundDeployMethod | UniversalDeployMethod { + const { wallet, artifact, postDeployCtor, args, salt, publicKeys, authWitnesses, capsules, extraHashedArgs } = this; + const contract: DeployMethodContract = { + artifact, + postDeployCtor, + args, + constructorNameOrArtifact: this.constructorArtifact?.name, + }; + const payload: DeployMethodPayload = { authWitnesses, capsules, extraHashedArgs }; + if (from === undefined || from === NO_FROM) { + return new UniversalDeployMethod( + wallet, + contract, + { salt, publicKeys, universalDeploy: true }, + payload, + ); } - return { salt: this.salt, publicKeys: this.publicKeys, deployer: this.deployer }; + return new BoundDeployMethod(wallet, contract, { salt, publicKeys, deployer: from }, payload); } } diff --git a/yarn-project/aztec.js/src/deployment/contract_deployer.ts b/yarn-project/aztec.js/src/deployment/contract_deployer.ts index 890b7723dd30..43fb0d0212d4 100644 --- a/yarn-project/aztec.js/src/deployment/contract_deployer.ts +++ b/yarn-project/aztec.js/src/deployment/contract_deployer.ts @@ -31,6 +31,10 @@ export class ContractDeployer { public deploy(args?: any[], instantiation?: DeployInstantiationOptions) { const postDeployCtor = (instance: ContractInstanceWithAddress, wallet: Wallet) => Contract.at(instance.address, this.artifact, wallet); - return new DeployMethod(this.wallet, this.artifact, postDeployCtor, args, this.constructorName, instantiation); + return DeployMethod.create( + this.wallet, + { artifact: this.artifact, postDeployCtor, args, constructorNameOrArtifact: this.constructorName }, + instantiation, + ); } } diff --git a/yarn-project/aztec.js/src/wallet/deploy_account_method.ts b/yarn-project/aztec.js/src/wallet/deploy_account_method.ts index 08c40d9cc932..3afe74d0139e 100644 --- a/yarn-project/aztec.js/src/wallet/deploy_account_method.ts +++ b/yarn-project/aztec.js/src/wallet/deploy_account_method.ts @@ -11,12 +11,16 @@ import type { Account } from '../account/account.js'; import type { Contract } from '../contract/contract.js'; import type { ContractBase } from '../contract/contract_base.js'; import { +<<<<<<< HEAD type DeployInteractionWaitOptions, DeployMethod, +======= +>>>>>>> 63cc7e6e46 (feat: deploy method refactor 2 (#23033)) type DeployOptions, type DeployOptionsWithoutWait, type RequestDeployOptions, type SimulateDeployOptions, + UniversalDeployMethod, } from '../contract/deploy_method.js'; import { type FeePaymentMethodOption, @@ -79,7 +83,7 @@ type DeployAccountInteractionOptions = Pick< * Modified version of the DeployMethod used to deploy account contracts. Supports deploying * contracts that can pay for their own fee, plus some preconfigured options to avoid errors. */ -export class DeployAccountMethod extends DeployMethod { +export class DeployAccountMethod extends UniversalDeployMethod { constructor( publicKeys: PublicKeys, wallet: Wallet, @@ -95,15 +99,10 @@ export class DeployAccountMethod exte ) { super( wallet, - artifact, - postDeployCtor, - args, - constructorNameOrArtifact, + { artifact, postDeployCtor, args, constructorNameOrArtifact }, // Account contracts are always deployed universally. { salt, universalDeploy: true, publicKeys }, - authWitnesses, - capsules, - extraHashedArgs, + { authWitnesses, capsules, extraHashedArgs }, ); } diff --git a/yarn-project/builder/src/contract-interface-gen/typescript.ts b/yarn-project/builder/src/contract-interface-gen/typescript.ts index e3e47bc56b84..245c9ab8cefa 100644 --- a/yarn-project/builder/src/contract-interface-gen/typescript.ts +++ b/yarn-project/builder/src/contract-interface-gen/typescript.ts @@ -107,7 +107,15 @@ function generateDeploy(input: ContractArtifact) { * Salt defaults to a random value; the deployer is locked lazily from the first send-time \`from\`. */ public static deploy(wallet: Wallet, ${args ? `${args}, ` : ''}instantiation?: DeployInstantiationOptions) { - return new DeployMethod<${contractName}>(wallet, ${artifactName}, (instance, wallet) => ${contractName}.at(instance.address, wallet), ${argsForwarding}, undefined, instantiation); + return DeployMethod.create<${contractName}>( + wallet, + { + artifact: ${artifactName}, + postDeployCtor: (instance, wallet) => ${contractName}.at(instance.address, wallet), + args: ${argsForwarding}, + }, + instantiation, + ); } /** @@ -117,12 +125,14 @@ function generateDeploy(input: ContractArtifact) { opts: { method?: M; wallet: Wallet; instantiation?: DeployInstantiationOptions }, ...args: Parameters<${contractName}['methods'][M]> ) { - return new DeployMethod<${contractName}>( + return DeployMethod.create<${contractName}>( opts.wallet, - ${artifactName}, - (instance, wallet) => ${contractName}.at(instance.address, wallet), - args, - opts.method ?? 'constructor', + { + artifact: ${artifactName}, + postDeployCtor: (instance, wallet) => ${contractName}.at(instance.address, wallet), + args, + constructorNameOrArtifact: opts.method ?? 'constructor', + }, opts.instantiation, ); } From f3ee7f6a9300f231f52c331d66e95f64e0b6f99d Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 16:38:15 +0000 Subject: [PATCH 21/30] fix: resolve cherry-pick conflicts --- .../aztec.js/src/contract/deploy_method.ts | 15 --------------- .../aztec.js/src/wallet/deploy_account_method.ts | 4 ---- 2 files changed, 19 deletions(-) diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index 350099767d45..ce6d044f4e32 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -543,13 +543,8 @@ export abstract class DeployMethod, ): Promise>; // eslint-disable-next-line jsdoc/require-jsdoc -<<<<<<< HEAD public override async send(options: DeployOptions): Promise { - this.lockDeployerFromSendOptions(options.from); -======= - public override async send(options: DeployOptions): Promise { this.lockDeployer(options.from); ->>>>>>> 63cc7e6e46 (feat: deploy method refactor 2 (#23033)) const executionPayload = await this.request(options); const sendOptions = this.convertDeployOptionsToSendOptions(options); @@ -684,15 +679,10 @@ export abstract class DeployMethod { return DeployMethod.create( ->>>>>>> 63cc7e6e46 (feat: deploy method refactor 2 (#23033)) this.wallet, { artifact: this.artifact, @@ -701,16 +691,11 @@ export abstract class DeployMethod>>>>>> 63cc7e6e46 (feat: deploy method refactor 2 (#23033)) ); } } diff --git a/yarn-project/aztec.js/src/wallet/deploy_account_method.ts b/yarn-project/aztec.js/src/wallet/deploy_account_method.ts index 3afe74d0139e..03deabaa6c48 100644 --- a/yarn-project/aztec.js/src/wallet/deploy_account_method.ts +++ b/yarn-project/aztec.js/src/wallet/deploy_account_method.ts @@ -11,11 +11,7 @@ import type { Account } from '../account/account.js'; import type { Contract } from '../contract/contract.js'; import type { ContractBase } from '../contract/contract_base.js'; import { -<<<<<<< HEAD type DeployInteractionWaitOptions, - DeployMethod, -======= ->>>>>>> 63cc7e6e46 (feat: deploy method refactor 2 (#23033)) type DeployOptions, type DeployOptionsWithoutWait, type RequestDeployOptions, From 4b425f55471001aefe16e5db26c789161ed2159d Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 16:42:28 +0000 Subject: [PATCH 22/30] fix: restore extraHashedArgs default in DeployMethod.with() The conflict resolution in the previous commit accidentally dropped the `extraHashedArgs = []` default in the destructuring of `with()`'s options argument, which would otherwise cause `concat(undefined)` to push an undefined entry. --- yarn-project/aztec.js/src/contract/deploy_method.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index ce6d044f4e32..bef0cc665d09 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -674,6 +674,7 @@ export abstract class DeployMethod Date: Fri, 8 May 2026 13:58:17 -0300 Subject: [PATCH 23/30] refactor(pxe): skip redundant getBlock RPC when querying at anchor block (#23100) --- .../oracle/utility_execution_oracle.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts index fe862fa4d271..dd5085e46311 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/utility_execution_oracle.ts @@ -995,6 +995,11 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra /** Runs a query concurrently with a validation that the block hash is not ahead of the anchor block. */ async #queryWithBlockHashNotAfterAnchor(blockHash: BlockHash, query: () => Promise): Promise { + const anchorHash = await this.anchorBlockHeader.hash(); + if (blockHash.equals(anchorHash)) { + return query(); + } + const [response] = await Promise.all([ query(), (async () => { @@ -1005,7 +1010,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra if (header.getBlockNumber() > this.anchorBlockHeader.getBlockNumber()) { throw new Error( - `Made a node query with a reference block hash ${blockHash} with block number ${header.getBlockNumber()}, which is ahead of the anchor block number ${this.anchorBlockHeader.getBlockNumber()} (from anchor block hash ${await this.anchorBlockHeader.hash()}).`, + `Made a node query with a reference block hash ${blockHash} with block number ${header.getBlockNumber()}, which is ahead of the anchor block number ${this.anchorBlockHeader.getBlockNumber()} (from anchor block hash ${anchorHash}).`, ); } })(), From 49100073af6024b5bd574c784d98b2d06836b8fe Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Fri, 8 May 2026 10:56:40 -0400 Subject: [PATCH 24/30] feat(ci): cherry-pick #23061 (with conflicts) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-picks f3911a8836 feat(ci): Snapshots for aztec-nr contract compilation failures and nargo expand (#23061). Conflicts (rename/delete style — no text markers): - noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/src/invalid_event.nr (renamed by #23061, deleted in v4-next-staging) — kept the renamed copy. - noir-projects/noir-contracts-comp-failures/bootstrap.sh and noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/expected_error (deleted by #23061, modified in v4-next-staging) — left as-is in this commit (HEAD content), removed in the follow-up resolution commit so reviewers can see what conflicted. --- Makefile | 1 - cspell.json | 4 +- noir-projects/bootstrap.sh | 2 +- noir-projects/contract-snapshots/.gitignore | 1 + noir-projects/contract-snapshots/Cargo.lock | 483 + noir-projects/contract-snapshots/Cargo.toml | 16 + noir-projects/contract-snapshots/README.md | 59 + noir-projects/contract-snapshots/bootstrap.sh | 45 + noir-projects/contract-snapshots/build.rs | 110 + noir-projects/contract-snapshots/src/lib.rs | 2 + .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../authorize_once_from_wrong_type/Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../authorize_once_on_utility_fn/Nargo.toml | 2 +- .../authorize_once_on_utility_fn/src/main.nr | 0 .../aztec_macro_too_many_args/Nargo.toml | 2 +- .../aztec_macro_too_many_args/src/main.nr | 0 .../compile_failure/bob_token/Nargo.toml | 8 + .../compile_failure}/bob_token/src/main.nr | 0 .../duplicate_storage/Nargo.toml | 2 +- .../duplicate_storage/src/main.nr | 0 .../event_selector_collision/Nargo.toml | 2 +- .../event_selector_collision/src/main.nr | 0 .../external_and_internal_together/Nargo.toml | 2 +- .../src/main.nr | 0 .../incorrect_storage_struct_name/Nargo.toml | 2 +- .../incorrect_storage_struct_name/src/main.nr | 0 .../initializer_on_non_external_fn/Nargo.toml | 2 +- .../src/main.nr | 0 .../initializer_on_utility_fn/Nargo.toml | 2 +- .../initializer_on_utility_fn/src/main.nr | 0 .../compile_failure}/invalid_event/Nargo.toml | 2 +- .../invalid_event/src/invalid_event.nr | 18 + .../invalid_event/src/main.nr | 0 .../invalid_external_function_type/Nargo.toml | 2 +- .../src/main.nr | 0 .../invalid_internal_function_type/Nargo.toml | 2 +- .../src/main.nr | 0 .../compile_failure}/invalid_note/Nargo.toml | 2 +- .../invalid_note/src/invalid_note.nr | 0 .../compile_failure}/invalid_note/src/main.nr | 0 .../marked_private_unconstrained/Nargo.toml | 2 +- .../marked_private_unconstrained/src/main.nr | 0 .../marked_public_unconstrained/Nargo.toml | 2 +- .../marked_public_unconstrained/src/main.nr | 0 .../noinitcheck_on_non_external_fn/Nargo.toml | 2 +- .../src/main.nr | 0 .../noinitcheck_on_utility_fn/Nargo.toml | 2 +- .../noinitcheck_on_utility_fn/src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../non_deserializable/Nargo.toml | 2 +- .../non_deserializable/src/main.nr | 0 .../non_serializable/Nargo.toml | 2 +- .../non_serializable/src/main.nr | 0 .../only_self_on_non_external_fn/Nargo.toml | 2 +- .../only_self_on_non_external_fn/src/main.nr | 0 .../only_self_on_utility_fn/Nargo.toml | 2 +- .../only_self_on_utility_fn/src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../pub_private_external_fn/Nargo.toml | 2 +- .../pub_private_external_fn/src/main.nr | 0 .../pub_public_external_fn/Nargo.toml | 2 +- .../pub_public_external_fn/src/main.nr | 0 .../pub_utility_external_fn/Nargo.toml | 2 +- .../pub_utility_external_fn/src/main.nr | 0 .../public_allow_phase_change/Nargo.toml | 2 +- .../public_allow_phase_change/src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../reserved_public_dispatch/Nargo.toml | 2 +- .../reserved_public_dispatch/src/main.nr | 0 .../Nargo.toml | 2 +- .../src/main.nr | 0 .../user_defined_offchain_receive/Nargo.toml | 2 +- .../user_defined_offchain_receive/src/main.nr | 0 .../utility_not_unconstrained/Nargo.toml | 2 +- .../utility_not_unconstrained/src/main.nr | 0 .../view_on_non_external_fn/Nargo.toml | 2 +- .../view_on_non_external_fn/src/main.nr | 0 .../view_on_utility_fn/Nargo.toml | 2 +- .../view_on_utility_fn/src/main.nr | 0 .../authorize_once_before_external/Nargo.toml | 2 +- .../src/main.nr | 0 .../contract-snapshots/tests/snapshots.rs | 107 + .../snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 67 + .../snapshots__stderr.snap | 27 + .../snapshots__stderr.snap | 27 + .../snapshots__stderr.snap | 27 + .../snapshots__stderr.snap | 27 + .../snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 17 + .../bob_token/snapshots__stderr.snap | 304 + .../duplicate_storage/snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 19 + .../invalid_event/snapshots__stderr.snap | 24 + .../snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 17 + .../invalid_note/snapshots__stderr.snap | 35 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 17 + .../non_deserializable/snapshots__stderr.snap | 77 + .../non_serializable/snapshots__stderr.snap | 77 + .../snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 15 + .../snapshots__stderr.snap | 15 + .../snapshots__stderr.snap | 15 + .../snapshots__stderr.snap | 15 + .../snapshots__stderr.snap | 15 + .../snapshots__stderr.snap | 25 + .../snapshots__stderr.snap | 26 + .../snapshots__stderr.snap | 25 + .../snapshots__stderr.snap | 26 + .../snapshots__stderr.snap | 41 + .../snapshots__stderr.snap | 41 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 23 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 17 + .../snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 17 + .../view_on_utility_fn/snapshots__stderr.snap | 19 + .../snapshots__stderr.snap | 5 + .../amm_contract/snapshots__expanded.snap | 2920 ++++++ .../snapshots__expanded.snap | 1655 ++++ .../snapshots__expanded.snap | 7788 +++++++++++++++++ .../snapshots__expanded.snap | 2146 +++++ .../token_contract/snapshots__expanded.snap | 4965 +++++++++++ .../noir-contracts-comp-failures/README.md | 37 - .../contracts/.gitignore | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 0 .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../aztec_macro_too_many_args/expected_error | 1 - .../contracts/bob_token/Nargo.toml | 8 - .../contracts/bob_token/expected_error | 38 - .../duplicate_storage/expected_error | 1 - .../event_selector_collision/expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../initializer_on_utility_fn/expected_error | 1 - .../contracts/invalid_event/expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../contracts/invalid_note/expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../noinitcheck_on_utility_fn/expected_error | 1 - .../expected_error | 1 - .../non_deserializable/expected_error | 6 - .../contracts/non_serializable/expected_error | 6 - .../expected_error | 1 - .../only_self_on_utility_fn/expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../expected_error | 2 - .../expected_error | 2 - .../expected_error | 2 - .../expected_error | 2 - .../expected_error | 3 - .../expected_error | 3 - .../pub_private_external_fn/expected_error | 1 - .../pub_public_external_fn/expected_error | 1 - .../pub_utility_external_fn/expected_error | 1 - .../public_allow_phase_change/expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../reserved_public_dispatch/expected_error | 1 - .../expected_error | 1 - .../expected_error | 1 - .../utility_not_unconstrained/expected_error | 1 - .../view_on_non_external_fn/expected_error | 1 - .../view_on_utility_fn/expected_error | 1 - 236 files changed, 21920 insertions(+), 209 deletions(-) create mode 100644 noir-projects/contract-snapshots/.gitignore create mode 100644 noir-projects/contract-snapshots/Cargo.lock create mode 100644 noir-projects/contract-snapshots/Cargo.toml create mode 100644 noir-projects/contract-snapshots/README.md create mode 100755 noir-projects/contract-snapshots/bootstrap.sh create mode 100644 noir-projects/contract-snapshots/build.rs create mode 100644 noir-projects/contract-snapshots/src/lib.rs rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/allow_phase_change_on_non_external_fn/Nargo.toml (68%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/allow_phase_change_on_non_external_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/allow_phase_change_on_utility_fn/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/allow_phase_change_on_utility_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorization_selector_collision/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorization_selector_collision/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_from_wrong_type/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_from_wrong_type/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_missing_from_param/Nargo.toml (68%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_missing_from_param/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_missing_nonce_param/Nargo.toml (68%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_missing_nonce_param/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_nonce_wrong_type/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_nonce_wrong_type/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_on_non_external_fn/Nargo.toml (68%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_on_non_external_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_on_utility_fn/Nargo.toml (66%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/authorize_once_on_utility_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/aztec_macro_too_many_args/Nargo.toml (66%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/aztec_macro_too_many_args/src/main.nr (100%) create mode 100644 noir-projects/contract-snapshots/test_programs/compile_failure/bob_token/Nargo.toml rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/bob_token/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/duplicate_storage/Nargo.toml (70%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/duplicate_storage/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/event_selector_collision/Nargo.toml (71%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/event_selector_collision/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/external_and_internal_together/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/external_and_internal_together/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/incorrect_storage_struct_name/Nargo.toml (72%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/incorrect_storage_struct_name/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/initializer_on_non_external_fn/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/initializer_on_non_external_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/initializer_on_utility_fn/Nargo.toml (66%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/initializer_on_utility_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/invalid_event/Nargo.toml (70%) create mode 100644 noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/src/invalid_event.nr rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/invalid_event/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/invalid_external_function_type/Nargo.toml (72%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/invalid_external_function_type/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/invalid_internal_function_type/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/invalid_internal_function_type/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/invalid_note/Nargo.toml (69%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/invalid_note/src/invalid_note.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/invalid_note/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/marked_private_unconstrained/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/marked_private_unconstrained/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/marked_public_unconstrained/Nargo.toml (66%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/marked_public_unconstrained/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/noinitcheck_on_non_external_fn/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/noinitcheck_on_non_external_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/noinitcheck_on_utility_fn/Nargo.toml (66%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/noinitcheck_on_utility_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/noinitcheck_without_initializer/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/noinitcheck_without_initializer/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/non_deserializable/Nargo.toml (70%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/non_deserializable/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/non_serializable/Nargo.toml (70%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/non_serializable/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/only_self_on_non_external_fn/Nargo.toml (66%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/only_self_on_non_external_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/only_self_on_utility_fn/Nargo.toml (65%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/only_self_on_utility_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_private_external_fn_call/Nargo.toml (74%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_private_external_fn_call/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_private_internal_fn_call/Nargo.toml (74%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_private_internal_fn_call/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_public_external_fn_call/Nargo.toml (74%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_public_external_fn_call/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_public_internal_fn_call/Nargo.toml (74%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_public_internal_fn_call/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_utility_external_fn_call/Nargo.toml (74%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_direct_utility_external_fn_call/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_incorrectly_performed_private_call/Nargo.toml (74%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_incorrectly_performed_private_call/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_incorrectly_performed_private_static_call/Nargo.toml (75%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_incorrectly_performed_private_static_call/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_incorrectly_performed_public_call/Nargo.toml (74%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_incorrectly_performed_public_call/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_incorrectly_performed_public_static_call/Nargo.toml (75%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_incorrectly_performed_public_static_call/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_non_state_var_in_storage/Nargo.toml (73%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_non_state_var_in_storage/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_owned_state_var_in_storage/Nargo.toml (73%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/panic_on_owned_state_var_in_storage/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/pub_private_external_fn/Nargo.toml (65%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/pub_private_external_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/pub_public_external_fn/Nargo.toml (65%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/pub_public_external_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/pub_utility_external_fn/Nargo.toml (65%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/pub_utility_external_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/public_allow_phase_change/Nargo.toml (66%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/public_allow_phase_change/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/public_function_selector_collision/Nargo.toml (73%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/public_function_selector_collision/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/reserved_emit_public_init_nullifier/Nargo.toml (68%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/reserved_emit_public_init_nullifier/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/reserved_public_dispatch/Nargo.toml (65%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/reserved_public_dispatch/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/unmacroified_function_in_contract/Nargo.toml (68%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/unmacroified_function_in_contract/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/user_defined_offchain_receive/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/user_defined_offchain_receive/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/utility_not_unconstrained/Nargo.toml (66%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/utility_not_unconstrained/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/view_on_non_external_fn/Nargo.toml (65%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/view_on_non_external_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/view_on_utility_fn/Nargo.toml (64%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_failure}/view_on_utility_fn/src/main.nr (100%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_success}/authorize_once_before_external/Nargo.toml (67%) rename noir-projects/{noir-contracts-comp-failures/contracts => contract-snapshots/test_programs/compile_success}/authorize_once_before_external/src/main.nr (100%) create mode 100644 noir-projects/contract-snapshots/tests/snapshots.rs create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/allow_phase_change_on_non_external_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/allow_phase_change_on_utility_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorization_selector_collision/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_from_wrong_type/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_from_param/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_nonce_param/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_nonce_wrong_type/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_on_non_external_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_on_utility_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/aztec_macro_too_many_args/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/bob_token/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/duplicate_storage/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/event_selector_collision/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/external_and_internal_together/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/incorrect_storage_struct_name/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/initializer_on_non_external_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/initializer_on_utility_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_event/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_external_function_type/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_internal_function_type/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_note/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/marked_private_unconstrained/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/marked_public_unconstrained/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_on_non_external_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_on_utility_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_without_initializer/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/non_deserializable/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/non_serializable/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/only_self_on_non_external_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/only_self_on_utility_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_private_external_fn_call/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_private_internal_fn_call/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_public_external_fn_call/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_public_internal_fn_call/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_utility_external_fn_call/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_private_call/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_private_static_call/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_public_call/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_public_static_call/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_non_state_var_in_storage/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_owned_state_var_in_storage/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_private_external_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_public_external_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_utility_external_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_allow_phase_change/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_function_selector_collision/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/reserved_emit_public_init_nullifier/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/reserved_public_dispatch/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/unmacroified_function_in_contract/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_offchain_receive/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/utility_not_unconstrained/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/view_on_non_external_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_failure/view_on_utility_fn/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/compile_success/authorize_once_before_external/snapshots__stderr.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/expand/amm_contract/snapshots__expanded.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/expand/storage_proof_test_contract/snapshots__expanded.snap create mode 100644 noir-projects/contract-snapshots/tests/snapshots/expand/token_contract/snapshots__expanded.snap delete mode 100644 noir-projects/noir-contracts-comp-failures/README.md delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/.gitignore delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_non_external_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_utility_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/authorize_once_before_external/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/authorize_once_from_wrong_type/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_from_param/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_nonce_param/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/authorize_once_nonce_wrong_type/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_non_external_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_utility_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/aztec_macro_too_many_args/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/bob_token/Nargo.toml delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/bob_token/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/duplicate_storage/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/event_selector_collision/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/external_and_internal_together/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/incorrect_storage_struct_name/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/initializer_on_non_external_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/initializer_on_utility_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/invalid_event/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/invalid_external_function_type/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/invalid_internal_function_type/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/invalid_note/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/marked_private_unconstrained/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/marked_public_unconstrained/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_non_external_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_utility_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_without_initializer/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/non_serializable/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/only_self_on_non_external_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/only_self_on_utility_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_external_fn_call/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_internal_fn_call/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_external_fn_call/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_internal_fn_call/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_utility_external_fn_call/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_call/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_static_call/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_call/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_static_call/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_non_state_var_in_storage/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/panic_on_owned_state_var_in_storage/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/pub_private_external_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/pub_public_external_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/pub_utility_external_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/public_allow_phase_change/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/public_function_selector_collision/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/reserved_emit_public_init_nullifier/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/reserved_public_dispatch/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/unmacroified_function_in_contract/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/user_defined_offchain_receive/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/utility_not_unconstrained/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/view_on_non_external_fn/expected_error delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/view_on_utility_fn/expected_error diff --git a/Makefile b/Makefile index a16906bc63b3..f6a6dc4a7b5a 100644 --- a/Makefile +++ b/Makefile @@ -262,7 +262,6 @@ aztec-nr: noir bb-cpp-native noir-projects-txe-tests: $(call test,$@,noir-projects/aztec-nr) $(call test,$@,noir-projects/noir-contracts) - $(call test,$@,noir-projects/noir-contracts-comp-failures) # Noir Projects - Aggregate target (builds all sub-projects) noir-projects: noir-protocol-circuits mock-protocol-circuits noir-contracts aztec-nr diff --git a/cspell.json b/cspell.json index 9766afc1ea5a..f792d7920a47 100644 --- a/cspell.json +++ b/cspell.json @@ -71,6 +71,7 @@ "cimg", "ciphertext", "ciphertexts", + "clippy", "clonedeep", "clonedeepwith", "cmd", @@ -171,6 +172,7 @@ "includable", "incrementation", "indexeddb", + "INSTA", "interruptible", "IPFS", "isequal", @@ -367,8 +369,8 @@ "unfinalized", "uniquified", "uniquify", - "unlinkability", "unkonstrained", + "unlinkability", "unnullify", "unpadded", "unprefixed", diff --git a/noir-projects/bootstrap.sh b/noir-projects/bootstrap.sh index 9bd80aeea54a..006f75495900 100755 --- a/noir-projects/bootstrap.sh +++ b/noir-projects/bootstrap.sh @@ -26,7 +26,7 @@ function build { } function test_cmds { - parallel -k ./{}/bootstrap.sh test_cmds ::: noir-protocol-circuits noir-contracts aztec-nr noir-contracts-comp-failures + parallel -k ./{}/bootstrap.sh test_cmds ::: noir-protocol-circuits noir-contracts aztec-nr contract-snapshots } function test { diff --git a/noir-projects/contract-snapshots/.gitignore b/noir-projects/contract-snapshots/.gitignore new file mode 100644 index 000000000000..ab3f4c8d559c --- /dev/null +++ b/noir-projects/contract-snapshots/.gitignore @@ -0,0 +1 @@ +/**/target/ diff --git a/noir-projects/contract-snapshots/Cargo.lock b/noir-projects/contract-snapshots/Cargo.lock new file mode 100644 index 000000000000..255d09d74e94 --- /dev/null +++ b/noir-projects/contract-snapshots/Cargo.lock @@ -0,0 +1,483 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "console" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +dependencies = [ + "encode_unicode", + "libc", + "windows-sys", +] + +[[package]] +name = "contract-snapshots" +version = "0.1.0" +dependencies = [ + "insta", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.0", + "serde", + "serde_core", +] + +[[package]] +name = "insta" +version = "1.47.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4a6248eb93a4401ed2f37dfe8ea592d3cf05b7cf4f8efa867b6895af7e094e" +dependencies = [ + "console", + "once_cell", + "similar", + "tempfile", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/noir-projects/contract-snapshots/Cargo.toml b/noir-projects/contract-snapshots/Cargo.toml new file mode 100644 index 000000000000..1fc3e8e0f3b4 --- /dev/null +++ b/noir-projects/contract-snapshots/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "contract-snapshots" +version = "0.1.0" +edition = "2024" +publish = false + +[lib] +path = "src/lib.rs" + +[[test]] +name = "snapshots" +path = "tests/snapshots.rs" +harness = true + +[dev-dependencies] +insta = "1" diff --git a/noir-projects/contract-snapshots/README.md b/noir-projects/contract-snapshots/README.md new file mode 100644 index 000000000000..fb8614eeb502 --- /dev/null +++ b/noir-projects/contract-snapshots/README.md @@ -0,0 +1,59 @@ +## Noir Contract Snapshots + +`cargo insta` snapshot tests for noir contracts. Two test categories live here: + +- **`expand/`** — runs `nargo expand` on a curated set of aztec-nr contracts (mirrors what CI benchmarks already exercise) and snapshots the expanded source. Surface for catching macro regressions that pass typechecking but silently change generated code. +- **`compile_failure/`** — drives `nargo compile` on intentionally invalid aztec-nr contracts and snapshots the full stderr. + +### Layout + +``` +Cargo.toml +build.rs # generates one #[test] per case at build time +tests/ + snapshots.rs # run_compile_failure / run_expand helpers + snapshots/ + compile_failure//*.snap # committed + expand//*.snap # committed +test_programs/ + compile_failure//{Nargo.toml,src/main.nr} +``` + +`expand` cases are *not* duplicated under `test_programs/`. They live in their canonical home under `noir-contracts/contracts/{app,test}/` and are referenced by relative path from `build.rs` (`EXPAND_CASES`). + +### Prerequisites + +`nargo` must be built. From the repo root: + +```sh +(cd noir && ./bootstrap.sh) +``` + +By default the test harness looks for `nargo` at `../../noir/noir-repo/target/release/nargo`. Override with `NARGO=/path/to/nargo cargo test`. + +### Running + +```sh +cargo test # run all snapshot tests +cargo test --test snapshots compile_failure # run one module +cargo test --test snapshots test_token # run one test (substring match) +``` + +### Updating snapshots + +Failing assertions write `.snap.new` siblings. Review them by reading the file, or use the review UI: + +```sh +cargo insta review # interactive, recommended +cargo insta accept # accept all pending snapshots +cargo insta test --accept # run + accept in one step (needed + # when the .snap doesn't exist yet) +``` + +CI rejects `INSTA_UPDATE`; any drift must be resolved locally and committed. + +### Adding a case + +`expand`: append `(name, relative_path)` to `EXPAND_CASES` in `build.rs`, then `cargo insta test --accept`. + +`compile_failure`: drop a contract under `test_programs/compile_failure//` (`Nargo.toml` + `src/main.nr`), then `cargo insta test --accept`. Case directory names must use `_`, not `-`. diff --git a/noir-projects/contract-snapshots/bootstrap.sh b/noir-projects/contract-snapshots/bootstrap.sh new file mode 100755 index 000000000000..f4ae19760903 --- /dev/null +++ b/noir-projects/contract-snapshots/bootstrap.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +source $(git rev-parse --show-toplevel)/ci3/source_bootstrap + +# nargo binary path relative to the crate root (this directory) +export NARGO=${NARGO:-../../noir/noir-repo/target/release/nargo} + +# Build the snapshot test binaries (compiles build.rs codegen too) and run Rust lints. +function build { + echo_header "contract-snapshots build" + denoise "cargo build --tests" + denoise "cargo fmt --check" + denoise "cargo clippy --all-targets" +} + +# Run the snapshot tests. CI rejects INSTA_UPDATE so any drift between +# committed snapshots and reality must be resolved intentionally by a developer. +function test { + echo_header "contract-snapshots test" + if [ "${CI:-0}" = "1" ] && [ -n "${INSTA_UPDATE:-}" ] && [ "${INSTA_UPDATE}" != "no" ]; then + echo "INSTA_UPDATE is not permitted in CI. Run 'cargo insta accept' locally and commit." >&2 + exit 1 + fi + INSTA_UPDATE=no cargo test --quiet +} + +function test_cmds { + if [ "${TARGET_BRANCH:-}" = "merge-train/fairies" ]; then + hash=disabled-cache + else + hash=$(hash_str \ + $(../../noir/bootstrap.sh hash) \ + $(cache_content_hash \ + ^noir-projects/contract-snapshots \ + ^noir-projects/noir-contracts/contracts/app \ + ^noir-projects/noir-contracts/contracts/test \ + ^noir-projects/aztec-nr)) + fi + echo "$hash ./noir-projects/contract-snapshots/bootstrap.sh test" +} + +case "$cmd" in + *) + default_cmd_handler "$@" + ;; +esac diff --git a/noir-projects/contract-snapshots/build.rs b/noir-projects/contract-snapshots/build.rs new file mode 100644 index 000000000000..22949c8a6e68 --- /dev/null +++ b/noir-projects/contract-snapshots/build.rs @@ -0,0 +1,110 @@ +use std::env; +use std::fs::{self, File}; +use std::io::Write; +use std::path::{Path, PathBuf}; + +/// Contracts whose `nargo expand` output is snapshotted. The set is kept +/// aligned with the contracts already exercised by CI benchmarks so that +/// macro-induced diffs and benchmark deltas show up on the same review. +/// +/// To add a case: append an entry here and run +/// `cargo insta test --accept -p contract-snapshots`. +const EXPAND_CASES: &[(&str, &str)] = &[ + ( + "token_contract", + "../noir-contracts/contracts/app/token_contract", + ), + ( + "amm_contract", + "../noir-contracts/contracts/app/amm_contract", + ), + ( + "storage_proof_test_contract", + "../noir-contracts/contracts/test/storage_proof_test_contract", + ), + ( + "avm_test_contract", + "../noir-contracts/contracts/test/avm_test_contract", + ), + ( + "avm_gadgets_test_contract", + "../noir-contracts/contracts/test/avm_gadgets_test_contract", + ), +]; + +fn main() { + let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + let dest = out_dir.join("tests.rs"); + let mut f = File::create(&dest).unwrap(); + + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=test_programs"); + for (_, rel) in EXPAND_CASES { + let abs = manifest_dir.join(rel); + println!("cargo:rerun-if-changed={}", abs.display()); + } + + write_dir_scanned_module( + &mut f, + &manifest_dir, + "compile_failure", + "run_compile_failure", + ); + write_dir_scanned_module( + &mut f, + &manifest_dir, + "compile_success", + "run_compile_success", + ); + write_expand_module(&mut f, &manifest_dir); +} + +fn write_dir_scanned_module(f: &mut File, manifest_dir: &Path, module: &str, helper: &str) { + let test_dir = manifest_dir.join(format!("test_programs/{module}")); + let mut cases: Vec<(String, PathBuf)> = fs::read_dir(&test_dir) + .unwrap_or_else(|e| { + panic!("could not read {}: {e}", test_dir.display()); + }) + .filter_map(Result::ok) + .filter(|e| e.path().is_dir() && e.path().join("Nargo.toml").exists()) + .map(|e| (e.file_name().into_string().unwrap(), e.path())) + .collect(); + cases.sort_by(|a, b| a.0.cmp(&b.0)); + + writeln!(f, "mod {module} {{").unwrap(); + for (name, path) in cases { + if name.contains('-') { + panic!("{module} case '{name}' must use '_' instead of '-'"); + } + writeln!( + f, + " #[test]\n fn test_{name}() {{\n super::{helper}(\"{name}\", std::path::PathBuf::from(r\"{path}\"));\n }}", + name = name, + path = path.display() + ) + .unwrap(); + } + writeln!(f, "}}").unwrap(); +} + +fn write_expand_module(f: &mut File, manifest_dir: &Path) { + writeln!(f, "mod expand {{").unwrap(); + for (name, rel) in EXPAND_CASES { + let path = manifest_dir.join(rel); + if !path.join("Nargo.toml").exists() { + panic!( + "expand case '{name}' has no Nargo.toml at {}", + path.display() + ); + } + writeln!( + f, + " #[test]\n fn test_{name}() {{\n super::run_expand(\"{name}\", std::path::PathBuf::from(r\"{path}\"));\n }}", + name = name, + path = path.display() + ) + .unwrap(); + } + writeln!(f, "}}").unwrap(); +} diff --git a/noir-projects/contract-snapshots/src/lib.rs b/noir-projects/contract-snapshots/src/lib.rs new file mode 100644 index 000000000000..ee7fc1b5c1f7 --- /dev/null +++ b/noir-projects/contract-snapshots/src/lib.rs @@ -0,0 +1,2 @@ +// This crate exists only to host integration tests under `tests/`. +// See `tests/snapshots.rs` and `build.rs` for the snapshot harness. diff --git a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_non_external_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_non_external_fn/Nargo.toml similarity index 68% rename from noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_non_external_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_non_external_fn/Nargo.toml index d2f5cfdc1eab..da4774a995f2 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_non_external_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_non_external_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_non_external_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_non_external_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_non_external_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_non_external_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_utility_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_utility_fn/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_utility_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_utility_fn/Nargo.toml index b3882cc6718e..67924e498857 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_utility_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_utility_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_utility_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_utility_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_utility_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/allow_phase_change_on_utility_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/authorization_selector_collision/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorization_selector_collision/Nargo.toml index 40ed4eabd259..1f269b35f385 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/authorization_selector_collision/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/authorization_selector_collision/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorization_selector_collision/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_from_wrong_type/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_from_wrong_type/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_from_wrong_type/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_from_wrong_type/Nargo.toml index 7130df19571a..26dc88d27a96 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_from_wrong_type/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_from_wrong_type/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_from_wrong_type/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_from_wrong_type/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_from_wrong_type/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_from_wrong_type/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_from_param/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_from_param/Nargo.toml similarity index 68% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_from_param/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_from_param/Nargo.toml index e3c0421eff43..59aafcbdb88d 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_from_param/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_from_param/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_from_param/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_from_param/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_from_param/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_from_param/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_nonce_param/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_nonce_param/Nargo.toml similarity index 68% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_nonce_param/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_nonce_param/Nargo.toml index 35c56f6dc0ef..ff272f0651e4 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_nonce_param/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_nonce_param/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_nonce_param/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_nonce_param/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_nonce_param/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_missing_nonce_param/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_nonce_wrong_type/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_nonce_wrong_type/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_nonce_wrong_type/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_nonce_wrong_type/Nargo.toml index ba1ea98efb15..3ee987f8d6ad 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_nonce_wrong_type/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_nonce_wrong_type/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_nonce_wrong_type/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_nonce_wrong_type/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_nonce_wrong_type/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_nonce_wrong_type/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_non_external_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_non_external_fn/Nargo.toml similarity index 68% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_non_external_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_non_external_fn/Nargo.toml index 31296f301ec6..e58946a6d681 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_non_external_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_non_external_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_non_external_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_non_external_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_non_external_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_non_external_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_utility_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_utility_fn/Nargo.toml similarity index 66% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_utility_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_utility_fn/Nargo.toml index ac377a90737c..ecc202de402f 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_utility_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_utility_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_utility_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_utility_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_utility_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/authorize_once_on_utility_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/aztec_macro_too_many_args/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/aztec_macro_too_many_args/Nargo.toml similarity index 66% rename from noir-projects/noir-contracts-comp-failures/contracts/aztec_macro_too_many_args/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/aztec_macro_too_many_args/Nargo.toml index 291f3c46342c..7b828f3c6b14 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/aztec_macro_too_many_args/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/aztec_macro_too_many_args/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/aztec_macro_too_many_args/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/aztec_macro_too_many_args/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/aztec_macro_too_many_args/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/aztec_macro_too_many_args/src/main.nr diff --git a/noir-projects/contract-snapshots/test_programs/compile_failure/bob_token/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/bob_token/Nargo.toml new file mode 100644 index 000000000000..906fff22a0eb --- /dev/null +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/bob_token/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "bob_token" +type = "contract" +authors = [""] + +[dependencies] +aztec = { path = "../../../../aztec-nr/aztec" } +balance_set = { path = "../../../../aztec-nr/balance-set" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/bob_token/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/bob_token/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/bob_token/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/bob_token/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/duplicate_storage/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/duplicate_storage/Nargo.toml similarity index 70% rename from noir-projects/noir-contracts-comp-failures/contracts/duplicate_storage/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/duplicate_storage/Nargo.toml index 9a28991054e9..1d0b0ee4ebed 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/duplicate_storage/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/duplicate_storage/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/duplicate_storage/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/duplicate_storage/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/duplicate_storage/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/duplicate_storage/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/event_selector_collision/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/event_selector_collision/Nargo.toml similarity index 71% rename from noir-projects/noir-contracts-comp-failures/contracts/event_selector_collision/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/event_selector_collision/Nargo.toml index 1ba8876ac6c4..5a93463ca0e9 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/event_selector_collision/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/event_selector_collision/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/event_selector_collision/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/event_selector_collision/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/event_selector_collision/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/event_selector_collision/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/external_and_internal_together/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/external_and_internal_together/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/external_and_internal_together/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/external_and_internal_together/Nargo.toml index 8f052fb53c2c..1eae6b6af3c8 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/external_and_internal_together/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/external_and_internal_together/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/external_and_internal_together/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/external_and_internal_together/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/external_and_internal_together/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/external_and_internal_together/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/incorrect_storage_struct_name/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/incorrect_storage_struct_name/Nargo.toml similarity index 72% rename from noir-projects/noir-contracts-comp-failures/contracts/incorrect_storage_struct_name/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/incorrect_storage_struct_name/Nargo.toml index 68a469c38437..86f7c26acbc0 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/incorrect_storage_struct_name/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/incorrect_storage_struct_name/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/incorrect_storage_struct_name/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/incorrect_storage_struct_name/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/incorrect_storage_struct_name/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/incorrect_storage_struct_name/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_non_external_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_non_external_fn/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/initializer_on_non_external_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_non_external_fn/Nargo.toml index d9076ac44554..14405987b386 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_non_external_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_non_external_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_non_external_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_non_external_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/initializer_on_non_external_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_non_external_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_utility_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_utility_fn/Nargo.toml similarity index 66% rename from noir-projects/noir-contracts-comp-failures/contracts/initializer_on_utility_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_utility_fn/Nargo.toml index 5849c6d94ea0..70a86d6d1ba3 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_utility_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_utility_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_utility_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_utility_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/initializer_on_utility_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/initializer_on_utility_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/Nargo.toml similarity index 70% rename from noir-projects/noir-contracts-comp-failures/contracts/invalid_event/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/Nargo.toml index fd5c446ab345..7004854044c4 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/src/invalid_event.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/src/invalid_event.nr new file mode 100644 index 000000000000..a38ba6855727 --- /dev/null +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/src/invalid_event.nr @@ -0,0 +1,18 @@ +use aztec::{ + macros::events::event, + messages::logs::event::MAX_EVENT_SERIALIZED_LEN, + protocol::{traits::Serialize, utils::writer::Writer}, +}; + +#[event] +pub struct InvalidEvent {} + +impl Serialize for InvalidEvent { + let N: u32 = MAX_EVENT_SERIALIZED_LEN + 1; + + fn serialize(self) -> [Field; Self::N] { + std::mem::zeroed() + } + + fn stream_serialize(self, _writer: &mut Writer) {} +} diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/invalid_event/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/invalid_event/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_external_function_type/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_external_function_type/Nargo.toml similarity index 72% rename from noir-projects/noir-contracts-comp-failures/contracts/invalid_external_function_type/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/invalid_external_function_type/Nargo.toml index 7e8025f4774d..fe12bc8fb0b1 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/invalid_external_function_type/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_external_function_type/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_external_function_type/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_external_function_type/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/invalid_external_function_type/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/invalid_external_function_type/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_internal_function_type/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_internal_function_type/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/invalid_internal_function_type/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/invalid_internal_function_type/Nargo.toml index 0d007ec76ca0..23b910e04b73 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/invalid_internal_function_type/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_internal_function_type/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_internal_function_type/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_internal_function_type/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/invalid_internal_function_type/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/invalid_internal_function_type/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_note/Nargo.toml similarity index 69% rename from noir-projects/noir-contracts-comp-failures/contracts/invalid_note/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/invalid_note/Nargo.toml index a94a89957382..f17604c48746 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_note/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/src/invalid_note.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_note/src/invalid_note.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/invalid_note/src/invalid_note.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/invalid_note/src/invalid_note.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/invalid_note/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/invalid_note/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/invalid_note/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/marked_private_unconstrained/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/marked_private_unconstrained/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/marked_private_unconstrained/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/marked_private_unconstrained/Nargo.toml index f72f5810797a..4c0448e82d09 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/marked_private_unconstrained/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/marked_private_unconstrained/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } \ No newline at end of file +aztec = { path = "../../../../aztec-nr/aztec" } \ No newline at end of file diff --git a/noir-projects/noir-contracts-comp-failures/contracts/marked_private_unconstrained/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/marked_private_unconstrained/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/marked_private_unconstrained/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/marked_private_unconstrained/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/marked_public_unconstrained/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/marked_public_unconstrained/Nargo.toml similarity index 66% rename from noir-projects/noir-contracts-comp-failures/contracts/marked_public_unconstrained/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/marked_public_unconstrained/Nargo.toml index b77dd5e5b4a7..01d1135d3b57 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/marked_public_unconstrained/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/marked_public_unconstrained/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/marked_public_unconstrained/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/marked_public_unconstrained/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/marked_public_unconstrained/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/marked_public_unconstrained/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_non_external_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_non_external_fn/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_non_external_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_non_external_fn/Nargo.toml index 14327850fecb..a6ac1090fa28 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_non_external_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_non_external_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_non_external_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_non_external_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_non_external_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_non_external_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_utility_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_utility_fn/Nargo.toml similarity index 66% rename from noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_utility_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_utility_fn/Nargo.toml index de8971626ad0..0638ade66b1f 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_utility_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_utility_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_utility_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_utility_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_utility_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_on_utility_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_without_initializer/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_without_initializer/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_without_initializer/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_without_initializer/Nargo.toml index b6785b52010e..e4977f869e05 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_without_initializer/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_without_initializer/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_without_initializer/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_without_initializer/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_without_initializer/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/noinitcheck_without_initializer/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/non_deserializable/Nargo.toml similarity index 70% rename from noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/non_deserializable/Nargo.toml index 5914769cb4d6..f3dcc8cfe2e6 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/non_deserializable/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/non_deserializable/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/non_deserializable/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/non_serializable/Nargo.toml similarity index 70% rename from noir-projects/noir-contracts-comp-failures/contracts/non_serializable/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/non_serializable/Nargo.toml index 61dd673b2bd3..cdab1cef9a69 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/non_serializable/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/non_serializable/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/non_serializable/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/non_serializable/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_non_external_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_non_external_fn/Nargo.toml similarity index 66% rename from noir-projects/noir-contracts-comp-failures/contracts/only_self_on_non_external_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_non_external_fn/Nargo.toml index 286bc46ee0af..72dda38ed4e6 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_non_external_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_non_external_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_non_external_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_non_external_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/only_self_on_non_external_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_non_external_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_utility_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_utility_fn/Nargo.toml similarity index 65% rename from noir-projects/noir-contracts-comp-failures/contracts/only_self_on_utility_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_utility_fn/Nargo.toml index 4560f50a26e3..f8be0fd46638 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_utility_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_utility_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_utility_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_utility_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/only_self_on_utility_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/only_self_on_utility_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_external_fn_call/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_external_fn_call/Nargo.toml similarity index 74% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_external_fn_call/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_external_fn_call/Nargo.toml index 35ab8ec6157d..6eed4a585ff7 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_external_fn_call/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_external_fn_call/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_external_fn_call/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_external_fn_call/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_external_fn_call/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_external_fn_call/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_internal_fn_call/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_internal_fn_call/Nargo.toml similarity index 74% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_internal_fn_call/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_internal_fn_call/Nargo.toml index f1ad725a4ce8..436b4ee2e970 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_internal_fn_call/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_internal_fn_call/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_internal_fn_call/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_internal_fn_call/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_internal_fn_call/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_private_internal_fn_call/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_external_fn_call/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_external_fn_call/Nargo.toml similarity index 74% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_external_fn_call/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_external_fn_call/Nargo.toml index a7ce32c176e5..ec3e23bb13da 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_external_fn_call/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_external_fn_call/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_external_fn_call/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_external_fn_call/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_external_fn_call/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_external_fn_call/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_internal_fn_call/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_internal_fn_call/Nargo.toml similarity index 74% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_internal_fn_call/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_internal_fn_call/Nargo.toml index f740d59f6626..84a37e697ef4 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_internal_fn_call/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_internal_fn_call/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_internal_fn_call/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_internal_fn_call/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_internal_fn_call/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_public_internal_fn_call/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_utility_external_fn_call/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_utility_external_fn_call/Nargo.toml similarity index 74% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_utility_external_fn_call/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_utility_external_fn_call/Nargo.toml index 261086647ccd..f56dc5fb2456 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_utility_external_fn_call/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_utility_external_fn_call/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_utility_external_fn_call/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_utility_external_fn_call/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_utility_external_fn_call/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_direct_utility_external_fn_call/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_call/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_call/Nargo.toml similarity index 74% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_call/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_call/Nargo.toml index a40cc7085669..64f73d29257e 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_call/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_call/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_call/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_call/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_call/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_call/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_static_call/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_static_call/Nargo.toml similarity index 75% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_static_call/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_static_call/Nargo.toml index 7f0978672f74..96d0dc5861ba 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_static_call/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_static_call/Nargo.toml @@ -5,5 +5,5 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_static_call/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_static_call/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_static_call/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_private_static_call/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_call/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_call/Nargo.toml similarity index 74% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_call/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_call/Nargo.toml index 82418ccd25ca..ae1de16b581c 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_call/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_call/Nargo.toml @@ -5,5 +5,5 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_call/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_call/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_call/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_call/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_static_call/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_static_call/Nargo.toml similarity index 75% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_static_call/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_static_call/Nargo.toml index 0bcb6a7437d8..69528a9afa01 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_static_call/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_static_call/Nargo.toml @@ -5,5 +5,5 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_static_call/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_static_call/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_static_call/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_incorrectly_performed_public_static_call/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_non_state_var_in_storage/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_non_state_var_in_storage/Nargo.toml similarity index 73% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_non_state_var_in_storage/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_non_state_var_in_storage/Nargo.toml index 84c1a3f7fff7..ce8727023340 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_non_state_var_in_storage/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_non_state_var_in_storage/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_non_state_var_in_storage/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_non_state_var_in_storage/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_non_state_var_in_storage/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_non_state_var_in_storage/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_owned_state_var_in_storage/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_owned_state_var_in_storage/Nargo.toml similarity index 73% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_owned_state_var_in_storage/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_owned_state_var_in_storage/Nargo.toml index 597dc861fd55..cabcfcb6cdd5 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_owned_state_var_in_storage/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_owned_state_var_in_storage/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_owned_state_var_in_storage/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_owned_state_var_in_storage/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/panic_on_owned_state_var_in_storage/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/panic_on_owned_state_var_in_storage/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/pub_private_external_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/pub_private_external_fn/Nargo.toml similarity index 65% rename from noir-projects/noir-contracts-comp-failures/contracts/pub_private_external_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/pub_private_external_fn/Nargo.toml index cc1650303414..431efaa8d4b3 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/pub_private_external_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/pub_private_external_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/pub_private_external_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/pub_private_external_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/pub_private_external_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/pub_private_external_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/pub_public_external_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/pub_public_external_fn/Nargo.toml similarity index 65% rename from noir-projects/noir-contracts-comp-failures/contracts/pub_public_external_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/pub_public_external_fn/Nargo.toml index 7953452634e6..1863966a4d4b 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/pub_public_external_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/pub_public_external_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/pub_public_external_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/pub_public_external_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/pub_public_external_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/pub_public_external_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/pub_utility_external_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/pub_utility_external_fn/Nargo.toml similarity index 65% rename from noir-projects/noir-contracts-comp-failures/contracts/pub_utility_external_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/pub_utility_external_fn/Nargo.toml index 6e878c49849c..94a7e823a84b 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/pub_utility_external_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/pub_utility_external_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/pub_utility_external_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/pub_utility_external_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/pub_utility_external_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/pub_utility_external_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/public_allow_phase_change/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/public_allow_phase_change/Nargo.toml similarity index 66% rename from noir-projects/noir-contracts-comp-failures/contracts/public_allow_phase_change/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/public_allow_phase_change/Nargo.toml index 0d19a888079a..fcc5e3960242 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/public_allow_phase_change/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/public_allow_phase_change/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/public_allow_phase_change/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/public_allow_phase_change/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/public_allow_phase_change/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/public_allow_phase_change/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/public_function_selector_collision/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/public_function_selector_collision/Nargo.toml similarity index 73% rename from noir-projects/noir-contracts-comp-failures/contracts/public_function_selector_collision/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/public_function_selector_collision/Nargo.toml index fc464e417620..7bd2e4a7abca 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/public_function_selector_collision/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/public_function_selector_collision/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.25.0" type = "contract" [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/public_function_selector_collision/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/public_function_selector_collision/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/public_function_selector_collision/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/public_function_selector_collision/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/reserved_emit_public_init_nullifier/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/reserved_emit_public_init_nullifier/Nargo.toml similarity index 68% rename from noir-projects/noir-contracts-comp-failures/contracts/reserved_emit_public_init_nullifier/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/reserved_emit_public_init_nullifier/Nargo.toml index 7a20f71d024d..3fb10af0c6af 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/reserved_emit_public_init_nullifier/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/reserved_emit_public_init_nullifier/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/reserved_emit_public_init_nullifier/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/reserved_emit_public_init_nullifier/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/reserved_emit_public_init_nullifier/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/reserved_emit_public_init_nullifier/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/reserved_public_dispatch/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/reserved_public_dispatch/Nargo.toml similarity index 65% rename from noir-projects/noir-contracts-comp-failures/contracts/reserved_public_dispatch/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/reserved_public_dispatch/Nargo.toml index a15aff4abcac..f875ce7c8202 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/reserved_public_dispatch/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/reserved_public_dispatch/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/reserved_public_dispatch/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/reserved_public_dispatch/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/reserved_public_dispatch/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/reserved_public_dispatch/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/unmacroified_function_in_contract/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/unmacroified_function_in_contract/Nargo.toml similarity index 68% rename from noir-projects/noir-contracts-comp-failures/contracts/unmacroified_function_in_contract/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/unmacroified_function_in_contract/Nargo.toml index 20537523e403..d4a297a56c34 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/unmacroified_function_in_contract/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/unmacroified_function_in_contract/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/unmacroified_function_in_contract/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/unmacroified_function_in_contract/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/unmacroified_function_in_contract/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/unmacroified_function_in_contract/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/user_defined_offchain_receive/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_offchain_receive/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/user_defined_offchain_receive/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_offchain_receive/Nargo.toml index e9269ae24e7a..0c1533e2caeb 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/user_defined_offchain_receive/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_offchain_receive/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/user_defined_offchain_receive/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_offchain_receive/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/user_defined_offchain_receive/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/user_defined_offchain_receive/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/utility_not_unconstrained/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/utility_not_unconstrained/Nargo.toml similarity index 66% rename from noir-projects/noir-contracts-comp-failures/contracts/utility_not_unconstrained/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/utility_not_unconstrained/Nargo.toml index 323d48fb2edc..8d2ada72c96a 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/utility_not_unconstrained/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/utility_not_unconstrained/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/utility_not_unconstrained/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/utility_not_unconstrained/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/utility_not_unconstrained/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/utility_not_unconstrained/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/view_on_non_external_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/view_on_non_external_fn/Nargo.toml similarity index 65% rename from noir-projects/noir-contracts-comp-failures/contracts/view_on_non_external_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/view_on_non_external_fn/Nargo.toml index 3461ff6d5fe4..5ab0d2b3adfb 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/view_on_non_external_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/view_on_non_external_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/view_on_non_external_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/view_on_non_external_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/view_on_non_external_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/view_on_non_external_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/view_on_utility_fn/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_failure/view_on_utility_fn/Nargo.toml similarity index 64% rename from noir-projects/noir-contracts-comp-failures/contracts/view_on_utility_fn/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_failure/view_on_utility_fn/Nargo.toml index c4845c37358f..7da9cd25bdaf 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/view_on_utility_fn/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_failure/view_on_utility_fn/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/view_on_utility_fn/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_failure/view_on_utility_fn/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/view_on_utility_fn/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_failure/view_on_utility_fn/src/main.nr diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_before_external/Nargo.toml b/noir-projects/contract-snapshots/test_programs/compile_success/authorize_once_before_external/Nargo.toml similarity index 67% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_before_external/Nargo.toml rename to noir-projects/contract-snapshots/test_programs/compile_success/authorize_once_before_external/Nargo.toml index f29f5d173b46..a2b023bb7165 100644 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_before_external/Nargo.toml +++ b/noir-projects/contract-snapshots/test_programs/compile_success/authorize_once_before_external/Nargo.toml @@ -4,4 +4,4 @@ type = "contract" authors = [""] [dependencies] -aztec = { path = "../../../aztec-nr/aztec" } +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_before_external/src/main.nr b/noir-projects/contract-snapshots/test_programs/compile_success/authorize_once_before_external/src/main.nr similarity index 100% rename from noir-projects/noir-contracts-comp-failures/contracts/authorize_once_before_external/src/main.nr rename to noir-projects/contract-snapshots/test_programs/compile_success/authorize_once_before_external/src/main.nr diff --git a/noir-projects/contract-snapshots/tests/snapshots.rs b/noir-projects/contract-snapshots/tests/snapshots.rs new file mode 100644 index 000000000000..f89ef8a41e71 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots.rs @@ -0,0 +1,107 @@ +use std::path::{Path, PathBuf}; +use std::process::Command; + +fn manifest_dir() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) +} + +/// `noir-projects/contract-snapshots/` -> repo root. +fn repo_root() -> PathBuf { + manifest_dir() + .parent() + .unwrap() + .parent() + .unwrap() + .to_path_buf() +} + +fn nargo_path() -> PathBuf { + let raw = std::env::var("NARGO") + .map(PathBuf::from) + .unwrap_or_else(|_| manifest_dir().join("../../noir/noir-repo/target/release/nargo")); + if raw.is_absolute() { + raw + } else { + manifest_dir().join(raw) + } +} + +fn nargo(dir: &Path) -> Command { + let mut cmd = Command::new(nargo_path()); + cmd.current_dir(dir); + cmd +} + +/// Scrubs nargo stderr before snapshotting: +/// +/// 1. Drops `Waiting for lock on git dependencies cache...` lines that nargo +/// emits when concurrent test invocations contend on its git-deps cache. +/// 2. Replaces the absolute repo prefix with `` so call-stack lines +/// pointing into `aztec-nr/aztec/src/macros/...` are stable across machines. +fn scrub_stderr(s: String) -> String { + let prefix = format!("{}/", repo_root().display()); + s.lines() + .filter(|l| !l.contains("Waiting for lock")) + .map(|l| l.replace(&prefix, "/")) + .collect::>() + .join("\n") +} + +/// Asserts `nargo compile` fails for `dir` and snapshots scrubbed stderr +fn run_compile_failure(name: &str, dir: PathBuf) { + let out = nargo(&dir) + .args(["compile", "--silence-warnings"]) + .output() + .unwrap_or_else(|e| panic!("could not invoke nargo at {:?}: {e}", nargo_path())); + assert!( + !out.status.success(), + "{name} unexpectedly compiled successfully" + ); + let stderr = scrub_stderr(String::from_utf8(out.stderr).expect("nargo stderr should be utf-8")); + insta::with_settings!({ snapshot_path => format!("snapshots/compile_failure/{name}") }, { + insta::assert_snapshot!("stderr", stderr); + }); +} + +/// Asserts `nargo compile` succeeds for `dir` and snapshots stderr +/// (typically empty, but captures any warnings nargo emits despite +/// `--silence-warnings`). Used for contracts that exist purely to track a +/// regression. If the test ever starts failing, the case must be moved to +/// `compile_failure/`. +fn run_compile_success(name: &str, dir: PathBuf) { + let out = nargo(&dir) + .args(["compile", "--silence-warnings"]) + .output() + .unwrap_or_else(|e| panic!("could not invoke nargo at {:?}: {e}", nargo_path())); + if !out.status.success() { + panic!( + "{name} unexpectedly failed to compile:\n--- stderr ---\n{}", + String::from_utf8_lossy(&out.stderr) + ); + } + let stderr = scrub_stderr(String::from_utf8(out.stderr).expect("nargo stderr should be utf-8")); + insta::with_settings!({ snapshot_path => format!("snapshots/compile_success/{name}") }, { + insta::assert_snapshot!("stderr", stderr); + }); +} + +/// Runs `nargo expand` in `dir` and snapshots stdout verbatim. The expanded +/// source has no path references, so no scrubbing is needed. +fn run_expand(name: &str, dir: PathBuf) { + let out = nargo(&dir) + .arg("expand") + .output() + .unwrap_or_else(|e| panic!("could not invoke nargo at {:?}: {e}", nargo_path())); + if !out.status.success() { + panic!( + "{name} expand failed:\n--- stderr ---\n{}", + String::from_utf8_lossy(&out.stderr) + ); + } + let stdout = String::from_utf8(out.stdout).expect("nargo stdout should be utf-8"); + insta::with_settings!({ snapshot_path => format!("snapshots/expand/{name}") }, { + insta::assert_snapshot!("expanded", stdout); + }); +} + +include!(concat!(env!("OUT_DIR"), "/tests.rs")); diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/allow_phase_change_on_non_external_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/allow_phase_change_on_non_external_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..4ba03004fab3 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/allow_phase_change_on_non_external_fn/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[allow_phase_change] attribute can only be applied to #[external("private")] functions - foo is not + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:11:5 + 2: allow_phase_change + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:166:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/allow_phase_change_on_utility_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/allow_phase_change_on_utility_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..8d21b0bec8f5 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/allow_phase_change_on_utility_fn/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[allow_phase_change] attribute cannot be applied to #[external("utility")] functions - foo + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:9:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:355:9 + 3: assert_valid_utility + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:505:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorization_selector_collision/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorization_selector_collision/snapshots__stderr.snap new file mode 100644 index 000000000000..de4879598429 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorization_selector_collision/snapshots__stderr.snap @@ -0,0 +1,67 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Trait crate::authwit::authorization_interface::AuthorizationInterface not found + ┌─ /noir-projects/aztec-nr/aztec/src/macros/authorization.nr:36:43 + │ +36 │ let authorization_interface = quote { crate::authwit::authorization_interface::AuthorizationInterface }; + │ --------------------------------------------------------------- + │ + ┌─ src/main.nr:24:5 + │ +24 │ #[authorization] + │ ---------------- While running this function attribute + │ + +error: Could not resolve 'authwit' in path + ┌─ /noir-projects/aztec-nr/aztec/src/macros/authorization.nr:37:54 + │ +37 │ let authorization_selector_type = quote { crate::authwit::AuthorizationSelector }; + │ ------- + │ + ┌─ src/main.nr:24:5 + │ +24 │ #[authorization] + │ ---------------- While running this function attribute + │ + +error: check_trait_impl_where_clause_matches_trait_where_clause: missing trait ID + ┌─ /noir-projects/aztec-nr/aztec/src/macros/authorization.nr:23:16 + │ +23 │ let name = s.name(); + │ -------- + │ + ┌─ src/main.nr:24:5 + │ +24 │ #[authorization] + │ ---------------- While running this function attribute + │ + +error: check_trait_impl_method_matches_declaration: missing trait impl + ┌─ /noir-projects/aztec-nr/aztec/src/macros/authorization.nr:42:16 + │ +42 │ fn get_authorization_selector(self) -> $authorization_selector_type { + │ -------------------------- + │ + ┌─ src/main.nr:24:5 + │ +24 │ #[authorization] + │ ---------------- While running this function attribute + │ + +error: Selector collision detected between authorizations 'EventCollision8370082250' and 'EventCollision' + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: AuthorizationSelectorCollision::#[authorization] + at src/main.nr:27:5 + 2: authorization + at /noir-projects/aztec-nr/aztec/src/macros/authorization.nr:65:5 + 3: register_authorization + at /noir-projects/aztec-nr/aztec/src/macros/authorization.nr:15:9 + +Aborting due to 5 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_from_wrong_type/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_from_wrong_type/snapshots__stderr.snap new file mode 100644 index 000000000000..d41d90c9c38b --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_from_wrong_type/snapshots__stderr.snap @@ -0,0 +1,27 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Argument from in function foo must be of type AztecAddress, but is of type Field + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:4:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21 + 3: process_functions + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:46:9 + 4: [T]::map + at std/vector.nr:67:33 + 5: process_functions + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:46:41 + 6: generate_public_external + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:97:9 + 7: create_authorize_once_check + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:72:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_from_param/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_from_param/snapshots__stderr.snap new file mode 100644 index 000000000000..83939084f7a4 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_from_param/snapshots__stderr.snap @@ -0,0 +1,27 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Function foo does not have a from parameter. Please specify which one to use in #[authorize_once("...", "authwit_nonce")] + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:4:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21 + 3: process_functions + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:46:9 + 4: [T]::map + at std/vector.nr:67:33 + 5: process_functions + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:46:41 + 6: generate_public_external + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:97:9 + 7: create_authorize_once_check + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:67:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_nonce_param/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_nonce_param/snapshots__stderr.snap new file mode 100644 index 000000000000..b0a19e34e8cc --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_missing_nonce_param/snapshots__stderr.snap @@ -0,0 +1,27 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Function foo does not have a authwit_nonce. Please specify which one to use in #[authorize_once("from", "...")] + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:4:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21 + 3: process_functions + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:46:9 + 4: [T]::map + at std/vector.nr:67:33 + 5: process_functions + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:46:41 + 6: generate_public_external + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:97:9 + 7: create_authorize_once_check + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:81:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_nonce_wrong_type/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_nonce_wrong_type/snapshots__stderr.snap new file mode 100644 index 000000000000..d2e4063624a2 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_nonce_wrong_type/snapshots__stderr.snap @@ -0,0 +1,27 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Argument authwit_nonce in function foo must be of type Field, but is of type u64 + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:4:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:97:21 + 3: process_functions + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:46:9 + 4: [T]::map + at std/vector.nr:67:33 + 5: process_functions + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/mod.nr:46:41 + 6: generate_public_external + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/public.nr:97:9 + 7: create_authorize_once_check + at /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/helpers.nr:86:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_on_non_external_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_on_non_external_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..856129ff8810 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_on_non_external_fn/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[authorize_once] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:14:5 + 2: authorize_once + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:320:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_on_utility_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_on_utility_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..8272342aa1d6 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorize_once_on_utility_fn/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[authorize_once] attribute cannot be applied to #[external("utility")] functions - foo + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:12:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:355:9 + 3: assert_valid_utility + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:470:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/aztec_macro_too_many_args/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/aztec_macro_too_many_args/snapshots__stderr.snap new file mode 100644 index 000000000000..e7043b21b324 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/aztec_macro_too_many_args/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: #[aztec] expects 0 or 1 arguments, got 2 + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:4:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:89:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/bob_token/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/bob_token/snapshots__stderr.snap new file mode 100644 index 000000000000..48141769333e --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/bob_token/snapshots__stderr.snap @@ -0,0 +1,304 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[internal] attribute cannot be applied to external functions - transfer_public is marked as both #[external] and #[internal("public")] + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:53:5 + 2: internal + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:375:9 + +error: A function marked as #[external("private")] or #[internal("private")] must not have public Noir visibility - transfer_private's visibility is 'pub' + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:85:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:349:9 + 3: assert_valid_private + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:398:9 + +error: The #[view] attribute can only be applied to #[external("private")] or #[external("public")] functions - _assert_is_owner is neither + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:107:5 + 2: view + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:283:9 + +error: #[external("private")] or #[internal("private")] functions must not be unconstrained - mint_private is + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:113:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:349:9 + 3: assert_valid_private + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:405:9 + +error: Function _assert_is_owner must be marked as either #[external(...)], #[internal(...)], or #[test] + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:18:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:93:5 + 3: check_each_fn_macroified + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:295:13 + +error: cannot find `self` in this scope + ┌─ src/main.nr:41:9 + │ +41 │ self.storage.owner.write(self.msg_sender()); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:46:19 + │ +46 │ assert_eq(self.msg_sender(), self.storage.owner.read(), "Only owner can mint"); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:46:38 + │ +46 │ assert_eq(self.msg_sender(), self.storage.owner.read(), "Only owner can mint"); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:47:31 + │ +47 │ let current_balance = self.storage.public_balances.at(employee).read(); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:48:9 + │ +48 │ self.storage.public_balances.at(employee).write(current_balance + amount); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:55:22 + │ +55 │ let sender = self.msg_sender(); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:56:30 + │ +56 │ let sender_balance = self.storage.public_balances.at(sender).read(); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:57:9 + │ +57 │ self.storage.public_balances.at(sender).write(sender_balance - amount); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:58:33 + │ +58 │ let recipient_balance = self.storage.public_balances.at(to).read(); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:59:9 + │ +59 │ self.storage.public_balances.at(to).write(recipient_balance + amount); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:64:19 + │ +64 │ assert_eq(self.msg_sender(), self.storage.owner.read(), "Only current owner"); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:64:38 + │ +64 │ assert_eq(self.msg_sender(), self.storage.owner.read(), "Only current owner"); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:65:9 + │ +65 │ self.storage.owner.write(new_owner); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:70:22 + │ +70 │ let sender = self.msg_sender(); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:71:9 + │ +71 │ self.enqueue_self._deduct_public_balance(sender, amount); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:72:9 + │ +72 │ self.storage.private_balances.at(sender).add(amount).deliver( + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:80:23 + │ +80 │ let balance = self.storage.public_balances.at(owner).read(); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:81:9 + │ +81 │ self.storage.public_balances.at(owner).write(balance - amount); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:87:22 + │ +87 │ let sender = self.msg_sender(); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:88:9 + │ +88 │ self.storage.private_balances.at(sender).sub(amount).deliver( + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:91:9 + │ +91 │ self.storage.private_balances.at(to).add(amount).deliver( + │ ---- not found in this scope + │ + +error: missing pub keyword on return type of function private_balance_of + ┌─ src/main.nr:97:65 + │ +97 │ unconstrained fn private_balance_of(owner: AztecAddress) -> u128 { + │ ---- missing pub on return type + │ + = The `pub` keyword is mandatory for the entry-point function return type because the verifier cannot retrieve private witness and thus the function will not be able to return a 'priv' value + +error: cannot find `self` in this scope + ┌─ src/main.nr:98:9 + │ +98 │ self.storage.private_balances.at(owner).balance_of() + │ ---- not found in this scope + │ + +error: missing pub keyword on return type of function public_balance_of + ┌─ src/main.nr:102:64 + │ +102 │ unconstrained fn public_balance_of(owner: AztecAddress) -> u128 { + │ ---- missing pub on return type + │ + = The `pub` keyword is mandatory for the entry-point function return type because the verifier cannot retrieve private witness and thus the function will not be able to return a 'priv' value + +error: cannot find `self` in this scope + ┌─ src/main.nr:103:9 + │ +103 │ self.storage.public_balances.at(owner).read() + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:109:28 + │ +109 │ assert_eq(address, self.storage.owner.read(), "Only owner"); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:115:9 + │ +115 │ self.enqueue_self._assert_is_owner(self.msg_sender()); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:116:9 + │ +116 │ self.storage.private_balances.at(employee).add(amount).deliver( + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:123:22 + │ +123 │ let sender = self.msg_sender(); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:124:9 + │ +124 │ self.storage.private_balances.at(sender).sub(amount).deliver( + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:127:9 + │ +127 │ self.enqueue_self._credit_public_balance(sender, amount); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:133:23 + │ +133 │ let balance = self.storage.public_balances.at(owner).read(); + │ ---- not found in this scope + │ + +error: cannot find `self` in this scope + ┌─ src/main.nr:134:9 + │ +134 │ self.storage.public_balances.at(owner).write(balance + amount); + │ ---- not found in this scope + │ + +Aborting due to 38 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/duplicate_storage/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/duplicate_storage/snapshots__stderr.snap new file mode 100644 index 000000000000..d6afbfc40656 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/duplicate_storage/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[storage] macro can only be applied to a struct with name 'Storage', got 'Storage2' instead. + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: DuplicateStorage::#[storage] + at src/main.nr:10:5 + 2: storage + at /noir-projects/aztec-nr/aztec/src/macros/storage.nr:23:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/event_selector_collision/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/event_selector_collision/snapshots__stderr.snap new file mode 100644 index 000000000000..1d7d038f0b81 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/event_selector_collision/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Event selector collision detected between events 'EventCollision8370082250' and 'EventCollision' + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: EventSelectorCollision::#[event] + at src/main.nr:10:5 + 2: event + at /noir-projects/aztec-nr/aztec/src/macros/events.nr:56:5 + 3: register_event_selector + at /noir-projects/aztec-nr/aztec/src/macros/events.nr:38:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/external_and_internal_together/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/external_and_internal_together/snapshots__stderr.snap new file mode 100644 index 000000000000..4e66449009a9 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/external_and_internal_together/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[internal] attribute cannot be applied to external functions - foo is marked as both #[external] and #[internal("private")] + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:9:5 + 2: internal + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:375:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/incorrect_storage_struct_name/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/incorrect_storage_struct_name/snapshots__stderr.snap new file mode 100644 index 000000000000..03ab1c2355a0 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/incorrect_storage_struct_name/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[storage] macro can only be applied to a struct with name 'Storage', got 'Storage2' instead. + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: IncorrectStorageStructName::#[storage] + at src/main.nr:8:5 + 2: storage + at /noir-projects/aztec-nr/aztec/src/macros/storage.nr:23:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/initializer_on_non_external_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/initializer_on_non_external_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..eadf7d5ff548 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/initializer_on_non_external_fn/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[initializer] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:11:5 + 2: initializer + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:100:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/initializer_on_utility_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/initializer_on_utility_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..22ddb085c680 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/initializer_on_utility_fn/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[initializer] attribute cannot be applied to #[external("utility")] functions - foo + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:9:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:355:9 + 3: assert_valid_utility + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:491:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_event/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_event/snapshots__stderr.snap new file mode 100644 index 000000000000..83b77125cd5c --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_event/snapshots__stderr.snap @@ -0,0 +1,24 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: event's serialized length exceeds the maximum allowed for private events + ┌─ /noir-projects/aztec-nr/aztec/src/messages/logs/event.nr:30:5 + │ +30 │ ╭ std::static_assert( +31 │ │ ::N <= MAX_EVENT_SERIALIZED_LEN, +32 │ │ "event's serialized length exceeds the maximum allowed for private events", +33 │ │ ); + │ ╰─────' + │ + = Call stack: + 1: remove_constraints + at /noir-projects/aztec-nr/aztec/src/utils/remove_constraints.nr:4:5 + 2: do_private_message_delivery + at /noir-projects/aztec-nr/aztec/src/messages/message_delivery.nr:222:28 + 3: EventMessage::deliver_to + at /noir-projects/aztec-nr/aztec/src/event/event_message.nr:57:16 + 4: encode_private_event_message + at /noir-projects/aztec-nr/aztec/src/messages/logs/event.nr:30:5 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_external_function_type/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_external_function_type/snapshots__stderr.snap new file mode 100644 index 000000000000..35d786263891 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_external_function_type/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Function 'invalid_external_function_type' is marked as #[external("invalid")], but 'invalid' is not a valid external function type. External functions must be one of 'private', 'public' or 'utility' + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:7:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:359:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_internal_function_type/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_internal_function_type/snapshots__stderr.snap new file mode 100644 index 000000000000..a5d6a01dfe97 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_internal_function_type/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Function 'foo' is marked as #[internal("utility")], but 'utility' is not a valid internal function type. Internal functions must be one of 'private', 'public' + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:8:5 + 2: internal + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:388:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_note/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_note/snapshots__stderr.snap new file mode 100644 index 000000000000..278bb9319a40 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/invalid_note/snapshots__stderr.snap @@ -0,0 +1,35 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: InvalidNote has a packed length of 9 fields, which exceeds the maximum allowed length of 8 fields. See https://docs.aztec.network/errors/4 + ┌─ /noir-projects/aztec-nr/aztec/src/macros/notes.nr:52:17 + │ +52 │ std::static_assert(note_packed_len <= $max_note_packed_len, f"{note_type_name} has a packed length of {note_packed_len} fields, which exceeds the maximum allowed length of {max_note_packed_len} fields. See https://docs.aztec.network/errors/4"); + │ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + │ + = Call stack: + 1: generate_sync_state + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:240:13 + 2: do_sync_state + at /noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr:130:5 + 3: EphemeralArray::for_each + at /noir-projects/aztec-nr/aztec/src/ephemeral/mod.nr:99:13 + 4: do_sync_state + at /noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr:139:13 + 5: process_message_ciphertext + at /noir-projects/aztec-nr/aztec/src/messages/discovery/process_message.nr:41:9 + 6: process_message_plaintext + at /noir-projects/aztec-nr/aztec/src/messages/discovery/process_message.nr:76:13 + 7: process_private_note_msg + at /noir-projects/aztec-nr/aztec/src/messages/discovery/private_notes.nr:27:9 + 8: attempt_note_discovery + at /noir-projects/aztec-nr/aztec/src/messages/discovery/private_notes.nr:64:28 + 9: attempt_note_nonce_discovery + at /noir-projects/aztec-nr/aztec/src/messages/discovery/nonce_discovery.nr:46:27 + 10: generate_contract_library_method_compute_note_hash + at /noir-projects/aztec-nr/aztec/src/macros/aztec/compute_note_hash_and_nullifier.nr:107:53 + 11: generate_note_type_impl + at /noir-projects/aztec-nr/aztec/src/macros/notes.nr:52:17 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/marked_private_unconstrained/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/marked_private_unconstrained/snapshots__stderr.snap new file mode 100644 index 000000000000..637b06f4e3f9 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/marked_private_unconstrained/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: #[external("private")] or #[internal("private")] functions must not be unconstrained - unconstrained_private_function is + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:11:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:349:9 + 3: assert_valid_private + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:405:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/marked_public_unconstrained/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/marked_public_unconstrained/snapshots__stderr.snap new file mode 100644 index 000000000000..f1f2b5c72bd8 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/marked_public_unconstrained/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: #[external("public")] or #[internal("public")] functions must not be unconstrained - unconstrained_public_function is + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:11:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:352:9 + 3: assert_valid_public + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:422:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_on_non_external_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_on_non_external_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..d776325d7ef9 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_on_non_external_fn/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[noinitcheck] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:11:5 + 2: noinitcheck + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:128:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_on_utility_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_on_utility_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..c04d0958d0af --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_on_utility_fn/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[noinitcheck] attribute cannot be applied to #[external("utility")] functions - foo + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:16:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:355:9 + 3: assert_valid_utility + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:498:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_without_initializer/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_without_initializer/snapshots__stderr.snap new file mode 100644 index 000000000000..431529c017a6 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/noinitcheck_without_initializer/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[noinitcheck] attribute is unnecessary for contracts with no #[initializer] functions + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:8:5 + 2: noinitcheck + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:134:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/non_deserializable/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/non_deserializable/snapshots__stderr.snap new file mode 100644 index 000000000000..df59b3f78c18 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/non_deserializable/snapshots__stderr.snap @@ -0,0 +1,77 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Contract function 'bad_private_return' returns a value of type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:169:13 + │ +169 │ return_type.implements(deserialize_constraint), + │ ---------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:15:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:345:5 + +error: Parameter '_p' of contract function 'bad_private_param' has type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:188:13 + │ +188 │ param_type.implements(deserialize_constraint), + │ --------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:20:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:346:5 + +error: Contract function 'bad_public_return' returns a value of type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:169:13 + │ +169 │ return_type.implements(deserialize_constraint), + │ ---------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:23:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:345:5 + +error: Parameter '_p' of contract function 'bad_public_param' has type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:188:13 + │ +188 │ param_type.implements(deserialize_constraint), + │ --------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:28:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:346:5 + +error: Contract function 'bad_utility_return' returns a value of type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:169:13 + │ +169 │ return_type.implements(deserialize_constraint), + │ ---------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:31:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:345:5 + +error: Parameter '_p' of contract function 'bad_utility_param' has type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:188:13 + │ +188 │ param_type.implements(deserialize_constraint), + │ --------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:36:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:346:5 + +Aborting due to 6 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/non_serializable/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/non_serializable/snapshots__stderr.snap new file mode 100644 index 000000000000..62ec3c61e351 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/non_serializable/snapshots__stderr.snap @@ -0,0 +1,77 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Contract function 'bad_private_return' returns a value of type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:164:13 + │ +164 │ return_type.implements(serialize_constraint), + │ -------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:15:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:345:5 + +error: Parameter '_p' of contract function 'bad_private_param' has type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:183:13 + │ +183 │ param_type.implements(serialize_constraint), + │ ------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:20:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:346:5 + +error: Contract function 'bad_public_return' returns a value of type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:164:13 + │ +164 │ return_type.implements(serialize_constraint), + │ -------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:23:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:345:5 + +error: Parameter '_p' of contract function 'bad_public_param' has type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:183:13 + │ +183 │ param_type.implements(serialize_constraint), + │ ------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:28:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:346:5 + +error: Contract function 'bad_utility_return' returns a value of type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:164:13 + │ +164 │ return_type.implements(serialize_constraint), + │ -------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:31:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:345:5 + +error: Parameter '_p' of contract function 'bad_utility_param' has type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. + ┌─ /noir-projects/aztec-nr/aztec/src/macros/utils.nr:183:13 + │ +183 │ param_type.implements(serialize_constraint), + │ ------------------------------------------- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:36:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:346:5 + +Aborting due to 6 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/only_self_on_non_external_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/only_self_on_non_external_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..58b9830a8cea --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/only_self_on_non_external_fn/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[only_self] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:11:5 + 2: only_self + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:244:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/only_self_on_utility_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/only_self_on_utility_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..aacfd01f46e0 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/only_self_on_utility_fn/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[only_self] attribute cannot be applied to #[external("utility")] functions - foo + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:9:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:355:9 + 3: assert_valid_utility + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:477:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_private_external_fn_call/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_private_external_fn_call/snapshots__stderr.snap new file mode 100644 index 000000000000..1eee416fbe05 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_private_external_fn_call/snapshots__stderr.snap @@ -0,0 +1,15 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Direct invocation of private functions is not supported. You attempted to call arbitrary_external_function. See https://docs.aztec.network/errors/6 + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +12 │ arbitrary_external_function(); + │ --------------------------- `arbitrary_external_function` has been deprecated + │ + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_private_internal_fn_call/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_private_internal_fn_call/snapshots__stderr.snap new file mode 100644 index 000000000000..829db1680a75 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_private_internal_fn_call/snapshots__stderr.snap @@ -0,0 +1,15 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Direct invocation of private internal functions is not supported. You attempted to call arbitrary_private_function. See https://docs.aztec.network/errors/6 + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +12 │ arbitrary_private_function(); + │ -------------------------- `arbitrary_private_function` has been deprecated + │ + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_public_external_fn_call/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_public_external_fn_call/snapshots__stderr.snap new file mode 100644 index 000000000000..51cef068790f --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_public_external_fn_call/snapshots__stderr.snap @@ -0,0 +1,15 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Direct invocation of public functions is not supported. You attempted to call arbitrary_external_function. See https://docs.aztec.network/errors/6 + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +12 │ arbitrary_external_function(); + │ --------------------------- `arbitrary_external_function` has been deprecated + │ + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_public_internal_fn_call/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_public_internal_fn_call/snapshots__stderr.snap new file mode 100644 index 000000000000..5709ee3cb74b --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_public_internal_fn_call/snapshots__stderr.snap @@ -0,0 +1,15 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Direct invocation of public internal functions is not supported. You attempted to call arbitrary_public_function. See https://docs.aztec.network/errors/6 + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +12 │ arbitrary_public_function(); + │ ------------------------- `arbitrary_public_function` has been deprecated + │ + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_utility_external_fn_call/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_utility_external_fn_call/snapshots__stderr.snap new file mode 100644 index 000000000000..252accac8f0f --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_direct_utility_external_fn_call/snapshots__stderr.snap @@ -0,0 +1,15 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Direct invocation of utility functions is not supported. You attempted to call arbitrary_external_function. See https://docs.aztec.network/errors/6 + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +12 │ arbitrary_external_function(); + │ --------------------------- `arbitrary_external_function` has been deprecated + │ + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_private_call/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_private_call/snapshots__stderr.snap new file mode 100644 index 000000000000..de1c268866c5 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_private_call/snapshots__stderr.snap @@ -0,0 +1,25 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Could not resolve 'ZERO' in path + ┌─ src/main.nr:3:1 + │ +3 │ #[aztec] + │ -------- While running this function attribute + · +9 │ PanicOnIncorrectlyPerformedPrivateCall::at(AztecAddress::ZERO).arbitrary_external_function(); + │ ---- + │ + +error: Your private call needs to be passed into the `self.call(...)` method to be executed (e.g. `self.call(MyContract::at(address).my_private_function(...args))` + ┌─ src/main.nr:3:1 + │ +3 │ #[aztec] + │ -------- While running this function attribute + · +9 │ PanicOnIncorrectlyPerformedPrivateCall::at(AztecAddress::ZERO).arbitrary_external_function(); + │ -------------------------------------------------------------------------------------------- Unused expression result of type PrivateCall<27, 0, ()> which must be used + │ + +Aborting due to 2 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_private_static_call/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_private_static_call/snapshots__stderr.snap new file mode 100644 index 000000000000..7bd6bfee98f3 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_private_static_call/snapshots__stderr.snap @@ -0,0 +1,26 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Could not resolve 'ZERO' in path + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +18 │ PanicOnIncorrectlyPerformedPrivateStaticCall::at(AztecAddress::ZERO) + │ ---- + │ + +error: Your private static call needs to be passed into the `self.view(...)` method to be executed (e.g. `self.view(MyContract::at(address).my_private_static_function(...args))` + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +18 │ ╭ PanicOnIncorrectlyPerformedPrivateStaticCall::at(AztecAddress::ZERO) +19 │ │ .arbitrary_view_function(); + │ ╰──────────────────────────────────────' Unused expression result of type PrivateStaticCall<23, 0, Field> which must be used + │ + +Aborting due to 2 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_public_call/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_public_call/snapshots__stderr.snap new file mode 100644 index 000000000000..3361a44915c4 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_public_call/snapshots__stderr.snap @@ -0,0 +1,25 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Could not resolve 'ZERO' in path + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +12 │ PanicOnIncorrectlyPerformedPublicCall::at(AztecAddress::ZERO).arbitrary_public_function(); + │ ---- + │ + +error: Your public call needs to be passed into the `self.call(...)`, `self.enqueue(...)` or `self.enqueue_incognito(...)` method to be executed (e.g. `self.call(MyContract::at(address).my_public_function(...args))` + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +12 │ PanicOnIncorrectlyPerformedPublicCall::at(AztecAddress::ZERO).arbitrary_public_function(); + │ ----------------------------------------------------------------------------------------- Unused expression result of type PublicCall<25, 0, ()> which must be used + │ + +Aborting due to 2 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_public_static_call/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_public_static_call/snapshots__stderr.snap new file mode 100644 index 000000000000..b426ebb70c1c --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_incorrectly_performed_public_static_call/snapshots__stderr.snap @@ -0,0 +1,26 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Could not resolve 'ZERO' in path + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +18 │ PanicOnIncorrectlyPerformedPublicStaticCall::at(AztecAddress::ZERO) + │ ---- + │ + +error: Your public static call needs to be passed into the `self.view(...)`, `self.enqueue_view(...)` or `self.enqueue_view_incognito(...)` method to be executed (e.g. `self.view(MyContract::at(address).my_public_static_function(...args))` + ┌─ src/main.nr:3:1 + │ + 3 │ #[aztec] + │ -------- While running this function attribute + · +18 │ ╭ PanicOnIncorrectlyPerformedPublicStaticCall::at(AztecAddress::ZERO) +19 │ │ .arbitrary_public_static_function(); + │ ╰───────────────────────────────────────────────' Unused expression result of type PublicStaticCall<32, 0, Field> which must be used + │ + +Aborting due to 2 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_non_state_var_in_storage/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_non_state_var_in_storage/snapshots__stderr.snap new file mode 100644 index 000000000000..3a141f8feda1 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_non_state_var_in_storage/snapshots__stderr.snap @@ -0,0 +1,41 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Type NonStateVar does not implement StateVariable and hence cannot be placed in Storage struct. + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: PanicOnNonStateVarInStorage::#[storage] + at src/main.nr:12:5 + 2: storage + at /noir-projects/aztec-nr/aztec/src/macros/storage.nr:54:13 + +error: Could not resolve 'init' in path + ┌─ /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/private.nr:35:36 + │ +35 │ let storage = Storage::init(&mut context); + │ ---- + │ + ┌─ src/main.nr:4:1 + │ + 4 │ #[aztec] + │ -------- While running this function attribute + │ + +error: Type annotation needed + ┌─ /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/private.nr:61:56 + │ +61 │ aztec::contract_self::ContractSelfPrivate::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + │ --- Could not determine the type of the generic argument `Storage` declared on the struct `ContractSelfPrivate` + │ + ┌─ src/main.nr:4:1 + │ + 4 │ #[aztec] + │ -------- While running this function attribute + │ + +Aborting due to 3 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_owned_state_var_in_storage/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_owned_state_var_in_storage/snapshots__stderr.snap new file mode 100644 index 000000000000..f7c7c14166a5 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/panic_on_owned_state_var_in_storage/snapshots__stderr.snap @@ -0,0 +1,41 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Type PrivateImmutable implements OwnedStateVariable and hence cannot be placed in Storage struct without being wrapped in Owned. Wrap the type in Owned<..., Context>. + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: PanicOnOwnedStateVarInStorage::#[storage] + at src/main.nr:8:5 + 2: storage + at /noir-projects/aztec-nr/aztec/src/macros/storage.nr:49:17 + +error: Could not resolve 'init' in path + ┌─ /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/private.nr:35:36 + │ +35 │ let storage = Storage::init(&mut context); + │ ---- + │ + ┌─ src/main.nr:4:1 + │ + 4 │ #[aztec] + │ -------- While running this function attribute + │ + +error: Type annotation needed + ┌─ /noir-projects/aztec-nr/aztec/src/macros/internals_functions_generation/external/private.nr:61:56 + │ +61 │ aztec::contract_self::ContractSelfPrivate::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + │ --- Could not determine the type of the generic argument `Storage` declared on the struct `ContractSelfPrivate` + │ + ┌─ src/main.nr:4:1 + │ + 4 │ #[aztec] + │ -------- While running this function attribute + │ + +Aborting due to 3 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_private_external_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_private_external_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..a0e08ce30faf --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_private_external_fn/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: A function marked as #[external("private")] or #[internal("private")] must not have public Noir visibility - foo's visibility is 'pub' + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:8:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:349:9 + 3: assert_valid_private + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:398:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_public_external_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_public_external_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..7fc4c600b3bd --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_public_external_fn/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: A function marked as #[external("public")] or #[internal("public")] must not have public Noir visibility - foo's visibility is 'pub' + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:8:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:352:9 + 3: assert_valid_public + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:415:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_utility_external_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_utility_external_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..676a28b3f0f7 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/pub_utility_external_fn/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: A function marked as #[external("utility")] must not have public Noir visibility - foo's visibility is 'pub' + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:8:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:355:9 + 3: assert_valid_utility + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:451:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_allow_phase_change/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_allow_phase_change/snapshots__stderr.snap new file mode 100644 index 000000000000..8466367d1039 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_allow_phase_change/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[allow_phase_change] attribute cannot be applied to #[external("public")] functions - foo + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:9:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:352:9 + 3: assert_valid_public + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:429:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_function_selector_collision/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_function_selector_collision/snapshots__stderr.snap new file mode 100644 index 000000000000..5e1f5985c358 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/public_function_selector_collision/snapshots__stderr.snap @@ -0,0 +1,23 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Public function selector collision detected between functions 'fn_selector_collision_1442740381' and 'fn_selector_collision' + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:4:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:145:27 + 3: generate_public_dispatch + at /noir-projects/aztec-nr/aztec/src/macros/dispatch.nr:20:19 + 4: [T]::map + at std/vector.nr:67:33 + 5: generate_public_dispatch + at /noir-projects/aztec-nr/aztec/src/macros/dispatch.nr:32:13 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/reserved_emit_public_init_nullifier/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/reserved_emit_public_init_nullifier/snapshots__stderr.snap new file mode 100644 index 000000000000..7ddaf938517a --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/reserved_emit_public_init_nullifier/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Function name '__emit_public_init_nullifier' is reserved for internal use + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:9:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:352:9 + 3: assert_valid_public + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:435:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/reserved_public_dispatch/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/reserved_public_dispatch/snapshots__stderr.snap new file mode 100644 index 000000000000..523b8cf5c4a4 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/reserved_public_dispatch/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Function name 'public_dispatch' is reserved for internal use + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:9:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:352:9 + 3: assert_valid_public + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:441:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/unmacroified_function_in_contract/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/unmacroified_function_in_contract/snapshots__stderr.snap new file mode 100644 index 000000000000..d96287947c14 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/unmacroified_function_in_contract/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: Function foo must be marked as either #[external(...)], #[internal(...)], or #[test] + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:4:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:93:5 + 3: check_each_fn_macroified + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:295:13 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_offchain_receive/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_offchain_receive/snapshots__stderr.snap new file mode 100644 index 000000000000..75565319fd2a --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/user_defined_offchain_receive/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: User-defined 'offchain_receive' is not allowed. The function is auto-injected by the #[aztec] macro. See https://docs.aztec.network/errors/7 + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: #[aztec] + at src/main.nr:4:1 + 2: aztec + at /noir-projects/aztec-nr/aztec/src/macros/aztec.nr:138:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/utility_not_unconstrained/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/utility_not_unconstrained/snapshots__stderr.snap new file mode 100644 index 000000000000..2d724bb3ad5d --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/utility_not_unconstrained/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: #[external("utility")] must be unconstrained - constrained_utility_function isn't + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:8:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:355:9 + 3: assert_valid_utility + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:458:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/view_on_non_external_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/view_on_non_external_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..e034afbf1b3b --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/view_on_non_external_fn/snapshots__stderr.snap @@ -0,0 +1,17 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[view] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:11:5 + 2: view + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:283:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/view_on_utility_fn/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/view_on_utility_fn/snapshots__stderr.snap new file mode 100644 index 000000000000..f2ae6c5e785b --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/view_on_utility_fn/snapshots__stderr.snap @@ -0,0 +1,19 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- +error: The #[view] attribute cannot be applied to #[external("utility")] functions - foo + ┌─ std/panic.nr:8:12 + │ +8 │ assert(false, message); + │ ----- Assertion failed + │ + = Call stack: + 1: ? + at src/main.nr:9:5 + 2: external + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:355:9 + 3: assert_valid_utility + at /noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr:484:9 + +Aborting due to 1 previous error diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_success/authorize_once_before_external/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_success/authorize_once_before_external/snapshots__stderr.snap new file mode 100644 index 000000000000..f0834d0b50ea --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_success/authorize_once_before_external/snapshots__stderr.snap @@ -0,0 +1,5 @@ +--- +source: tests/snapshots.rs +expression: stderr +--- + diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/amm_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/amm_contract/snapshots__expanded.snap new file mode 100644 index 000000000000..1253e48c4746 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/amm_contract/snapshots__expanded.snap @@ -0,0 +1,2920 @@ +--- +source: tests/snapshots.rs +expression: stdout +--- +use aztec::macros::aztec; +use aztec::macros::aztec; + +mod config { + use std::meta::derive; + use aztec::protocol::address::AztecAddress; + use aztec::protocol::traits::Deserialize; + use aztec::protocol::traits::Packable; + use aztec::protocol::traits::Serialize; + + /// We store the tokens of the pool in a struct such that to load it from PublicImmutable asserts only a single + /// merkle proof. + pub struct Config { + pub token0: AztecAddress, + pub token1: AztecAddress, + pub liquidity_token: AztecAddress, + } + + impl Eq for Config { + fn eq(_self: Self, _other: Self) -> bool { + ((_self.token0 == _other.token0) & (_self.token1 == _other.token1)) & (_self.liquidity_token == _other.liquidity_token) + } + } + + impl Packable for Config { + let N: u32 = 3; + + #[inline_always] + fn pack(self) -> [Field; 3] { + let mut result: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let packed_member: [Field; 1] = self.token0.pack(); + let packed_member_len: u32 = ::N; + for i in 0_u32..packed_member_len { + { + let i_0: u32 = i + offset; + result[i_0] = packed_member[i]; + } + }; + offset = offset + packed_member_len; + let packed_member: [Field; 1] = self.token1.pack(); + let packed_member_len: u32 = ::N; + for i in 0_u32..packed_member_len { + { + let i_1: u32 = i + offset; + result[i_1] = packed_member[i]; + } + }; + offset = offset + packed_member_len; + let packed_member: [Field; 1] = self.liquidity_token.pack(); + let packed_member_len: u32 = ::N; + for i in 0_u32..packed_member_len { + { + let i_2: u32 = i + offset; + result[i_2] = packed_member[i]; + } + }; + offset = offset + packed_member_len; + result + } + + #[inline_always] + fn unpack(packed: [Field; 3]) -> Self { + let mut offset: u32 = 0_u32; + let mut member_fields: [Field; 1] = [0_Field; 1]; + for i in 0_u32..::N { + member_fields[i] = packed[i + offset]; + }; + let token0: AztecAddress = ::unpack(member_fields); + offset = offset + ::N; + let mut member_fields: [Field; 1] = [0_Field; 1]; + for i in 0_u32..::N { + member_fields[i] = packed[i + offset]; + }; + let token1: AztecAddress = ::unpack(member_fields); + offset = offset + ::N; + let mut member_fields: [Field; 1] = [0_Field; 1]; + for i in 0_u32..::N { + member_fields[i] = packed[i + offset]; + }; + let liquidity_token: AztecAddress = ::unpack(member_fields); + offset = offset + ::N; + Self { token0: token0, token1: token1, liquidity_token: liquidity_token} + } + } + + impl Serialize for Config { + let N: u32 = 3; + + fn serialize(self) -> [Field; 3] { + let mut writer: aztec::protocol::utils::writer::Writer<3> = aztec::protocol::utils::writer::Writer::<3>::new(); + self.stream_serialize(&mut writer); + writer.finish() + } + + #[inline_always] + fn stream_serialize(self, writer: &mut aztec::protocol::utils::writer::Writer) { + self.token0.stream_serialize(writer); + self.token1.stream_serialize(writer); + self.liquidity_token.stream_serialize(writer); + } + } + + impl Deserialize for Config { + let N: u32 = 3; + + fn deserialize(fields: [Field; 3]) -> Self { + let mut reader: aztec::protocol::utils::reader::Reader<3> = aztec::protocol::utils::reader::Reader::<3>::new(fields); + let result: Self = Self::stream_deserialize(&mut reader); + reader.finish(); + result + } + + #[inline_always] + fn stream_deserialize(reader: &mut aztec::protocol::utils::reader::Reader) -> Self { + let token0: AztecAddress = ::stream_deserialize(reader); + let token1: AztecAddress = ::stream_deserialize(reader); + let liquidity_token: AztecAddress = ::stream_deserialize(reader); + Self { token0: token0, token1: token1, liquidity_token: liquidity_token} + } + } +} + +mod lib { + /// Given an input amount of an asset and pair balances, returns the maximum output amount of the other asset. + pub fn get_amount_out(amount_in: u128, balance_in: u128, balance_out: u128) -> u128 { + assert(amount_in > (0_Field as u128), "INSUFFICIENT_INPUT_AMOUNT"); + assert((balance_in > (0_Field as u128)) & (balance_out > (0_Field as u128)), "INSUFFICIENT_LIQUIDITY"); + let amount_in_with_fee: u128 = amount_in * (997_Field as u128); + let numerator: u128 = amount_in_with_fee * balance_out; + let denominator: u128 = (balance_in * (1000_Field as u128)) + amount_in_with_fee; + numerator / denominator + } + + /// Given an output amount of an asset and pair balances, returns a required input amount of the other asset. + pub fn get_amount_in(amount_out: u128, balance_in: u128, balance_out: u128) -> u128 { + assert(amount_out > (0_Field as u128), "INSUFFICIENT_OUTPUT_AMOUNT"); + assert((balance_in > (0_Field as u128)) & (balance_out > (0_Field as u128)), "INSUFFICIENT_LIQUIDITY"); + let numerator: u128 = (balance_in * amount_out) * (1000_Field as u128); + let denominator: u128 = (balance_out - amount_out) * (997_Field as u128); + (numerator / denominator) + (1_Field as u128) + } + + /// Given the desired amounts and balances of token0 and token1 returns the optimal amount of token0 and token1 to be + /// added to the pool. + pub fn get_amounts_to_add(amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128, balance0: u128, balance1: u128) -> (u128, u128) { + if (balance0 == (0_Field as u128)) | (balance1 == (0_Field as u128)) { + (amount0_max, amount1_max) + } else { + let amount1_equivalent: u128 = get_equivalent_amount(amount0_max, balance0, balance1); + if amount1_equivalent <= amount1_max { + assert(amount1_equivalent >= amount1_min, "AMOUNT_1_BELOW_MINIMUM"); + (amount0_max, amount1_equivalent) + } else { + let amount0_equivalent: u128 = get_equivalent_amount(amount1_max, balance1, balance0); + assert(amount0_equivalent <= amount0_max); + assert(amount0_equivalent >= amount0_min, "AMOUNT_0_BELOW_MINIMUM"); + (amount0_equivalent, amount1_max) + } + } + } + + /// Returns the amount of tokens to return to a liquidity provider when they remove liquidity from the pool. + pub fn get_amounts_on_remove(to_burn: u128, total_supply: u128, balance0: u128, balance1: u128) -> (u128, u128) { + ((to_burn * balance0) / total_supply, (to_burn * balance1) / total_supply) + } + + /// Given some amount of an asset and pair balances, returns an equivalent amount of the other asset. Tokens should be + /// added and removed from the Pool respecting this ratio. + fn get_equivalent_amount(amount0: u128, balance0: u128, balance1: u128) -> u128 { + assert((balance0 > (0_Field as u128)) & (balance1 > (0_Field as u128)), "INSUFFICIENT_LIQUIDITY"); + (amount0 * balance1) / balance0 + } +} + +/// ## Overview +/// This contract demonstrates how to implement an **Automated Market Maker (AMM)** that maintains **public state** +/// while still achieving **identity privacy**. However, it does **not provide function privacy**: +/// - Anyone can observe **what actions** were performed. +/// - All amounts involved are visible, but **who** performed the action remains private. +/// +/// Unlike most Ethereum AMMs, the AMM contract is not itself the token that tracks participation of liquidity +/// providers, mostly due to Noir lacking inheritance as a feature. Instead, the AMM is expected to have mint and burn +/// permission over an external token contract. +/// +/// **Note:** +/// This is purely a demonstration. The **Aztec team** does not consider this the optimal design for building a DEX. +/// +/// ## Reentrancy Guard Considerations +/// +/// ### 1. Private Functions: +/// Reentrancy protection is typically necessary if entering an intermediate state that is only valid when +/// the action completes uninterrupted. This follows the **Checks-Effects-Interactions** pattern. +/// +/// - In this contract, **private functions** do not introduce intermediate states. +/// - All operations will be fully executed in **public** without needing intermediate checks. +/// +/// ### 2. Public Functions: +/// No **reentrancy guard** is required for public functions because: +/// - All public functions are marked as **internal** with a **single callsite** - from a private function. +/// - Public functions **cannot call private functions**, eliminating the risk of reentering into them from private. +/// - Since public functions are internal-only, **external contracts cannot access them**, ensuring no external +/// contract can trigger a reentrant call. This eliminates the following attack vector: +/// `AMM.private_fn --> AMM.public_fn --> ExternalContract.fn --> AMM.public_fn`. +pub contract AMM { + use crate::config::Config; + use crate::lib::get_amount_in; + use crate::lib::get_amount_out; + use crate::lib::get_amounts_on_remove; + use crate::lib::get_amounts_to_add; + use aztec::macros::functions::external; + use aztec::macros::functions::initializer; + use aztec::macros::functions::only_self; + use aztec::macros::storage::storage; + use aztec::protocol::address::AztecAddress; + use aztec::state_vars::PublicImmutable; + use token::Token; + use uint_note::PartialUintNote; + + struct Storage { + config: PublicImmutable, + } + + impl Storage { + fn init(context: Context) -> Self { + Self { config: as aztec::state_vars::StateVariable<4, Context>>::new(context, 1_Field)} + } + } + + /// Amount of liquidity which gets locked when liquidity is provided for the first time. Its purpose is to prevent + /// the pool from ever emptying which could lead to undefined behavior. + pub global MINIMUM_LIQUIDITY: u128 = 1000; + + /// We set it to 99 times the minimum liquidity. That way the first LP gets 99% of the value of their deposit. + pub global INITIAL_LIQUIDITY: u128 = 99000; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call constructor. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn constructor(token0: AztecAddress, token1: AztecAddress, liquidity_token: AztecAddress); + + /// Privately adds liquidity to the pool. This function receives the minimum and maximum number of tokens the caller + /// is willing to add, in order to account for changing market conditions, and will try to add as many tokens as + /// possible. + /// + /// `authwit_nonce` can be any non-zero value, as it's only used to isolate token transfer authwits to this + /// specific call. + /// + /// The identity of the liquidity provider is not revealed, but the action and amounts are. + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call add_liquidity. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn add_liquidity(amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128, authwit_nonce: Field); + + #[abi(storage)] + pub global STORAGE_LAYOUT_AMM: StorageLayout<3> = StorageLayout::<3> { + contract_name: "AMM", + fields: StorageLayoutFields { + config: aztec::state_vars::Storable { + slot: 0x01, + }, + }, + }; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call _add_liquidity. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _add_liquidity(config: Config, refund_token0_partial_note: PartialUintNote, refund_token1_partial_note: PartialUintNote, liquidity_partial_note: PartialUintNote, amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128); + + /// Privately removes liquidity from the pool. This function receives how many liquidity tokens to burn, and the + /// minimum number of tokens the caller is willing to receive, in order to account for changing market conditions. + /// + /// `authwit_nonce` can be any non-zero value, as it's only used to isolate token transfer authwits to this + /// specific call. + /// + /// The identity of the liquidity provider is not revealed, but the action and amounts are. + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call remove_liquidity. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn remove_liquidity(liquidity: u128, amount0_min: u128, amount1_min: u128, authwit_nonce: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call _remove_liquidity. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _remove_liquidity(config: Config, liquidity: u128, token0_partial_note: PartialUintNote, token1_partial_note: PartialUintNote, amount0_min: u128, amount1_min: u128); + + /// Privately swaps `amount_in` `token_in` tokens for at least `amount_out_mint` `token_out` tokens with the pool. + /// + /// `authwit_nonce` can be any non-zero value, as it's only used to isolate token transfer authwits to this + /// specific call. + /// + /// The identity of the swapper is not revealed, but the action and amounts are. + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call swap_exact_tokens_for_tokens. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn swap_exact_tokens_for_tokens(token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, authwit_nonce: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call _swap_exact_tokens_for_tokens. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _swap_exact_tokens_for_tokens(token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, token_out_partial_note: PartialUintNote); + + /// Privately swaps at most `amount_in_max` `token_in` tokens for `amount_out` `token_out` tokens with the pool. + /// + /// `authwit_nonce` can be any non-zero value, as it's only used to isolate token transfer authwits to this + /// specific call. + /// + /// The identity of the swapper is not revealed, but the action and amounts are. + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call swap_tokens_for_exact_tokens. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn swap_tokens_for_exact_tokens(token_in: AztecAddress, token_out: AztecAddress, amount_out: u128, amount_in_max: u128, authwit_nonce: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call _swap_tokens_for_exact_tokens. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _swap_tokens_for_exact_tokens(token_in: AztecAddress, token_out: AztecAddress, amount_in_max: u128, amount_out: u128, change_token_in_partial_note: PartialUintNote, token_out_partial_note: PartialUintNote); + + #[deprecated(deny, "Direct invocation of utility functions is not supported. You attempted to call get_amount_out_for_exact_in. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + unconstrained fn get_amount_out_for_exact_in(balance_in: u128, balance_out: u128, amount_in: u128) -> u128; + + #[deprecated(deny, "Direct invocation of utility functions is not supported. You attempted to call get_amount_in_for_exact_out. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + unconstrained fn get_amount_in_for_exact_out(balance_in: u128, balance_out: u128, amount_out: u128) -> u128; + + /// Unpacks an array into a note corresponding to `note_type_id` and then computes its note hash (non-siloed) and inner nullifier (non-siloed) assuming the note has been inserted into the note hash tree with `note_nonce`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + #[allow(dead_code)] + unconstrained fn _compute_note_hash_and_nullifier(packed_note: BoundedVec, owner: AztecAddress, storage_slot: Field, note_type_id: Field, contract_address: AztecAddress, randomness: Field, note_nonce: Field) -> Option { + _compute_note_hash(packed_note, owner, storage_slot, note_type_id, contract_address, randomness).map(|note_hash: Field| -> aztec::messages::discovery::NoteHashAndNullifier { + let siloed_note_hash: Field = aztec::protocol::hash::compute_siloed_note_hash(contract_address, note_hash); + let unique_note_hash: Field = aztec::protocol::hash::compute_unique_note_hash(note_nonce, siloed_note_hash); + let inner_nullifier: Option = _compute_note_nullifier(unique_note_hash, packed_note, owner, storage_slot, note_type_id, contract_address, randomness); + aztec::messages::discovery::NoteHashAndNullifier { note_hash: note_hash, inner_nullifier: inner_nullifier} + }) + } + + /// Unpacks an array into a note corresponding to `note_type_id` and then computes its note hash (non-siloed). + /// + /// The signature of this function notably matches the `aztec::messages::discovery::ComputeNoteHash` type, and so it can be used to call functions from that module such as `do_sync_state` and `attempt_note_discovery`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_hash(packed_note: BoundedVec, owner: AztecAddress, storage_slot: Field, note_type_id: Field, _contract_address: AztecAddress, randomness: Field) -> Option { + if note_type_id == ::get_id() { + let expected_len: u32 = ::N; + let actual_len: u32 = packed_note.len(); + if actual_len != expected_len { + (|args: [Field; 3]| aztec::oracle::logging::warn_log_format("[aztec-nr] Packed note length mismatch for note type id {0}: expected {1} fields, got {2}. Skipping note.", args))([note_type_id, expected_len as Field, actual_len as Field]); + Option::::none() + } else { + let note: uint_note::UintNote = ::unpack(aztec::utils::array::subarray::subarray(packed_note.storage(), 0_u32)); + Option::::some(::compute_note_hash(note, owner, storage_slot, randomness)) + } + } else { + (|args: [Field; 1]| aztec::oracle::logging::warn_log_format("[aztec-nr] Unknown note type id {0}. Skipping note.", args))([note_type_id]); + Option::::none() + } + } + + /// Computes a note's inner nullifier (non-siloed) given its unique note hash, preimage and extra data. + /// + /// The signature of this function notably matches the `aztec::messages::discovery::ComputeNoteNullifier` type, and so it can be used to call functions from that module such as `do_sync_state` and `attempt_note_discovery`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_nullifier(unique_note_hash: Field, packed_note: BoundedVec, owner: AztecAddress, _storage_slot: Field, note_type_id: Field, _contract_address: AztecAddress, _randomness: Field) -> Option { + if note_type_id == ::get_id() { + let expected_len: u32 = ::N; + let actual_len: u32 = packed_note.len(); + if actual_len != expected_len { + (|args: [Field; 3]| aztec::oracle::logging::warn_log_format("[aztec-nr] Packed note length mismatch for note type id {0}: expected {1} fields, got {2}. Skipping note.", args))([note_type_id, expected_len as Field, actual_len as Field]); + Option::::none() + } else { + let note: uint_note::UintNote = ::unpack(aztec::utils::array::subarray::subarray(packed_note.storage(), 0_u32)); + ::compute_nullifier_unconstrained(note, owner, unique_note_hash) + } + } else { + (|args: [Field; 1]| aztec::oracle::logging::warn_log_format("[aztec-nr] Unknown note type id {0}. Skipping note.", args))([note_type_id]); + Option::::none() + } + } + + /// Receives offchain messages into this contract's offchain inbox for subsequent processing. + /// + /// Each message is routed to the inbox scoped to its `recipient` field. + /// + /// For more details, see `aztec::messages::processing::offchain::receive`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + unconstrained fn offchain_receive(messages: BoundedVec) { + let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::processing::offchain::receive(address, messages); + } + + pub struct AMM { + pub target_contract: AztecAddress, + } + + impl AMM { + pub fn storage_layout() -> StorageLayoutFields { + STORAGE_LAYOUT_AMM.fields + } + + pub fn at(addr: AztecAddress) -> Self { + Self { target_contract: addr} + } + + pub fn interface() -> Self { + Self { target_contract: AztecAddress::zero()} + } + + pub fn constructor(self, token0: AztecAddress, token1: AztecAddress, liquidity_token: AztecAddress) -> aztec::context::calls::PublicCall<11, 3, ()> { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token0); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token1); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(liquidity_token); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2287085075_Field); + aztec::context::calls::PublicCall::<11, 3, ()>::new(self.target_contract, selector, "constructor", serialized_params) + } + + pub fn add_liquidity(self, amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128, authwit_nonce: Field) -> aztec::context::calls::PrivateCall<13, 5, ()> { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(amount0_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3734879327_Field); + aztec::context::calls::PrivateCall::<13, 5, ()>::new(self.target_contract, selector, "add_liquidity", serialized_params) + } + + pub fn swap_exact_tokens_for_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, authwit_nonce: Field) -> aztec::context::calls::PrivateCall<28, 5, ()> { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2960373586_Field); + aztec::context::calls::PrivateCall::<28, 5, ()>::new(self.target_contract, selector, "swap_exact_tokens_for_tokens", serialized_params) + } + + pub fn _swap_tokens_for_exact_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in_max: u128, amount_out: u128, change_token_in_partial_note: PartialUintNote, token_out_partial_note: PartialUintNote) -> aztec::context::calls::PublicCall<29, 6, ()> { + let mut serialized_params: [Field; 6] = [0_Field; 6]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(change_token_in_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3156435103_Field); + aztec::context::calls::PublicCall::<29, 6, ()>::new(self.target_contract, selector, "_swap_tokens_for_exact_tokens", serialized_params) + } + + pub fn _swap_exact_tokens_for_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, token_out_partial_note: PartialUintNote) -> aztec::context::calls::PublicCall<29, 5, ()> { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1918288610_Field); + aztec::context::calls::PublicCall::<29, 5, ()>::new(self.target_contract, selector, "_swap_exact_tokens_for_tokens", serialized_params) + } + + pub fn _remove_liquidity(self, config: Config, liquidity: u128, token0_partial_note: PartialUintNote, token1_partial_note: PartialUintNote, amount0_min: u128, amount1_min: u128) -> aztec::context::calls::PublicCall<17, 8, ()> { + let mut serialized_params: [Field; 8] = [0_Field; 8]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3] = >::serialize(config); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(liquidity); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token0_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token1_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2270402407_Field); + aztec::context::calls::PublicCall::<17, 8, ()>::new(self.target_contract, selector, "_remove_liquidity", serialized_params) + } + + pub fn _add_liquidity(self, config: Config, refund_token0_partial_note: PartialUintNote, refund_token1_partial_note: PartialUintNote, liquidity_partial_note: PartialUintNote, amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128) -> aztec::context::calls::PublicCall<14, 10, ()> { + let mut serialized_params: [Field; 10] = [0_Field; 10]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3] = >::serialize(config); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(refund_token0_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(refund_token1_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(liquidity_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_6: u32 = i + offset; + serialized_params[i_6] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_7: u32 = i + offset; + serialized_params[i_7] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1909103841_Field); + aztec::context::calls::PublicCall::<14, 10, ()>::new(self.target_contract, selector, "_add_liquidity", serialized_params) + } + + pub fn remove_liquidity(self, liquidity: u128, amount0_min: u128, amount1_min: u128, authwit_nonce: Field) -> aztec::context::calls::PrivateCall<16, 4, ()> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(liquidity); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1221183968_Field); + aztec::context::calls::PrivateCall::<16, 4, ()>::new(self.target_contract, selector, "remove_liquidity", serialized_params) + } + + pub fn swap_tokens_for_exact_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_out: u128, amount_in_max: u128, authwit_nonce: Field) -> aztec::context::calls::PrivateCall<28, 5, ()> { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2620890703_Field); + aztec::context::calls::PrivateCall::<28, 5, ()>::new(self.target_contract, selector, "swap_tokens_for_exact_tokens", serialized_params) + } + + pub fn get_amount_out_for_exact_in(self, balance_in: u128, balance_out: u128, amount_in: u128) -> aztec::context::calls::UtilityCall<27, 3, u128> { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(balance_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(balance_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(58321933_Field); + aztec::context::calls::UtilityCall::<27, 3, u128>::new(self.target_contract, selector, "get_amount_out_for_exact_in", serialized_params) + } + + pub fn get_amount_in_for_exact_out(self, balance_in: u128, balance_out: u128, amount_out: u128) -> aztec::context::calls::UtilityCall<27, 3, u128> { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(balance_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(balance_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4155151179_Field); + aztec::context::calls::UtilityCall::<27, 3, u128>::new(self.target_contract, selector, "get_amount_in_for_exact_out", serialized_params) + } + + pub fn offchain_receive(self, messages: BoundedVec) -> aztec::context::calls::UtilityCall<16, 321, ()> { + let serialized_params: [Field; 321] = as aztec::protocol::traits::Serialize>::serialize(messages); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1396850735_Field); + aztec::context::calls::UtilityCall::<16, 321, ()>::new(self.target_contract, selector, "offchain_receive", serialized_params) + } + } + + #[contract_library_method] + pub fn storage_layout() -> StorageLayoutFields { + STORAGE_LAYOUT_AMM.fields + } + + #[contract_library_method] + pub fn at(addr: AztecAddress) -> AMM { + AMM { target_contract: addr} + } + + #[contract_library_method] + pub fn interface() -> AMM { + AMM { target_contract: AztecAddress::zero()} + } + + pub struct sync_state_parameters { + pub scope: AztecAddress, + } + + #[abi(functions)] + pub struct sync_state_abi { + parameters: sync_state_parameters, + } + + unconstrained fn sync_state(scope: AztecAddress) { + let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + } + + pub struct offchain_receive_parameters { + pub messages: BoundedVec, + } + + #[abi(functions)] + pub struct offchain_receive_abi { + parameters: offchain_receive_parameters, + } + + pub struct CallSelf { + pub address: AztecAddress, + pub context: Context, + } + + impl CallSelf { + pub fn _remove_liquidity(self, config: Config, liquidity: u128, token0_partial_note: PartialUintNote, token1_partial_note: PartialUintNote, amount0_min: u128, amount1_min: u128) { + let mut serialized_params: [Field; 8] = [0_Field; 8]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3] = >::serialize(config); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(liquidity); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token0_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token1_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2270402407_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<17, 8, ()>::new(self.address, selector, "_remove_liquidity", serialized_params).call(self.context) + } + } + + pub fn _add_liquidity(self, config: Config, refund_token0_partial_note: PartialUintNote, refund_token1_partial_note: PartialUintNote, liquidity_partial_note: PartialUintNote, amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128) { + let mut serialized_params: [Field; 10] = [0_Field; 10]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3] = >::serialize(config); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(refund_token0_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(refund_token1_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(liquidity_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_6: u32 = i + offset; + serialized_params[i_6] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_7: u32 = i + offset; + serialized_params[i_7] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1909103841_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 10, ()>::new(self.address, selector, "_add_liquidity", serialized_params).call(self.context) + } + } + + pub fn constructor(self, token0: AztecAddress, token1: AztecAddress, liquidity_token: AztecAddress) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token0); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token1); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(liquidity_token); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2287085075_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<11, 3, ()>::new(self.address, selector, "constructor", serialized_params).call(self.context) + } + } + + pub fn _swap_tokens_for_exact_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in_max: u128, amount_out: u128, change_token_in_partial_note: PartialUintNote, token_out_partial_note: PartialUintNote) { + let mut serialized_params: [Field; 6] = [0_Field; 6]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(change_token_in_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3156435103_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<29, 6, ()>::new(self.address, selector, "_swap_tokens_for_exact_tokens", serialized_params).call(self.context) + } + } + + pub fn _swap_exact_tokens_for_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, token_out_partial_note: PartialUintNote) { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1918288610_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<29, 5, ()>::new(self.address, selector, "_swap_exact_tokens_for_tokens", serialized_params).call(self.context) + } + } + } + + impl CallSelf<&mut aztec::context::PrivateContext> { + pub fn remove_liquidity(self, liquidity: u128, amount0_min: u128, amount1_min: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(liquidity); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1221183968_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn add_liquidity(self, amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(amount0_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3734879327_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn swap_tokens_for_exact_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_out: u128, amount_in_max: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2620890703_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn swap_exact_tokens_for_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2960373586_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + } + + pub struct CallSelfStatic { + pub address: AztecAddress, + pub context: Context, + } + + pub struct EnqueueSelf { + pub address: AztecAddress, + pub context: Context, + } + + impl EnqueueSelf<&mut aztec::context::PrivateContext> { + pub fn _remove_liquidity(self, config: Config, liquidity: u128, token0_partial_note: PartialUintNote, token1_partial_note: PartialUintNote, amount0_min: u128, amount1_min: u128) { + let mut serialized_params: [Field; 8] = [0_Field; 8]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3] = >::serialize(config); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(liquidity); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token0_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token1_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2270402407_Field); + let calldata: [Field; 1 + 8] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn _swap_tokens_for_exact_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in_max: u128, amount_out: u128, change_token_in_partial_note: PartialUintNote, token_out_partial_note: PartialUintNote) { + let mut serialized_params: [Field; 6] = [0_Field; 6]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(change_token_in_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3156435103_Field); + let calldata: [Field; 1 + 6] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn _add_liquidity(self, config: Config, refund_token0_partial_note: PartialUintNote, refund_token1_partial_note: PartialUintNote, liquidity_partial_note: PartialUintNote, amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128) { + let mut serialized_params: [Field; 10] = [0_Field; 10]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3] = >::serialize(config); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(refund_token0_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(refund_token1_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(liquidity_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_6: u32 = i + offset; + serialized_params[i_6] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_7: u32 = i + offset; + serialized_params[i_7] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1909103841_Field); + let calldata: [Field; 1 + 10] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn _swap_exact_tokens_for_tokens(self, token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, token_out_partial_note: PartialUintNote) { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out_partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1918288610_Field); + let calldata: [Field; 1 + 5] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn constructor(self, token0: AztecAddress, token1: AztecAddress, liquidity_token: AztecAddress) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token0); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token1); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(liquidity_token); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2287085075_Field); + let calldata: [Field; 1 + 3] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + } + + pub struct EnqueueSelfStatic { + pub address: AztecAddress, + pub context: Context, + } + + pub struct CallSelfUtility { + pub address: AztecAddress, + } + + impl CallSelfUtility { + pub unconstrained fn get_amount_out_for_exact_in(self, balance_in: u128, balance_out: u128, amount_in: u128) -> u128 { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(balance_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(balance_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(58321933_Field); + let returns: [Field; 1] = aztec::oracle::call_utility_function::call_utility_function(self.address, selector, serialized_params); + ::deserialize(returns) + } + + pub unconstrained fn get_amount_in_for_exact_out(self, balance_in: u128, balance_out: u128, amount_out: u128) -> u128 { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(balance_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(balance_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4155151179_Field); + let returns: [Field; 1] = aztec::oracle::call_utility_function::call_utility_function(self.address, selector, serialized_params); + ::deserialize(returns) + } + } + + pub struct CallInternal { + pub context: Context, + } + + pub unconstrained fn public_dispatch(selector: Field) { + if selector == 2287085075_Field { + let input_calldata: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (::N + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<3> = aztec::protocol::utils::reader::Reader::<3>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: AztecAddress = ::stream_deserialize(&mut reader); + let arg2: AztecAddress = ::stream_deserialize(&mut reader); + __aztec_nr_internals__constructor(arg0, arg1, arg2); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1909103841_Field { + let input_calldata: [Field; 10] = aztec::oracle::avm::calldata_copy(1_u32, ((((((>::N + ::N) + ::N) + ::N) + ::N) + ::N) + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<10> = aztec::protocol::utils::reader::Reader::<10>::new(input_calldata); + let arg0: Config = >::stream_deserialize(&mut reader); + let arg1: PartialUintNote = ::stream_deserialize(&mut reader); + let arg2: PartialUintNote = ::stream_deserialize(&mut reader); + let arg3: PartialUintNote = ::stream_deserialize(&mut reader); + let arg4: u128 = ::stream_deserialize(&mut reader); + let arg5: u128 = ::stream_deserialize(&mut reader); + let arg6: u128 = ::stream_deserialize(&mut reader); + let arg7: u128 = ::stream_deserialize(&mut reader); + __aztec_nr_internals___add_liquidity(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2270402407_Field { + let input_calldata: [Field; 8] = aztec::oracle::avm::calldata_copy(1_u32, ((((>::N + ::N) + ::N) + ::N) + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<8> = aztec::protocol::utils::reader::Reader::<8>::new(input_calldata); + let arg0: Config = >::stream_deserialize(&mut reader); + let arg1: u128 = ::stream_deserialize(&mut reader); + let arg2: PartialUintNote = ::stream_deserialize(&mut reader); + let arg3: PartialUintNote = ::stream_deserialize(&mut reader); + let arg4: u128 = ::stream_deserialize(&mut reader); + let arg5: u128 = ::stream_deserialize(&mut reader); + __aztec_nr_internals___remove_liquidity(arg0, arg1, arg2, arg3, arg4, arg5); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1918288610_Field { + let input_calldata: [Field; 5] = aztec::oracle::avm::calldata_copy(1_u32, (((::N + ::N) + ::N) + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<5> = aztec::protocol::utils::reader::Reader::<5>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: AztecAddress = ::stream_deserialize(&mut reader); + let arg2: u128 = ::stream_deserialize(&mut reader); + let arg3: u128 = ::stream_deserialize(&mut reader); + let arg4: PartialUintNote = ::stream_deserialize(&mut reader); + __aztec_nr_internals___swap_exact_tokens_for_tokens(arg0, arg1, arg2, arg3, arg4); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3156435103_Field { + let input_calldata: [Field; 6] = aztec::oracle::avm::calldata_copy(1_u32, ((((::N + ::N) + ::N) + ::N) + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<6> = aztec::protocol::utils::reader::Reader::<6>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: AztecAddress = ::stream_deserialize(&mut reader); + let arg2: u128 = ::stream_deserialize(&mut reader); + let arg3: u128 = ::stream_deserialize(&mut reader); + let arg4: PartialUintNote = ::stream_deserialize(&mut reader); + let arg5: PartialUintNote = ::stream_deserialize(&mut reader); + __aztec_nr_internals___swap_tokens_for_exact_tokens(arg0, arg1, arg2, arg3, arg4, arg5); + aztec::oracle::avm::avm_return([].as_slice()); + }; + panic(f"Unknown selector {selector}") + } + + pub struct _add_liquidity_parameters { + pub config: Config, + pub refund_token0_partial_note: PartialUintNote, + pub refund_token1_partial_note: PartialUintNote, + pub liquidity_partial_note: PartialUintNote, + pub amount0_max: u128, + pub amount1_max: u128, + pub amount0_min: u128, + pub amount1_min: u128, + } + + pub struct _remove_liquidity_parameters { + pub config: Config, + pub liquidity: u128, + pub token0_partial_note: PartialUintNote, + pub token1_partial_note: PartialUintNote, + pub amount0_min: u128, + pub amount1_min: u128, + } + + pub struct _swap_exact_tokens_for_tokens_parameters { + pub token_in: AztecAddress, + pub token_out: AztecAddress, + pub amount_in: u128, + pub amount_out_min: u128, + pub token_out_partial_note: PartialUintNote, + } + + pub struct _swap_tokens_for_exact_tokens_parameters { + pub token_in: AztecAddress, + pub token_out: AztecAddress, + pub amount_in_max: u128, + pub amount_out: u128, + pub change_token_in_partial_note: PartialUintNote, + pub token_out_partial_note: PartialUintNote, + } + + pub struct add_liquidity_parameters { + pub amount0_max: u128, + pub amount1_max: u128, + pub amount0_min: u128, + pub amount1_min: u128, + pub authwit_nonce: Field, + } + + pub struct constructor_parameters { + pub token0: AztecAddress, + pub token1: AztecAddress, + pub liquidity_token: AztecAddress, + } + + pub struct get_amount_in_for_exact_out_parameters { + pub balance_in: u128, + pub balance_out: u128, + pub amount_out: u128, + } + + pub struct get_amount_out_for_exact_in_parameters { + pub balance_in: u128, + pub balance_out: u128, + pub amount_in: u128, + } + + pub struct remove_liquidity_parameters { + pub liquidity: u128, + pub amount0_min: u128, + pub amount1_min: u128, + pub authwit_nonce: Field, + } + + pub struct swap_exact_tokens_for_tokens_parameters { + pub token_in: AztecAddress, + pub token_out: AztecAddress, + pub amount_in: u128, + pub amount_out_min: u128, + pub authwit_nonce: Field, + } + + pub struct swap_tokens_for_exact_tokens_parameters { + pub token_in: AztecAddress, + pub token_out: AztecAddress, + pub amount_out: u128, + pub amount_in_max: u128, + pub authwit_nonce: Field, + } + + #[abi(functions)] + pub struct _add_liquidity_abi { + parameters: _add_liquidity_parameters, + } + + #[abi(functions)] + pub struct _remove_liquidity_abi { + parameters: _remove_liquidity_parameters, + } + + #[abi(functions)] + pub struct _swap_exact_tokens_for_tokens_abi { + parameters: _swap_exact_tokens_for_tokens_parameters, + } + + #[abi(functions)] + pub struct _swap_tokens_for_exact_tokens_abi { + parameters: _swap_tokens_for_exact_tokens_parameters, + } + + #[abi(functions)] + pub struct add_liquidity_abi { + parameters: add_liquidity_parameters, + } + + #[abi(functions)] + pub struct constructor_abi { + parameters: constructor_parameters, + } + + #[abi(functions)] + pub struct get_amount_in_for_exact_out_abi { + parameters: get_amount_in_for_exact_out_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct get_amount_out_for_exact_in_abi { + parameters: get_amount_out_for_exact_in_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct remove_liquidity_abi { + parameters: remove_liquidity_parameters, + } + + #[abi(functions)] + pub struct swap_exact_tokens_for_tokens_abi { + parameters: swap_exact_tokens_for_tokens_parameters, + } + + #[abi(functions)] + pub struct swap_tokens_for_exact_tokens_abi { + parameters: swap_tokens_for_exact_tokens_parameters, + } + + fn __aztec_nr_internals__add_liquidity(inputs: aztec::context::inputs::PrivateContextInputs, amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(amount0_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: aztec::context::PrivateContext = aztec::context::PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut aztec::context::PrivateContext> = Storage::<&mut aztec::context::PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut aztec::context::PrivateContext> = CallSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut aztec::context::PrivateContext> = EnqueueSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut aztec::context::PrivateContext> = CallSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut aztec::context::PrivateContext> = EnqueueSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut aztec::context::PrivateContext> = CallInternal::<&mut aztec::context::PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + assert((amount0_min < amount0_max) | (amount0_min == amount0_max), "INCORRECT_TOKEN0_LIMITS"); + assert((amount1_min < amount1_max) | (amount1_min == amount1_max), "INCORRECT_TOKEN1_LIMITS"); + assert(((0_Field as u128) < amount0_max) & ((0_Field as u128) < amount1_max), "INSUFFICIENT_INPUT_AMOUNTS"); + let config: Config = self.storage.config.read(); + let token0: Token::Token = Token::at(config.token0); + let token1: Token::Token = Token::at(config.token1); + let liquidity_token: Token::Token = Token::at(config.liquidity_token); + let sender: AztecAddress = self.msg_sender(); + let refund_token0_partial_note: PartialUintNote = self.call(token0.transfer_to_public_and_prepare_private_balance_increase(sender, self.address, amount0_max, authwit_nonce)); + let refund_token1_partial_note: PartialUintNote = self.call(token1.transfer_to_public_and_prepare_private_balance_increase(sender, self.address, amount1_max, authwit_nonce)); + let liquidity_partial_note: PartialUintNote = self.call(liquidity_token.prepare_private_balance_increase(sender)); + self.enqueue_self._add_liquidity(config, refund_token0_partial_note, refund_token1_partial_note, liquidity_partial_note, amount0_max, amount1_max, amount0_min, amount1_min); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__remove_liquidity(inputs: aztec::context::inputs::PrivateContextInputs, liquidity: u128, amount0_min: u128, amount1_min: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(liquidity); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount0_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount1_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: aztec::context::PrivateContext = aztec::context::PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut aztec::context::PrivateContext> = Storage::<&mut aztec::context::PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut aztec::context::PrivateContext> = CallSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut aztec::context::PrivateContext> = EnqueueSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut aztec::context::PrivateContext> = CallSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut aztec::context::PrivateContext> = EnqueueSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut aztec::context::PrivateContext> = CallInternal::<&mut aztec::context::PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + let config: Config = self.storage.config.read(); + let liquidity_token: Token::Token = Token::at(config.liquidity_token); + let token0: Token::Token = Token::at(config.token0); + let token1: Token::Token = Token::at(config.token1); + let sender: AztecAddress = self.msg_sender(); + self.call(liquidity_token.transfer_to_public(sender, self.address, liquidity, authwit_nonce)); + let token0_partial_note: PartialUintNote = self.call(token0.prepare_private_balance_increase(sender)); + let token1_partial_note: PartialUintNote = self.call(token1.prepare_private_balance_increase(sender)); + self.enqueue_self._remove_liquidity(config, liquidity, token0_partial_note, token1_partial_note, amount0_min, amount1_min); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__swap_exact_tokens_for_tokens(inputs: aztec::context::inputs::PrivateContextInputs, token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out_min); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: aztec::context::PrivateContext = aztec::context::PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut aztec::context::PrivateContext> = Storage::<&mut aztec::context::PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut aztec::context::PrivateContext> = CallSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut aztec::context::PrivateContext> = EnqueueSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut aztec::context::PrivateContext> = CallSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut aztec::context::PrivateContext> = EnqueueSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut aztec::context::PrivateContext> = CallInternal::<&mut aztec::context::PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + let config: Config = self.storage.config.read(); + assert((token_in == config.token0) | (token_in == config.token1), "TOKEN_IN_IS_INVALID"); + assert((token_out == config.token0) | (token_out == config.token1), "TOKEN_OUT_IS_INVALID"); + assert(token_in != token_out, "SAME_TOKEN_SWAP"); + let sender: AztecAddress = self.msg_sender(); + self.call(Token::at(token_in).transfer_to_public(sender, self.address, amount_in, authwit_nonce)); + let token_out_partial_note: PartialUintNote = self.call(Token::at(token_out).prepare_private_balance_increase(sender)); + self.enqueue_self._swap_exact_tokens_for_tokens(token_in, token_out, amount_in, amount_out_min, token_out_partial_note); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__swap_tokens_for_exact_tokens(inputs: aztec::context::inputs::PrivateContextInputs, token_in: AztecAddress, token_out: AztecAddress, amount_out: u128, amount_in_max: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 5] = [0_Field; 5]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(token_in); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(token_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_out); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount_in_max); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: aztec::context::PrivateContext = aztec::context::PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut aztec::context::PrivateContext> = Storage::<&mut aztec::context::PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut aztec::context::PrivateContext> = CallSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut aztec::context::PrivateContext> = EnqueueSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut aztec::context::PrivateContext> = CallSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut aztec::context::PrivateContext> = EnqueueSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut aztec::context::PrivateContext> = CallInternal::<&mut aztec::context::PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + let config: Config = self.storage.config.read(); + assert((token_in == config.token0) | (token_in == config.token1), "TOKEN_IN_IS_INVALID"); + assert((token_out == config.token0) | (token_out == config.token1), "TOKEN_OUT_IS_INVALID"); + assert(token_in != token_out, "SAME_TOKEN_SWAP"); + let sender: AztecAddress = self.msg_sender(); + let change_token_in_partial_note: PartialUintNote = self.call(Token::at(token_in).transfer_to_public_and_prepare_private_balance_increase(sender, self.address, amount_in_max, authwit_nonce)); + let token_out_partial_note: PartialUintNote = self.call(Token::at(token_out).prepare_private_balance_increase(sender)); + self.enqueue_self._swap_tokens_for_exact_tokens(token_in, token_out, amount_in_max, amount_out, change_token_in_partial_note, token_out_partial_note); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + unconstrained fn __aztec_nr_internals___add_liquidity(config: Config, refund_token0_partial_note: PartialUintNote, refund_token1_partial_note: PartialUintNote, liquidity_partial_note: PartialUintNote, amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 10] = aztec::oracle::avm::calldata_copy(1_u32, ((((((>::N + ::N) + ::N) + ::N) + ::N) + ::N) + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.msg_sender() == self.address, "Function _add_liquidity can only be called by the same contract"); + { + let token0: Token::Token = Token::at(config.token0); + let token1: Token::Token = Token::at(config.token1); + let liquidity_token: Token::Token = Token::at(config.liquidity_token); + let balance0_plus_amount0_max: u128 = self.view(token0.balance_of_public(self.address)); + let balance0: u128 = balance0_plus_amount0_max - amount0_max; + let balance1_plus_amount1_max: u128 = self.view(token1.balance_of_public(self.address)); + let balance1: u128 = balance1_plus_amount1_max - amount1_max; + let (amount0, amount1): (u128, u128) = get_amounts_to_add(amount0_max, amount1_max, amount0_min, amount1_min, balance0, balance1); + let refund_amount_token0: u128 = amount0_max - amount0; + let refund_amount_token1: u128 = amount1_max - amount1; + if refund_amount_token0 > (0_Field as u128) { + self.call(token0.finalize_transfer_to_private(refund_amount_token0, refund_token0_partial_note)); + }; + if refund_amount_token1 > (0_Field as u128) { + self.call(token1.finalize_transfer_to_private(refund_amount_token1, refund_token1_partial_note)); + }; + let total_supply: u128 = self.view(liquidity_token.total_supply()); + let liquidity_amount: u128 = if total_supply != (0_Field as u128) { + std::cmp::min((amount0 * total_supply) / balance0, (amount1 * total_supply) / balance1) + } else { + liquidity_token.mint_to_public(AztecAddress::zero(), MINIMUM_LIQUIDITY).call(self.context); + INITIAL_LIQUIDITY + }; + assert(liquidity_amount > (0_Field as u128), "INSUFFICIENT_LIQUIDITY_MINTED"); + liquidity_token.finalize_mint_to_private(liquidity_amount, liquidity_partial_note).call(self.context); + } + } + + unconstrained fn __aztec_nr_internals___remove_liquidity(config: Config, liquidity: u128, token0_partial_note: PartialUintNote, token1_partial_note: PartialUintNote, amount0_min: u128, amount1_min: u128) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 8] = aztec::oracle::avm::calldata_copy(1_u32, ((((>::N + ::N) + ::N) + ::N) + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.msg_sender() == self.address, "Function _remove_liquidity can only be called by the same contract"); + { + let token0: Token::Token = Token::at(config.token0); + let token1: Token::Token = Token::at(config.token1); + let liquidity_token: Token::Token = Token::at(config.liquidity_token); + let balance0: u128 = self.view(token0.balance_of_public(self.address)); + let balance1: u128 = self.view(token1.balance_of_public(self.address)); + let total_supply: u128 = self.view(liquidity_token.total_supply()); + let (amount0, amount1): (u128, u128) = get_amounts_on_remove(liquidity, total_supply, balance0, balance1); + assert(amount0 >= amount0_min, "INSUFFICIENT_0_AMOUNT"); + assert(amount1 >= amount1_min, "INSUFFICIENT_1_AMOUNT"); + self.call(liquidity_token.burn_public(self.address, liquidity, 0_Field)); + self.call(token0.finalize_transfer_to_private(amount0, token0_partial_note)); + self.call(token1.finalize_transfer_to_private(amount1, token1_partial_note)); + } + } + + unconstrained fn __aztec_nr_internals___swap_exact_tokens_for_tokens(token_in: AztecAddress, token_out: AztecAddress, amount_in: u128, amount_out_min: u128, token_out_partial_note: PartialUintNote) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 5] = aztec::oracle::avm::calldata_copy(1_u32, (((::N + ::N) + ::N) + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.msg_sender() == self.address, "Function _swap_exact_tokens_for_tokens can only be called by the same contract"); + { + let balance_in_plus_amount_in: u128 = self.view(Token::at(token_in).balance_of_public(self.address)); + let balance_in: u128 = balance_in_plus_amount_in - amount_in; + let balance_out: u128 = self.view(Token::at(token_out).balance_of_public(self.address)); + let amount_out: u128 = get_amount_out(amount_in, balance_in, balance_out); + assert(amount_out >= amount_out_min, "INSUFFICIENT_OUTPUT_AMOUNT"); + Token::at(token_out).finalize_transfer_to_private(amount_out, token_out_partial_note).call(self.context); + } + } + + unconstrained fn __aztec_nr_internals___swap_tokens_for_exact_tokens(token_in: AztecAddress, token_out: AztecAddress, amount_in_max: u128, amount_out: u128, change_token_in_partial_note: PartialUintNote, token_out_partial_note: PartialUintNote) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 6] = aztec::oracle::avm::calldata_copy(1_u32, ((((::N + ::N) + ::N) + ::N) + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.msg_sender() == self.address, "Function _swap_tokens_for_exact_tokens can only be called by the same contract"); + { + let balance_in_plus_amount_in_max: u128 = self.view(Token::at(token_in).balance_of_public(self.address)); + let balance_in: u128 = balance_in_plus_amount_in_max - amount_in_max; + let balance_out: u128 = self.view(Token::at(token_out).balance_of_public(self.address)); + let amount_in: u128 = get_amount_in(amount_out, balance_in, balance_out); + assert(amount_in <= amount_in_max, "INSUFFICIENT_OUTPUT_AMOUNT"); + let change: u128 = amount_in_max - amount_in; + if change > (0_Field as u128) { + self.call(Token::at(token_in).finalize_transfer_to_private(change, change_token_in_partial_note)); + }; + Token::at(token_out).finalize_transfer_to_private(amount_out, token_out_partial_note).call(self.context); + } + } + + unconstrained fn __aztec_nr_internals__constructor(token0: AztecAddress, token1: AztecAddress, liquidity_token: AztecAddress) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (::N + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_initialization_matches_address_preimage_public(self.context); + { + self.storage.config.initialize(Config { token0: token0, token1: token1, liquidity_token: liquidity_token}); + }; + aztec::macros::functions::initialization_utils::mark_as_initialized_from_public_initializer(self.context); + } + + unconstrained fn __aztec_nr_internals__get_amount_in_for_exact_out(balance_in: u128, balance_out: u128, amount_out: u128) -> pub u128 { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_utility::ContractSelfUtility, CallSelfUtility> = { + let context: aztec::context::UtilityContext = aztec::context::UtilityContext::new(); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelfUtility = CallSelfUtility { address: self_address}; + aztec::contract_self::contract_self_utility::ContractSelfUtility::, CallSelfUtility>::new(context, storage, call_self) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_utility(self.context); + { + get_amount_in(amount_out, balance_in, balance_out) + } + } + + unconstrained fn __aztec_nr_internals__get_amount_out_for_exact_in(balance_in: u128, balance_out: u128, amount_in: u128) -> pub u128 { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_utility::ContractSelfUtility, CallSelfUtility> = { + let context: aztec::context::UtilityContext = aztec::context::UtilityContext::new(); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelfUtility = CallSelfUtility { address: self_address}; + aztec::contract_self::contract_self_utility::ContractSelfUtility::, CallSelfUtility>::new(context, storage, call_self) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_utility(self.context); + { + get_amount_out(amount_in, balance_in, balance_out) + } + } + + pub struct StorageLayoutFields { + pub config: aztec::state_vars::Storable, + } + + pub struct StorageLayout { + pub contract_name: str, + pub fields: StorageLayoutFields, + } +} + +mod test { + mod test { + use crate::AMM; + use super::utils::add_liquidity; + use super::utils::remove_liquidity; + use super::utils::setup; + use aztec::protocol::address::AztecAddress; + use aztec::protocol::traits::FromField; + use aztec::test::helpers::authwit::add_private_authwit_from_call; + use token::Token; + + global AUTHWIT_NONCE: Field = 0x01; + + global DEFAULT_AMOUNT_0_MIN: u128 = 0; + + global DEFAULT_AMOUNT_1_MIN: u128 = 0; + + #[test] + unconstrained fn add_liquidity_twice_and_remove_liquidity() { + let (mut env, amm_address, token0_address, token1_address, liquidity_token_address, minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider_1: AztecAddress = env.create_contract_account(); + let liquidity_provider_2: AztecAddress = env.create_contract_account(); + let token0: Token::Token = Token::at(token0_address); + let token1: Token::Token = Token::at(token1_address); + let liquidity_token: Token::Token = Token::at(liquidity_token_address); + let initial_amount0: u128 = 1000_Field as u128; + let initial_amount1: u128 = 2000_Field as u128; + add_liquidity(env, amm_address, token0_address, token1_address, minter, liquidity_provider_1, initial_amount0, initial_amount1, DEFAULT_AMOUNT_0_MIN, DEFAULT_AMOUNT_1_MIN); + let initial_liquidity_token_supply: u128 = env.view_public(liquidity_token.total_supply()); + assert(initial_liquidity_token_supply == (AMM::MINIMUM_LIQUIDITY + AMM::INITIAL_LIQUIDITY)); + let expected_amount_0_in: u128 = initial_amount0 / 2_u128; + let expected_amount_1_in: u128 = initial_amount1 / 2_u128; + let expected_refund_amount1: u128 = 200_Field as u128; + let amount1_max: u128 = expected_amount_1_in + expected_refund_amount1; + add_liquidity(env, amm_address, token0_address, token1_address, minter, liquidity_provider_2, expected_amount_0_in, amount1_max, DEFAULT_AMOUNT_0_MIN, DEFAULT_AMOUNT_1_MIN); + assert(env.view_public(token0.balance_of_public(amm_address)) == (initial_amount0 + expected_amount_0_in)); + assert(env.view_public(token1.balance_of_public(amm_address)) == (initial_amount1 + expected_amount_1_in)); + assert(env.execute_utility(token0.balance_of_private(liquidity_provider_2)) == 0_u128); + assert(env.execute_utility(token1.balance_of_private(liquidity_provider_2)) == expected_refund_amount1); + let expected_liquidity_tokens: u128 = (expected_amount_0_in * initial_liquidity_token_supply) / initial_amount0; + assert(env.execute_utility(liquidity_token.balance_of_private(liquidity_provider_2)) == expected_liquidity_tokens); + let liquidity_to_remove: u128 = AMM::INITIAL_LIQUIDITY / 2_u128; + let amount0_min: u128 = 400_Field as u128; + let amount1_min: u128 = 800_Field as u128; + remove_liquidity(env, amm_address, liquidity_token_address, liquidity_provider_1, liquidity_to_remove, amount0_min, amount1_min); + let expected_token0_back: u128 = (liquidity_to_remove * initial_amount0) / initial_liquidity_token_supply; + let expected_token1_back: u128 = (liquidity_to_remove * initial_amount1) / initial_liquidity_token_supply; + assert(env.execute_utility(token0.balance_of_private(liquidity_provider_1)) == expected_token0_back); + assert(env.execute_utility(token1.balance_of_private(liquidity_provider_1)) == expected_token1_back); + assert(env.execute_utility(liquidity_token.balance_of_private(liquidity_provider_1)) == (AMM::INITIAL_LIQUIDITY / 2_u128)); + } + + #[test] + unconstrained fn swap_exact_tokens_for_tokens() { + let (mut env, amm_address, token0_address, token1_address, _liquidity_token_address, minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider: AztecAddress = env.create_contract_account(); + let swapper: AztecAddress = env.create_contract_account(); + let token0: Token::Token = Token::at(token0_address); + let token1: Token::Token = Token::at(token1_address); + let amm: AMM::AMM = AMM::at(amm_address); + let liquidity_amount0: u128 = 10000_Field as u128; + let liquidity_amount1: u128 = 20000_Field as u128; + add_liquidity(env, amm_address, token0_address, token1_address, minter, liquidity_provider, liquidity_amount0, liquidity_amount1, DEFAULT_AMOUNT_0_MIN, DEFAULT_AMOUNT_1_MIN); + let amount_in: u128 = 1000_Field as u128; + let amount_out_min: u128 = 1800_Field as u128; + env.call_private(minter, token0.mint_to_private(swapper, amount_in)); + add_private_authwit_from_call(env, swapper, amm_address, token0.transfer_to_public(swapper, amm_address, amount_in, AUTHWIT_NONCE)); + env.call_private(swapper, amm.swap_exact_tokens_for_tokens(token0_address, token1_address, amount_in, amount_out_min, AUTHWIT_NONCE)); + assert(env.execute_utility(token0.balance_of_private(swapper)) == 0_u128); + assert(env.execute_utility(token1.balance_of_private(swapper)) >= amount_out_min); + } + + #[test] + unconstrained fn swap_tokens_for_exact_tokens() { + let (mut env, amm_address, token0_address, token1_address, _liquidity_token_address, minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider: AztecAddress = env.create_contract_account(); + let swapper: AztecAddress = env.create_contract_account(); + let token0: Token::Token = Token::at(token0_address); + let token1: Token::Token = Token::at(token1_address); + let amm: AMM::AMM = AMM::at(amm_address); + let liquidity_amount0: u128 = 10000_Field as u128; + let liquidity_amount1: u128 = 20000_Field as u128; + add_liquidity(env, amm_address, token0_address, token1_address, minter, liquidity_provider, liquidity_amount0, liquidity_amount1, DEFAULT_AMOUNT_0_MIN, DEFAULT_AMOUNT_1_MIN); + let amount_out: u128 = 1000_Field as u128; + let amount_in_max: u128 = 600_Field as u128; + env.call_private(minter, token0.mint_to_private(swapper, amount_in_max)); + let transfer_call: aztec::context::calls::PrivateCall<55, 4, uint_note::PartialUintNote> = token0.transfer_to_public_and_prepare_private_balance_increase(swapper, amm_address, amount_in_max, AUTHWIT_NONCE); + add_private_authwit_from_call(env, swapper, amm_address, transfer_call); + env.call_private(swapper, amm.swap_tokens_for_exact_tokens(token0_address, token1_address, amount_out, amount_in_max, AUTHWIT_NONCE)); + assert(env.execute_utility(token1.balance_of_private(swapper)) == amount_out); + let swapper_token0_balance: u128 = env.execute_utility(token0.balance_of_private(swapper)); + assert(swapper_token0_balance > 0_u128); + assert(swapper_token0_balance < amount_in_max); + } + + #[test(should_fail_with = "INCORRECT_TOKEN0_LIMITS")] + unconstrained fn add_liquidity_incorrect_token0_limits() { + let (mut env, amm_address, _token0_address, _token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let amount0_max: u128 = 500_Field as u128; + let amount1_max: u128 = 1000_Field as u128; + let amount0_min: u128 = 600_Field as u128; + let amount1_min: u128 = 500_Field as u128; + env.call_private(liquidity_provider, amm.add_liquidity(amount0_max, amount1_max, amount0_min, amount1_min, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "INCORRECT_TOKEN1_LIMITS")] + unconstrained fn add_liquidity_incorrect_token1_limits() { + let (mut env, amm_address, _token0_address, _token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let amount0_max: u128 = 500_Field as u128; + let amount1_max: u128 = 1000_Field as u128; + let amount0_min: u128 = 400_Field as u128; + let amount1_min: u128 = 1100_Field as u128; + env.call_private(liquidity_provider, amm.add_liquidity(amount0_max, amount1_max, amount0_min, amount1_min, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "INSUFFICIENT_INPUT_AMOUNTS")] + unconstrained fn add_liquidity_zero_amount0_max() { + let (mut env, amm_address, _token0_address, _token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let amount0_max: u128 = 0_Field as u128; + let amount1_max: u128 = 1000_Field as u128; + let amount0_min: u128 = 0_Field as u128; + let amount1_min: u128 = 500_Field as u128; + env.call_private(liquidity_provider, amm.add_liquidity(amount0_max, amount1_max, amount0_min, amount1_min, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "INSUFFICIENT_INPUT_AMOUNTS")] + unconstrained fn add_liquidity_zero_amount1_max() { + let (mut env, amm_address, _token0_address, _token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let amount0_max: u128 = 1000_Field as u128; + let amount1_max: u128 = 0_Field as u128; + let amount0_min: u128 = 500_Field as u128; + let amount1_min: u128 = 0_Field as u128; + env.call_private(liquidity_provider, amm.add_liquidity(amount0_max, amount1_max, amount0_min, amount1_min, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "TOKEN_IN_IS_INVALID")] + unconstrained fn swap_exact_tokens_invalid_token_in() { + let (mut env, amm_address, _token0_address, token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let swapper: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let invalid_token: AztecAddress = AztecAddress::from_field(999_Field); + let amount_in: u128 = 1000_Field as u128; + let amount_out_min: u128 = 900_Field as u128; + env.call_private(swapper, amm.swap_exact_tokens_for_tokens(invalid_token, token1_address, amount_in, amount_out_min, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "TOKEN_OUT_IS_INVALID")] + unconstrained fn swap_exact_tokens_invalid_token_out() { + let (mut env, amm_address, token0_address, _token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let swapper: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let invalid_token: AztecAddress = AztecAddress::from_field(999_Field); + let amount_in: u128 = 1000_Field as u128; + let amount_out_min: u128 = 900_Field as u128; + env.call_private(swapper, amm.swap_exact_tokens_for_tokens(token0_address, invalid_token, amount_in, amount_out_min, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "SAME_TOKEN_SWAP")] + unconstrained fn swap_exact_tokens_same_tokens() { + let (mut env, amm_address, token0_address, _token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let swapper: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let amount_in: u128 = 1000_Field as u128; + let amount_out_min: u128 = 900_Field as u128; + env.call_private(swapper, amm.swap_exact_tokens_for_tokens(token0_address, token0_address, amount_in, amount_out_min, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "TOKEN_IN_IS_INVALID")] + unconstrained fn swap_tokens_for_exact_invalid_token_in() { + let (mut env, amm_address, _token0_address, token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let swapper: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let invalid_token: AztecAddress = AztecAddress::from_field(999_Field); + let amount_out: u128 = 1000_Field as u128; + let amount_in_max: u128 = 1200_Field as u128; + env.call_private(swapper, amm.swap_tokens_for_exact_tokens(invalid_token, token1_address, amount_out, amount_in_max, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "TOKEN_OUT_IS_INVALID")] + unconstrained fn swap_tokens_for_exact_invalid_token_out() { + let (mut env, amm_address, token0_address, _token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let swapper: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let invalid_token: AztecAddress = AztecAddress::from_field(999_Field); + let amount_out: u128 = 1000_Field as u128; + let amount_in_max: u128 = 1200_Field as u128; + env.call_private(swapper, amm.swap_tokens_for_exact_tokens(token0_address, invalid_token, amount_out, amount_in_max, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "SAME_TOKEN_SWAP")] + unconstrained fn swap_tokens_for_exact_same_tokens() { + let (mut env, amm_address, token0_address, _token1_address, _liquidity_token_address, _minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let swapper: AztecAddress = env.create_contract_account(); + let amm: AMM::AMM = AMM::at(amm_address); + let amount_out: u128 = 1000_Field as u128; + let amount_in_max: u128 = 1200_Field as u128; + env.call_private(swapper, amm.swap_tokens_for_exact_tokens(token0_address, token0_address, amount_out, amount_in_max, AUTHWIT_NONCE)); + } + + #[test(should_fail_with = "INSUFFICIENT_LIQUIDITY_MINTED")] + unconstrained fn add_liquidity_insufficient_liquidity_minted() { + let (mut env, amm_address, token0_address, token1_address, _liquidity_token_address, minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider_1: AztecAddress = env.create_contract_account(); + let liquidity_provider_2: AztecAddress = env.create_contract_account(); + let initial_amount0: u128 = 100000000_Field as u128; + let initial_amount1: u128 = 200000000_Field as u128; + add_liquidity(env, amm_address, token0_address, token1_address, minter, liquidity_provider_1, initial_amount0, initial_amount1, DEFAULT_AMOUNT_0_MIN, DEFAULT_AMOUNT_1_MIN); + let tiny_amount0: u128 = 1_Field as u128; + let tiny_amount1: u128 = 2_Field as u128; + add_liquidity(env, amm_address, token0_address, token1_address, minter, liquidity_provider_2, tiny_amount0, tiny_amount1, DEFAULT_AMOUNT_0_MIN, DEFAULT_AMOUNT_1_MIN); + } + + #[test(should_fail_with = "INSUFFICIENT_0_AMOUNT")] + unconstrained fn remove_liquidity_insufficient_amount0() { + let (mut env, amm_address, token0_address, token1_address, liquidity_token_address, minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider: AztecAddress = env.create_contract_account(); + let amount0: u128 = 1000_Field as u128; + let amount1: u128 = 2000_Field as u128; + add_liquidity(env, amm_address, token0_address, token1_address, minter, liquidity_provider, amount0, amount1, DEFAULT_AMOUNT_0_MIN, DEFAULT_AMOUNT_1_MIN); + let liquidity_to_remove: u128 = AMM::INITIAL_LIQUIDITY / 2_u128; + let amount0_min: u128 = 10000_Field as u128; + let amount1_min: u128 = 800_Field as u128; + remove_liquidity(env, amm_address, liquidity_token_address, liquidity_provider, liquidity_to_remove, amount0_min, amount1_min); + } + + #[test(should_fail_with = "INSUFFICIENT_1_AMOUNT")] + unconstrained fn remove_liquidity_insufficient_amount1() { + let (mut env, amm_address, token0_address, token1_address, liquidity_token_address, minter): (aztec::test::helpers::test_environment::TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) = setup(); + let liquidity_provider: AztecAddress = env.create_contract_account(); + let amount0: u128 = 1000_Field as u128; + let amount1: u128 = 2000_Field as u128; + add_liquidity(env, amm_address, token0_address, token1_address, minter, liquidity_provider, amount0, amount1, DEFAULT_AMOUNT_0_MIN, DEFAULT_AMOUNT_1_MIN); + let liquidity_to_remove: u128 = AMM::INITIAL_LIQUIDITY / 2_u128; + let amount0_min: u128 = 400_Field as u128; + let amount1_min: u128 = 20000_Field as u128; + remove_liquidity(env, amm_address, liquidity_token_address, liquidity_provider, liquidity_to_remove, amount0_min, amount1_min); + } + } + + pub(crate) mod utils { + use crate::AMM; + use aztec::protocol::address::AztecAddress; + use aztec::test::helpers::authwit::add_private_authwit_from_call; + use aztec::test::helpers::test_environment::TestEnvironment; + use token::Token; + + global AUTHWIT_NONCE: Field = 0x01; + + pub(crate) unconstrained fn setup() -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, AztecAddress, AztecAddress) { + let mut env: TestEnvironment = TestEnvironment::new(); + let admin: AztecAddress = env.create_contract_account(); + let token0_initializer: aztec::context::calls::PublicCall<11, 64, ()> = Token::interface().constructor(admin, "Token00000000000000000000000000", "TK00000000000000000000000000000", 18_u8); + let token0_address: AztecAddress = env.deploy("@token_contract/Token").with_public_initializer(admin, token0_initializer); + let token1_initializer: aztec::context::calls::PublicCall<11, 64, ()> = Token::interface().constructor(admin, "Token11111111111111111111111111", "TK11111111111111111111111111111", 18_u8); + let token1_address: AztecAddress = env.deploy("@token_contract/Token").with_public_initializer(admin, token1_initializer); + let liquidity_token_initializer: aztec::context::calls::PublicCall<11, 64, ()> = Token::interface().constructor(admin, "LiquidityToken00000000000000000", "LT00000000000000000000000000000", 18_u8); + let liquidity_token_address: AztecAddress = env.deploy("@token_contract/Token").with_public_initializer(admin, liquidity_token_initializer); + let amm_initializer: aztec::context::calls::PublicCall<11, 3, ()> = AMM::interface().constructor(token0_address, token1_address, liquidity_token_address); + let amm_address: AztecAddress = env.deploy("AMM").with_public_initializer(admin, amm_initializer); + env.call_public(admin, Token::at(liquidity_token_address).set_minter(amm_address, true)); + let minter: AztecAddress = admin; + (env, amm_address, token0_address, token1_address, liquidity_token_address, minter) + } + + pub(crate) unconstrained fn add_liquidity(env: TestEnvironment, amm_address: AztecAddress, token0_address: AztecAddress, token1_address: AztecAddress, minter: AztecAddress, liquidity_provider: AztecAddress, amount0_max: u128, amount1_max: u128, amount0_min: u128, amount1_min: u128) { + let token0: Token::Token = Token::at(token0_address); + let token1: Token::Token = Token::at(token1_address); + let amm: AMM::AMM = AMM::at(amm_address); + env.call_private(minter, token0.mint_to_private(liquidity_provider, amount0_max)); + env.call_private(minter, token1.mint_to_private(liquidity_provider, amount1_max)); + let transfer0_call: aztec::context::calls::PrivateCall<55, 4, uint_note::PartialUintNote> = token0.transfer_to_public_and_prepare_private_balance_increase(liquidity_provider, amm_address, amount0_max, AUTHWIT_NONCE); + add_private_authwit_from_call(env, liquidity_provider, amm_address, transfer0_call); + let transfer1_call: aztec::context::calls::PrivateCall<55, 4, uint_note::PartialUintNote> = token1.transfer_to_public_and_prepare_private_balance_increase(liquidity_provider, amm_address, amount1_max, AUTHWIT_NONCE); + add_private_authwit_from_call(env, liquidity_provider, amm_address, transfer1_call); + env.call_private(liquidity_provider, amm.add_liquidity(amount0_max, amount1_max, amount0_min, amount1_min, AUTHWIT_NONCE)); + } + + pub(crate) unconstrained fn remove_liquidity(env: TestEnvironment, amm_address: AztecAddress, liquidity_token_address: AztecAddress, liquidity_provider: AztecAddress, liquidity_amount: u128, amount0_min: u128, amount1_min: u128) { + let liquidity_token: Token::Token = Token::at(liquidity_token_address); + let amm: AMM::AMM = AMM::at(amm_address); + let transfer_liquidity_call: aztec::context::calls::PrivateCall<18, 4, ()> = liquidity_token.transfer_to_public(liquidity_provider, amm_address, liquidity_amount, AUTHWIT_NONCE); + add_private_authwit_from_call(env, liquidity_provider, amm_address, transfer_liquidity_call); + env.call_private(liquidity_provider, amm.remove_liquidity(liquidity_amount, amount0_min, amount1_min, AUTHWIT_NONCE)); + } + } +} + +// Warning: the generated code has syntax errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap new file mode 100644 index 000000000000..2f36a53d539e --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap @@ -0,0 +1,1655 @@ +--- +source: tests/snapshots.rs +expression: stdout +--- +use aztec::macros::aztec; +use aztec::macros::aztec; + +contract AvmGadgetsTest { + use aztec::macros::functions::external; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call keccak_hash. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn keccak_hash(data: [u8; 10]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call keccak_hash_300. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn keccak_hash_300(data: [u8; 300]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call keccak_hash_1400. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn keccak_hash_1400(data: [u8; 1400]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call keccak_f1600. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn keccak_f1600(data: [u64; 25]) -> [u64; 25]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call poseidon2_hash. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn poseidon2_hash(data: [Field; 10]) -> Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call poseidon2_hash_1000fields. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn poseidon2_hash_1000fields(data: [Field; 1000]) -> Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_10. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_10(data: [u8; 10]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_20. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_20(data: [u8; 20]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_30. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_30(data: [u8; 30]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_40. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_40(data: [u8; 40]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_50. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_50(data: [u8; 50]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_60. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_60(data: [u8; 60]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_70. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_70(data: [u8; 70]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_80. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_80(data: [u8; 80]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_90. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_90(data: [u8; 90]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_100. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_100(data: [u8; 100]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_255. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_255(data: [u8; 255]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_256. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_256(data: [u8; 256]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_511. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_511(data: [u8; 511]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_512. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_512(data: [u8; 512]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_1024. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_1024(data: [u8; 1024]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call sha256_hash_1536. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn sha256_hash_1536(data: [u8; 1536]) -> [u8; 32]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call pedersen_hash. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn pedersen_hash(data: [Field; 10]) -> Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call pedersen_hash_with_index. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn pedersen_hash_with_index(data: [Field; 10]) -> Field; + + /// Unpacks an array into a note corresponding to `note_type_id` and then computes its note hash (non-siloed) and inner nullifier (non-siloed) assuming the note has been inserted into the note hash tree with `note_nonce`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + #[allow(dead_code)] + unconstrained fn _compute_note_hash_and_nullifier(packed_note: BoundedVec, owner: aztec::protocol::address::AztecAddress, storage_slot: Field, note_type_id: Field, contract_address: aztec::protocol::address::AztecAddress, randomness: Field, note_nonce: Field) -> Option { + _compute_note_hash(packed_note, owner, storage_slot, note_type_id, contract_address, randomness).map(|note_hash: Field| -> aztec::messages::discovery::NoteHashAndNullifier { + let siloed_note_hash: Field = aztec::protocol::hash::compute_siloed_note_hash(contract_address, note_hash); + let unique_note_hash: Field = aztec::protocol::hash::compute_unique_note_hash(note_nonce, siloed_note_hash); + let inner_nullifier: Option = _compute_note_nullifier(unique_note_hash, packed_note, owner, storage_slot, note_type_id, contract_address, randomness); + aztec::messages::discovery::NoteHashAndNullifier { note_hash: note_hash, inner_nullifier: inner_nullifier} + }) + } + + /// This contract does not use private notes, so this function should never be called as it will unconditionally fail. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_hash(_packed_note: BoundedVec, _owner: aztec::protocol::address::AztecAddress, _storage_slot: Field, _note_type_id: Field, _contract_address: aztec::protocol::address::AztecAddress, _randomness: Field) -> Option { + panic(f"This contract does not use private notes") + } + + /// This contract does not use private notes, so this function should never be called as it will unconditionally fail. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_nullifier(_unique_note_hash: Field, _packed_note: BoundedVec, _owner: aztec::protocol::address::AztecAddress, _storage_slot: Field, _note_type_id: Field, _contract_address: aztec::protocol::address::AztecAddress, _randomness: Field) -> Option { + panic(f"This contract does not use private notes") + } + + /// Receives offchain messages into this contract's offchain inbox for subsequent processing. + /// + /// Each message is routed to the inbox scoped to its `recipient` field. + /// + /// For more details, see `aztec::messages::processing::offchain::receive`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + unconstrained fn offchain_receive(messages: BoundedVec) { + let address: aztec::protocol::address::AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::processing::offchain::receive(address, messages); + } + + pub struct AvmGadgetsTest { + pub target_contract: aztec::protocol::address::AztecAddress, + } + + impl AvmGadgetsTest { + pub fn at(addr: aztec::protocol::address::AztecAddress) -> Self { + Self { target_contract: addr} + } + + pub fn interface() -> Self { + Self { target_contract: aztec::protocol::address::AztecAddress::zero()} + } + + pub fn sha256_hash_1536(self, data: [u8; 1536]) -> aztec::context::calls::PublicCall<16, 1536, [u8; 32]> { + let serialized_params: [Field; 1536] = <[u8; 1536] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(373006257_Field); + aztec::context::calls::PublicCall::<16, 1536, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_1536", serialized_params) + } + + pub fn pedersen_hash_with_index(self, data: [Field; 10]) -> aztec::context::calls::PublicCall<24, 10, Field> { + let serialized_params: [Field; 10] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3265405934_Field); + aztec::context::calls::PublicCall::<24, 10, Field>::new(self.target_contract, selector, "pedersen_hash_with_index", serialized_params) + } + + pub fn keccak_hash(self, data: [u8; 10]) -> aztec::context::calls::PublicCall<11, 10, [u8; 32]> { + let serialized_params: [Field; 10] = <[u8; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1352369823_Field); + aztec::context::calls::PublicCall::<11, 10, [u8; 32]>::new(self.target_contract, selector, "keccak_hash", serialized_params) + } + + pub fn sha256_hash_511(self, data: [u8; 511]) -> aztec::context::calls::PublicCall<15, 511, [u8; 32]> { + let serialized_params: [Field; 511] = <[u8; 511] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(797967809_Field); + aztec::context::calls::PublicCall::<15, 511, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_511", serialized_params) + } + + pub fn sha256_hash_100(self, data: [u8; 100]) -> aztec::context::calls::PublicCall<15, 100, [u8; 32]> { + let serialized_params: [Field; 100] = <[u8; 100] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2074027672_Field); + aztec::context::calls::PublicCall::<15, 100, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_100", serialized_params) + } + + pub fn sha256_hash_80(self, data: [u8; 80]) -> aztec::context::calls::PublicCall<14, 80, [u8; 32]> { + let serialized_params: [Field; 80] = <[u8; 80] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4268069756_Field); + aztec::context::calls::PublicCall::<14, 80, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_80", serialized_params) + } + + pub fn pedersen_hash(self, data: [Field; 10]) -> aztec::context::calls::PublicCall<13, 10, Field> { + let serialized_params: [Field; 10] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2669406607_Field); + aztec::context::calls::PublicCall::<13, 10, Field>::new(self.target_contract, selector, "pedersen_hash", serialized_params) + } + + pub fn sha256_hash_20(self, data: [u8; 20]) -> aztec::context::calls::PublicCall<14, 20, [u8; 32]> { + let serialized_params: [Field; 20] = <[u8; 20] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2926274626_Field); + aztec::context::calls::PublicCall::<14, 20, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_20", serialized_params) + } + + pub fn poseidon2_hash(self, data: [Field; 10]) -> aztec::context::calls::PublicCall<14, 10, Field> { + let serialized_params: [Field; 10] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3724082008_Field); + aztec::context::calls::PublicCall::<14, 10, Field>::new(self.target_contract, selector, "poseidon2_hash", serialized_params) + } + + pub fn sha256_hash_512(self, data: [u8; 512]) -> aztec::context::calls::PublicCall<15, 512, [u8; 32]> { + let serialized_params: [Field; 512] = <[u8; 512] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2560938307_Field); + aztec::context::calls::PublicCall::<15, 512, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_512", serialized_params) + } + + pub fn keccak_f1600(self, data: [u64; 25]) -> aztec::context::calls::PublicCall<12, 25, [u64; 25]> { + let serialized_params: [Field; 25] = <[u64; 25] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1867977279_Field); + aztec::context::calls::PublicCall::<12, 25, [u64; 25]>::new(self.target_contract, selector, "keccak_f1600", serialized_params) + } + + pub fn sha256_hash_30(self, data: [u8; 30]) -> aztec::context::calls::PublicCall<14, 30, [u8; 32]> { + let serialized_params: [Field; 30] = <[u8; 30] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3609677267_Field); + aztec::context::calls::PublicCall::<14, 30, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_30", serialized_params) + } + + pub fn sha256_hash_50(self, data: [u8; 50]) -> aztec::context::calls::PublicCall<14, 50, [u8; 32]> { + let serialized_params: [Field; 50] = <[u8; 50] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(256881939_Field); + aztec::context::calls::PublicCall::<14, 50, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_50", serialized_params) + } + + pub fn sha256_hash_60(self, data: [u8; 60]) -> aztec::context::calls::PublicCall<14, 60, [u8; 32]> { + let serialized_params: [Field; 60] = <[u8; 60] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2495458303_Field); + aztec::context::calls::PublicCall::<14, 60, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_60", serialized_params) + } + + pub fn poseidon2_hash_1000fields(self, data: [Field; 1000]) -> aztec::context::calls::PublicCall<25, 1000, Field> { + let serialized_params: [Field; 1000] = <[Field; 1000] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(278602445_Field); + aztec::context::calls::PublicCall::<25, 1000, Field>::new(self.target_contract, selector, "poseidon2_hash_1000fields", serialized_params) + } + + pub fn sha256_hash_70(self, data: [u8; 70]) -> aztec::context::calls::PublicCall<14, 70, [u8; 32]> { + let serialized_params: [Field; 70] = <[u8; 70] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2200074453_Field); + aztec::context::calls::PublicCall::<14, 70, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_70", serialized_params) + } + + pub fn sha256_hash_90(self, data: [u8; 90]) -> aztec::context::calls::PublicCall<14, 90, [u8; 32]> { + let serialized_params: [Field; 90] = <[u8; 90] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(799349905_Field); + aztec::context::calls::PublicCall::<14, 90, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_90", serialized_params) + } + + pub fn sha256_hash_40(self, data: [u8; 40]) -> aztec::context::calls::PublicCall<14, 40, [u8; 32]> { + let serialized_params: [Field; 40] = <[u8; 40] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(900925045_Field); + aztec::context::calls::PublicCall::<14, 40, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_40", serialized_params) + } + + pub fn sha256_hash_10(self, data: [u8; 10]) -> aztec::context::calls::PublicCall<14, 10, [u8; 32]> { + let serialized_params: [Field; 10] = <[u8; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3545543018_Field); + aztec::context::calls::PublicCall::<14, 10, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_10", serialized_params) + } + + pub fn sha256_hash_1024(self, data: [u8; 1024]) -> aztec::context::calls::PublicCall<16, 1024, [u8; 32]> { + let serialized_params: [Field; 1024] = <[u8; 1024] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2235915052_Field); + aztec::context::calls::PublicCall::<16, 1024, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_1024", serialized_params) + } + + pub fn sha256_hash_255(self, data: [u8; 255]) -> aztec::context::calls::PublicCall<15, 255, [u8; 32]> { + let serialized_params: [Field; 255] = <[u8; 255] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3548859530_Field); + aztec::context::calls::PublicCall::<15, 255, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_255", serialized_params) + } + + pub fn sha256_hash_256(self, data: [u8; 256]) -> aztec::context::calls::PublicCall<15, 256, [u8; 32]> { + let serialized_params: [Field; 256] = <[u8; 256] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3409224101_Field); + aztec::context::calls::PublicCall::<15, 256, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_256", serialized_params) + } + + pub fn keccak_hash_1400(self, data: [u8; 1400]) -> aztec::context::calls::PublicCall<16, 1400, [u8; 32]> { + let serialized_params: [Field; 1400] = <[u8; 1400] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(372001522_Field); + aztec::context::calls::PublicCall::<16, 1400, [u8; 32]>::new(self.target_contract, selector, "keccak_hash_1400", serialized_params) + } + + pub fn keccak_hash_300(self, data: [u8; 300]) -> aztec::context::calls::PublicCall<15, 300, [u8; 32]> { + let serialized_params: [Field; 300] = <[u8; 300] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3065624740_Field); + aztec::context::calls::PublicCall::<15, 300, [u8; 32]>::new(self.target_contract, selector, "keccak_hash_300", serialized_params) + } + + pub fn offchain_receive(self, messages: BoundedVec) -> aztec::context::calls::UtilityCall<16, 321, ()> { + let serialized_params: [Field; 321] = as aztec::protocol::traits::Serialize>::serialize(messages); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1396850735_Field); + aztec::context::calls::UtilityCall::<16, 321, ()>::new(self.target_contract, selector, "offchain_receive", serialized_params) + } + } + + #[contract_library_method] + pub fn at(addr: aztec::protocol::address::AztecAddress) -> AvmGadgetsTest { + AvmGadgetsTest { target_contract: addr} + } + + #[contract_library_method] + pub fn interface() -> AvmGadgetsTest { + AvmGadgetsTest { target_contract: aztec::protocol::address::AztecAddress::zero()} + } + + pub struct sync_state_parameters { + pub scope: aztec::protocol::address::AztecAddress, + } + + #[abi(functions)] + pub struct sync_state_abi { + parameters: sync_state_parameters, + } + + unconstrained fn sync_state(scope: aztec::protocol::address::AztecAddress) { + let address: aztec::protocol::address::AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + } + + pub struct offchain_receive_parameters { + pub messages: BoundedVec, + } + + #[abi(functions)] + pub struct offchain_receive_abi { + parameters: offchain_receive_parameters, + } + + pub struct CallSelf { + pub address: aztec::protocol::address::AztecAddress, + pub context: Context, + } + + impl CallSelf { + pub fn sha256_hash_1536(self, data: [u8; 1536]) -> [u8; 32] { + let serialized_params: [Field; 1536 * 1] = <[u8; 1536] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(373006257_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 1536 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_1536", serialized_params).call(self.context) + } + } + + pub fn pedersen_hash_with_index(self, data: [Field; 10]) -> Field { + let serialized_params: [Field; 10 * 1] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3265405934_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<24, 10 * 1, Field>::new(self.address, selector, "pedersen_hash_with_index", serialized_params).call(self.context) + } + } + + pub fn keccak_hash(self, data: [u8; 10]) -> [u8; 32] { + let serialized_params: [Field; 10 * 1] = <[u8; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1352369823_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<11, 10 * 1, [u8; 32]>::new(self.address, selector, "keccak_hash", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_511(self, data: [u8; 511]) -> [u8; 32] { + let serialized_params: [Field; 511 * 1] = <[u8; 511] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(797967809_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 511 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_511", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_100(self, data: [u8; 100]) -> [u8; 32] { + let serialized_params: [Field; 100 * 1] = <[u8; 100] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2074027672_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 100 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_100", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_80(self, data: [u8; 80]) -> [u8; 32] { + let serialized_params: [Field; 80 * 1] = <[u8; 80] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4268069756_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 80 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_80", serialized_params).call(self.context) + } + } + + pub fn pedersen_hash(self, data: [Field; 10]) -> Field { + let serialized_params: [Field; 10 * 1] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2669406607_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 10 * 1, Field>::new(self.address, selector, "pedersen_hash", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_20(self, data: [u8; 20]) -> [u8; 32] { + let serialized_params: [Field; 20 * 1] = <[u8; 20] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2926274626_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 20 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_20", serialized_params).call(self.context) + } + } + + pub fn poseidon2_hash(self, data: [Field; 10]) -> Field { + let serialized_params: [Field; 10 * 1] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3724082008_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 10 * 1, Field>::new(self.address, selector, "poseidon2_hash", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_512(self, data: [u8; 512]) -> [u8; 32] { + let serialized_params: [Field; 512 * 1] = <[u8; 512] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2560938307_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 512 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_512", serialized_params).call(self.context) + } + } + + pub fn keccak_f1600(self, data: [u64; 25]) -> [u64; 25] { + let serialized_params: [Field; 25 * 1] = <[u64; 25] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1867977279_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<12, 25 * 1, [u64; 25]>::new(self.address, selector, "keccak_f1600", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_30(self, data: [u8; 30]) -> [u8; 32] { + let serialized_params: [Field; 30 * 1] = <[u8; 30] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3609677267_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 30 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_30", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_50(self, data: [u8; 50]) -> [u8; 32] { + let serialized_params: [Field; 50 * 1] = <[u8; 50] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(256881939_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 50 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_50", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_60(self, data: [u8; 60]) -> [u8; 32] { + let serialized_params: [Field; 60 * 1] = <[u8; 60] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2495458303_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 60 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_60", serialized_params).call(self.context) + } + } + + pub fn poseidon2_hash_1000fields(self, data: [Field; 1000]) -> Field { + let serialized_params: [Field; 1000 * 1] = <[Field; 1000] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(278602445_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<25, 1000 * 1, Field>::new(self.address, selector, "poseidon2_hash_1000fields", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_70(self, data: [u8; 70]) -> [u8; 32] { + let serialized_params: [Field; 70 * 1] = <[u8; 70] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2200074453_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 70 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_70", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_90(self, data: [u8; 90]) -> [u8; 32] { + let serialized_params: [Field; 90 * 1] = <[u8; 90] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(799349905_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 90 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_90", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_40(self, data: [u8; 40]) -> [u8; 32] { + let serialized_params: [Field; 40 * 1] = <[u8; 40] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(900925045_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 40 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_40", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_10(self, data: [u8; 10]) -> [u8; 32] { + let serialized_params: [Field; 10 * 1] = <[u8; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3545543018_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 10 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_10", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_1024(self, data: [u8; 1024]) -> [u8; 32] { + let serialized_params: [Field; 1024 * 1] = <[u8; 1024] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2235915052_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 1024 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_1024", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_255(self, data: [u8; 255]) -> [u8; 32] { + let serialized_params: [Field; 255 * 1] = <[u8; 255] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3548859530_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 255 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_255", serialized_params).call(self.context) + } + } + + pub fn sha256_hash_256(self, data: [u8; 256]) -> [u8; 32] { + let serialized_params: [Field; 256 * 1] = <[u8; 256] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3409224101_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 256 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_256", serialized_params).call(self.context) + } + } + + pub fn keccak_hash_1400(self, data: [u8; 1400]) -> [u8; 32] { + let serialized_params: [Field; 1400 * 1] = <[u8; 1400] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(372001522_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 1400 * 1, [u8; 32]>::new(self.address, selector, "keccak_hash_1400", serialized_params).call(self.context) + } + } + + pub fn keccak_hash_300(self, data: [u8; 300]) -> [u8; 32] { + let serialized_params: [Field; 300 * 1] = <[u8; 300] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3065624740_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 300 * 1, [u8; 32]>::new(self.address, selector, "keccak_hash_300", serialized_params).call(self.context) + } + } + } + + pub struct CallSelfStatic { + pub address: aztec::protocol::address::AztecAddress, + pub context: Context, + } + + pub struct EnqueueSelf { + pub address: aztec::protocol::address::AztecAddress, + pub context: Context, + } + + impl EnqueueSelf<&mut aztec::context::PrivateContext> { + pub fn sha256_hash_1536(self, data: [u8; 1536]) { + let serialized_params: [Field; 1536 * 1] = <[u8; 1536] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(373006257_Field); + let calldata: [Field; 1 + (1536 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn pedersen_hash_with_index(self, data: [Field; 10]) { + let serialized_params: [Field; 10 * 1] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3265405934_Field); + let calldata: [Field; 1 + (10 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn keccak_hash(self, data: [u8; 10]) { + let serialized_params: [Field; 10 * 1] = <[u8; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1352369823_Field); + let calldata: [Field; 1 + (10 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_511(self, data: [u8; 511]) { + let serialized_params: [Field; 511 * 1] = <[u8; 511] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(797967809_Field); + let calldata: [Field; 1 + (511 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_100(self, data: [u8; 100]) { + let serialized_params: [Field; 100 * 1] = <[u8; 100] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2074027672_Field); + let calldata: [Field; 1 + (100 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_80(self, data: [u8; 80]) { + let serialized_params: [Field; 80 * 1] = <[u8; 80] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4268069756_Field); + let calldata: [Field; 1 + (80 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn pedersen_hash(self, data: [Field; 10]) { + let serialized_params: [Field; 10 * 1] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2669406607_Field); + let calldata: [Field; 1 + (10 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_20(self, data: [u8; 20]) { + let serialized_params: [Field; 20 * 1] = <[u8; 20] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2926274626_Field); + let calldata: [Field; 1 + (20 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn poseidon2_hash(self, data: [Field; 10]) { + let serialized_params: [Field; 10 * 1] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3724082008_Field); + let calldata: [Field; 1 + (10 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_512(self, data: [u8; 512]) { + let serialized_params: [Field; 512 * 1] = <[u8; 512] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2560938307_Field); + let calldata: [Field; 1 + (512 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn keccak_f1600(self, data: [u64; 25]) { + let serialized_params: [Field; 25 * 1] = <[u64; 25] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1867977279_Field); + let calldata: [Field; 1 + (25 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_30(self, data: [u8; 30]) { + let serialized_params: [Field; 30 * 1] = <[u8; 30] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3609677267_Field); + let calldata: [Field; 1 + (30 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_50(self, data: [u8; 50]) { + let serialized_params: [Field; 50 * 1] = <[u8; 50] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(256881939_Field); + let calldata: [Field; 1 + (50 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_60(self, data: [u8; 60]) { + let serialized_params: [Field; 60 * 1] = <[u8; 60] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2495458303_Field); + let calldata: [Field; 1 + (60 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn poseidon2_hash_1000fields(self, data: [Field; 1000]) { + let serialized_params: [Field; 1000 * 1] = <[Field; 1000] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(278602445_Field); + let calldata: [Field; 1 + (1000 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_70(self, data: [u8; 70]) { + let serialized_params: [Field; 70 * 1] = <[u8; 70] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2200074453_Field); + let calldata: [Field; 1 + (70 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_90(self, data: [u8; 90]) { + let serialized_params: [Field; 90 * 1] = <[u8; 90] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(799349905_Field); + let calldata: [Field; 1 + (90 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_40(self, data: [u8; 40]) { + let serialized_params: [Field; 40 * 1] = <[u8; 40] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(900925045_Field); + let calldata: [Field; 1 + (40 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_10(self, data: [u8; 10]) { + let serialized_params: [Field; 10 * 1] = <[u8; 10] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3545543018_Field); + let calldata: [Field; 1 + (10 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_1024(self, data: [u8; 1024]) { + let serialized_params: [Field; 1024 * 1] = <[u8; 1024] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2235915052_Field); + let calldata: [Field; 1 + (1024 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_255(self, data: [u8; 255]) { + let serialized_params: [Field; 255 * 1] = <[u8; 255] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3548859530_Field); + let calldata: [Field; 1 + (255 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn sha256_hash_256(self, data: [u8; 256]) { + let serialized_params: [Field; 256 * 1] = <[u8; 256] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3409224101_Field); + let calldata: [Field; 1 + (256 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn keccak_hash_1400(self, data: [u8; 1400]) { + let serialized_params: [Field; 1400 * 1] = <[u8; 1400] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(372001522_Field); + let calldata: [Field; 1 + (1400 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn keccak_hash_300(self, data: [u8; 300]) { + let serialized_params: [Field; 300 * 1] = <[u8; 300] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3065624740_Field); + let calldata: [Field; 1 + (300 * 1)] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + } + + pub struct EnqueueSelfStatic { + pub address: aztec::protocol::address::AztecAddress, + pub context: Context, + } + + pub struct CallSelfUtility { + pub address: aztec::protocol::address::AztecAddress, + } + + pub struct CallInternal { + pub context: Context, + } + + pub unconstrained fn public_dispatch(selector: Field) { + if selector == 1352369823_Field { + let input_calldata: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 10] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<10 * 1> = aztec::protocol::utils::reader::Reader::<10 * 1>::new(input_calldata); + let arg0: [u8; 10] = <[u8; 10] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__keccak_hash(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3065624740_Field { + let input_calldata: [Field; 300 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 300] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<300 * 1> = aztec::protocol::utils::reader::Reader::<300 * 1>::new(input_calldata); + let arg0: [u8; 300] = <[u8; 300] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__keccak_hash_300(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 372001522_Field { + let input_calldata: [Field; 1400 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 1400] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<1400 * 1> = aztec::protocol::utils::reader::Reader::<1400 * 1>::new(input_calldata); + let arg0: [u8; 1400] = <[u8; 1400] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__keccak_hash_1400(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1867977279_Field { + let input_calldata: [Field; 25 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u64; 25] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<25 * 1> = aztec::protocol::utils::reader::Reader::<25 * 1>::new(input_calldata); + let arg0: [u64; 25] = <[u64; 25] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 25 * 1] = <[u64; 25] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__keccak_f1600(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3724082008_Field { + let input_calldata: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 10] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<10 * 1> = aztec::protocol::utils::reader::Reader::<10 * 1>::new(input_calldata); + let arg0: [Field; 10] = <[Field; 10] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__poseidon2_hash(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 278602445_Field { + let input_calldata: [Field; 1000 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 1000] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<1000 * 1> = aztec::protocol::utils::reader::Reader::<1000 * 1>::new(input_calldata); + let arg0: [Field; 1000] = <[Field; 1000] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__poseidon2_hash_1000fields(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3545543018_Field { + let input_calldata: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 10] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<10 * 1> = aztec::protocol::utils::reader::Reader::<10 * 1>::new(input_calldata); + let arg0: [u8; 10] = <[u8; 10] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_10(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2926274626_Field { + let input_calldata: [Field; 20 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 20] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<20 * 1> = aztec::protocol::utils::reader::Reader::<20 * 1>::new(input_calldata); + let arg0: [u8; 20] = <[u8; 20] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_20(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3609677267_Field { + let input_calldata: [Field; 30 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 30] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<30 * 1> = aztec::protocol::utils::reader::Reader::<30 * 1>::new(input_calldata); + let arg0: [u8; 30] = <[u8; 30] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_30(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 900925045_Field { + let input_calldata: [Field; 40 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 40] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<40 * 1> = aztec::protocol::utils::reader::Reader::<40 * 1>::new(input_calldata); + let arg0: [u8; 40] = <[u8; 40] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_40(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 256881939_Field { + let input_calldata: [Field; 50 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 50] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<50 * 1> = aztec::protocol::utils::reader::Reader::<50 * 1>::new(input_calldata); + let arg0: [u8; 50] = <[u8; 50] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_50(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2495458303_Field { + let input_calldata: [Field; 60 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 60] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<60 * 1> = aztec::protocol::utils::reader::Reader::<60 * 1>::new(input_calldata); + let arg0: [u8; 60] = <[u8; 60] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_60(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2200074453_Field { + let input_calldata: [Field; 70 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 70] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<70 * 1> = aztec::protocol::utils::reader::Reader::<70 * 1>::new(input_calldata); + let arg0: [u8; 70] = <[u8; 70] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_70(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 4268069756_Field { + let input_calldata: [Field; 80 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 80] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<80 * 1> = aztec::protocol::utils::reader::Reader::<80 * 1>::new(input_calldata); + let arg0: [u8; 80] = <[u8; 80] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_80(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 799349905_Field { + let input_calldata: [Field; 90 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 90] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<90 * 1> = aztec::protocol::utils::reader::Reader::<90 * 1>::new(input_calldata); + let arg0: [u8; 90] = <[u8; 90] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_90(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2074027672_Field { + let input_calldata: [Field; 100 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 100] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<100 * 1> = aztec::protocol::utils::reader::Reader::<100 * 1>::new(input_calldata); + let arg0: [u8; 100] = <[u8; 100] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_100(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3548859530_Field { + let input_calldata: [Field; 255 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 255] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<255 * 1> = aztec::protocol::utils::reader::Reader::<255 * 1>::new(input_calldata); + let arg0: [u8; 255] = <[u8; 255] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_255(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3409224101_Field { + let input_calldata: [Field; 256 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 256] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<256 * 1> = aztec::protocol::utils::reader::Reader::<256 * 1>::new(input_calldata); + let arg0: [u8; 256] = <[u8; 256] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_256(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 797967809_Field { + let input_calldata: [Field; 511 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 511] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<511 * 1> = aztec::protocol::utils::reader::Reader::<511 * 1>::new(input_calldata); + let arg0: [u8; 511] = <[u8; 511] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_511(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2560938307_Field { + let input_calldata: [Field; 512 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 512] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<512 * 1> = aztec::protocol::utils::reader::Reader::<512 * 1>::new(input_calldata); + let arg0: [u8; 512] = <[u8; 512] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_512(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2235915052_Field { + let input_calldata: [Field; 1024 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 1024] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<1024 * 1> = aztec::protocol::utils::reader::Reader::<1024 * 1>::new(input_calldata); + let arg0: [u8; 1024] = <[u8; 1024] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_1024(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 373006257_Field { + let input_calldata: [Field; 1536 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 1536] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<1536 * 1> = aztec::protocol::utils::reader::Reader::<1536 * 1>::new(input_calldata); + let arg0: [u8; 1536] = <[u8; 1536] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__sha256_hash_1536(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2669406607_Field { + let input_calldata: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 10] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<10 * 1> = aztec::protocol::utils::reader::Reader::<10 * 1>::new(input_calldata); + let arg0: [Field; 10] = <[Field; 10] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__pedersen_hash(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3265405934_Field { + let input_calldata: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 10] as aztec::protocol::traits::Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<10 * 1> = aztec::protocol::utils::reader::Reader::<10 * 1>::new(input_calldata); + let arg0: [Field; 10] = <[Field; 10] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__pedersen_hash_with_index(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + panic(f"Unknown selector {selector}") + } + + pub struct keccak_f1600_parameters { + pub data: [u64; 25], + } + + pub struct keccak_hash_1400_parameters { + pub data: [u8; 1400], + } + + pub struct keccak_hash_300_parameters { + pub data: [u8; 300], + } + + pub struct keccak_hash_parameters { + pub data: [u8; 10], + } + + pub struct pedersen_hash_parameters { + pub data: [Field; 10], + } + + pub struct pedersen_hash_with_index_parameters { + pub data: [Field; 10], + } + + pub struct poseidon2_hash_1000fields_parameters { + pub data: [Field; 1000], + } + + pub struct poseidon2_hash_parameters { + pub data: [Field; 10], + } + + pub struct sha256_hash_100_parameters { + pub data: [u8; 100], + } + + pub struct sha256_hash_1024_parameters { + pub data: [u8; 1024], + } + + pub struct sha256_hash_10_parameters { + pub data: [u8; 10], + } + + pub struct sha256_hash_1536_parameters { + pub data: [u8; 1536], + } + + pub struct sha256_hash_20_parameters { + pub data: [u8; 20], + } + + pub struct sha256_hash_255_parameters { + pub data: [u8; 255], + } + + pub struct sha256_hash_256_parameters { + pub data: [u8; 256], + } + + pub struct sha256_hash_30_parameters { + pub data: [u8; 30], + } + + pub struct sha256_hash_40_parameters { + pub data: [u8; 40], + } + + pub struct sha256_hash_50_parameters { + pub data: [u8; 50], + } + + pub struct sha256_hash_511_parameters { + pub data: [u8; 511], + } + + pub struct sha256_hash_512_parameters { + pub data: [u8; 512], + } + + pub struct sha256_hash_60_parameters { + pub data: [u8; 60], + } + + pub struct sha256_hash_70_parameters { + pub data: [u8; 70], + } + + pub struct sha256_hash_80_parameters { + pub data: [u8; 80], + } + + pub struct sha256_hash_90_parameters { + pub data: [u8; 90], + } + + #[abi(functions)] + pub struct keccak_f1600_abi { + parameters: keccak_f1600_parameters, + return_type: [u64; 25], + } + + #[abi(functions)] + pub struct keccak_hash_1400_abi { + parameters: keccak_hash_1400_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct keccak_hash_300_abi { + parameters: keccak_hash_300_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct keccak_hash_abi { + parameters: keccak_hash_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct pedersen_hash_abi { + parameters: pedersen_hash_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct pedersen_hash_with_index_abi { + parameters: pedersen_hash_with_index_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct poseidon2_hash_1000fields_abi { + parameters: poseidon2_hash_1000fields_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct poseidon2_hash_abi { + parameters: poseidon2_hash_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct sha256_hash_100_abi { + parameters: sha256_hash_100_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_1024_abi { + parameters: sha256_hash_1024_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_10_abi { + parameters: sha256_hash_10_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_1536_abi { + parameters: sha256_hash_1536_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_20_abi { + parameters: sha256_hash_20_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_255_abi { + parameters: sha256_hash_255_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_256_abi { + parameters: sha256_hash_256_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_30_abi { + parameters: sha256_hash_30_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_40_abi { + parameters: sha256_hash_40_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_50_abi { + parameters: sha256_hash_50_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_511_abi { + parameters: sha256_hash_511_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_512_abi { + parameters: sha256_hash_512_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_60_abi { + parameters: sha256_hash_60_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_70_abi { + parameters: sha256_hash_70_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_80_abi { + parameters: sha256_hash_80_parameters, + return_type: [u8; 32], + } + + #[abi(functions)] + pub struct sha256_hash_90_abi { + parameters: sha256_hash_90_parameters, + return_type: [u8; 32], + } + + unconstrained fn __aztec_nr_internals__keccak_f1600(data: [u64; 25]) -> pub [u64; 25] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 25 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u64; 25] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + std::hash::keccakf1600(data) + } + } + + unconstrained fn __aztec_nr_internals__keccak_hash(data: [u8; 10]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 10] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + keccak256::keccak256(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__keccak_hash_1400(data: [u8; 1400]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1400 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 1400] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + keccak256::keccak256(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__keccak_hash_300(data: [u8; 300]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 300 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 300] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + keccak256::keccak256(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__pedersen_hash(data: [Field; 10]) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 10] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + std::hash::pedersen_hash(data) + } + } + + unconstrained fn __aztec_nr_internals__pedersen_hash_with_index(data: [Field; 10]) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 10] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + std::hash::pedersen_hash_with_separator(data, 20_u32) + } + } + + unconstrained fn __aztec_nr_internals__poseidon2_hash(data: [Field; 10]) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 10] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + poseidon::poseidon2::Poseidon2::hash(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__poseidon2_hash_1000fields(data: [Field; 1000]) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1000 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 1000] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + poseidon::poseidon2::Poseidon2::hash(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_10(data: [u8; 10]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 10 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 10] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_100(data: [u8; 100]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 100 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 100] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_1024(data: [u8; 1024]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1024 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 1024] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_1536(data: [u8; 1536]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1536 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 1536] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_20(data: [u8; 20]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 20 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 20] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_255(data: [u8; 255]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 255 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 255] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_256(data: [u8; 256]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 256 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 256] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_30(data: [u8; 30]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 30 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 30] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_40(data: [u8; 40]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 40 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 40] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_50(data: [u8; 50]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 50 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 50] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_511(data: [u8; 511]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 511 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 511] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_512(data: [u8; 512]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 512 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 512] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_60(data: [u8; 60]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 60 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 60] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_70(data: [u8; 70]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 70 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 70] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_80(data: [u8; 80]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 80 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 80] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } + + unconstrained fn __aztec_nr_internals__sha256_hash_90(data: [u8; 90]) -> pub [u8; 32] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 90 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 90] as aztec::protocol::traits::Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + sha256::sha256_var(data, data.len()) + } + } +} + +// Warning: the generated code has syntax errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap new file mode 100644 index 000000000000..7b88b9531a0c --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap @@ -0,0 +1,7788 @@ +--- +source: tests/snapshots.rs +expression: stdout +--- +use aztec::macros::aztec; +use aztec::macros::aztec; + +mod fake_avm_oracle { + use aztec::protocol::address::AztecAddress; + + pub unconstrained fn call(l2_gas_allocation: u32, da_gas_allocation: u32, address: AztecAddress, args: [Field; N]) { + call_opcode(l2_gas_allocation, da_gas_allocation, address, N, args) + } + + pub unconstrained fn success_copy() -> bool { + success_copy_opcode() + } + + pub unconstrained fn returndata_size() -> u32 { + returndata_size_opcode() + } + + pub unconstrained fn returndata_copy(rdoffset: u32, copy_size: u32) -> [Field] { + returndata_copy_opcode(rdoffset, copy_size) + } + + pub unconstrained fn avm_return(returndata: [Field]) { + return_opcode(returndata) + } + + pub unconstrained fn revert(revertdata: [Field]) { + revert_opcode(revertdata) + } + + #[oracle(aztec_avm_call)] + unconstrained fn call_opcode(l2_gas_allocation: u32, da_gas_allocation: u32, address: AztecAddress, length: u32, args: [Field; N]) {} + + #[oracle(aztec_avm_successCopy)] + unconstrained fn success_copy_opcode() -> bool {} + + #[oracle(aztec_avm_returndataSize)] + unconstrained fn returndata_size_opcode() -> u32 {} + + #[oracle(aztec_avm_returndataCopy)] + unconstrained fn returndata_copy_opcode(rdoffset: u32, copy_size: u32) -> [Field] {} + + #[oracle(aztec_avm_return)] + unconstrained fn return_opcode(returndata: [Field]) {} + + #[oracle(aztec_avm_revert)] + unconstrained fn revert_opcode(revertdata: [Field]) {} +} + +pub contract AvmTest { + use crate::note::Note; + use crate::fake_avm_oracle::avm_return; + use crate::fake_avm_oracle::call; + use crate::fake_avm_oracle::returndata_copy; + use crate::fake_avm_oracle::returndata_size; + use crate::fake_avm_oracle::revert; + use crate::fake_avm_oracle::success_copy; + use aztec::context::gas::GasOpts; + use aztec::macros::functions::external; + use aztec::macros::functions::view; + use aztec::macros::storage::storage; + use aztec::oracle::get_contract_instance::get_contract_instance_class_id_avm; + use aztec::oracle::get_contract_instance::get_contract_instance_deployer_avm; + use aztec::oracle::get_contract_instance::get_contract_instance_initialization_hash_avm; + use aztec::protocol::abis::function_selector::FunctionSelector; + use aztec::protocol::address::AztecAddress; + use aztec::protocol::address::EthAddress; + use aztec::protocol::point::Point; + use std::embedded_curve_ops::EmbeddedCurveScalar as Scalar; + use aztec::protocol::constants::CANONICAL_AUTH_REGISTRY_ADDRESS; + use aztec::protocol::constants::CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS; + use aztec::protocol::constants::FEE_JUICE_ADDRESS; + use aztec::protocol::constants::GRUMPKIN_ONE_X; + use aztec::protocol::constants::GRUMPKIN_ONE_Y; + use aztec::protocol::constants::MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS; + use aztec::protocol::contract_class_id::ContractClassId; + use aztec::protocol::storage::map::derive_storage_slot_in_map; + use aztec::protocol::traits::Empty; + use aztec::protocol::traits::FromField; + use aztec::protocol::traits::ToField; + use aztec::protocol::traits::Serialize; + use aztec::state_vars::Map; + use aztec::state_vars::PublicMutable; + use aztec::state_vars::StateVariable; + use compressed_string::CompressedString; + use std::embedded_curve_ops::multi_scalar_mul; + use auth_contract::AuthRegistry; + use aztec::context::PublicContext; + use fee_juice::FeeJuice; + use instance_contract::ContractInstanceRegistry; + use std::ops::Add; + + global big_field_128_bits: Field = 0x1234567890abcdef1234567890abcdef; + + global big_field_136_bits: Field = 0x991234567890abcdef1234567890abcdef; + + global big_field_254_bits: Field = 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef; + + struct Storage { + single: PublicMutable, + list: PublicMutable, + map: Map, Context>, + } + + impl Storage { + fn init(context: Context) -> Self { + Self { single: as StateVariable<1, Context>>::new(context, 1_Field), list: as StateVariable<2, Context>>::new(context, 2_Field), map: , Context> as StateVariable<1, Context>>::new(context, 4_Field)} + } + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_storage_single. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_storage_single(a: Field); + + #[contract_library_method] + fn _set_storage_single(storage: Storage, a: Field) { + storage.single.write(a); + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call read_storage_single. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn read_storage_single() -> Field; + + #[contract_library_method] + fn _read_storage_single(storage: Storage) -> Field { + storage.single.read() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call read_assert_storage_single. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn read_assert_storage_single(a: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_read_storage_single. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_read_storage_single(a: Field) -> pub Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_storage_list. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_storage_list(a: Field, b: Field); + + #[contract_library_method] + fn _set_storage_list(storage: Storage, a: Field, b: Field) { + storage.list.write(Note { a: a, b: b}); + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call read_storage_list. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn read_storage_list() -> [Field; 2]; + + #[contract_library_method] + fn _read_storage_list(storage: Storage) -> [Field; 2] { + let note: Note = storage.list.read(); + note.serialize() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_storage_map. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_storage_map(to: AztecAddress, amount: u32) -> Field; + + #[contract_library_method] + fn _set_storage_map(storage: Storage, to: AztecAddress, amount: u32) -> Field { + storage.map.at(to).write(amount); + derive_storage_slot_in_map(storage.map.get_storage_slot(), to) + } + + #[abi(storage)] + pub global STORAGE_LAYOUT_AvmTest: StorageLayout<7> = StorageLayout::<7> { + contract_name: "AvmTest", + fields: StorageLayoutFields { + single: aztec::state_vars::Storable { + slot: 0x01, + }, + list: aztec::state_vars::Storable { + slot: 0x02, + }, + map: aztec::state_vars::Storable { + slot: 0x04, + }, + }, + }; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call add_storage_map. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn add_storage_map(to: AztecAddress, amount: u32) -> Field; + + #[contract_library_method] + fn _add_storage_map(storage: Storage, to: AztecAddress, amount: u32) -> Field { + let new_balance: u32 = storage.map.at(to).read().add(amount); + storage.map.at(to).write(new_balance); + derive_storage_slot_in_map(storage.map.get_storage_slot(), to) + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call read_storage_map. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn read_storage_map(address: AztecAddress) -> u32; + + #[contract_library_method] + fn _read_storage_map(storage: Storage, address: AztecAddress) -> u32 { + storage.map.at(address).read() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call add_args_return. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn add_args_return(arg_a: Field, arg_b: Field) -> Field; + + #[contract_library_method] + unconstrained fn add(lhs: Field, rhs: Field) -> Field { + lhs + rhs + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_opcode_u8. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_opcode_u8() -> u8; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_opcode_u8_view. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_opcode_u8_view() -> u8; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_opcode_u32. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_opcode_u32() -> u32; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_opcode_u64. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_opcode_u64() -> u64; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_opcode_small_field. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_opcode_small_field() -> Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_opcode_big_field. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_opcode_big_field() -> Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_opcode_really_big_field. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_opcode_really_big_field() -> Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call add_u128. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn add_u128(a: u128, b: u128) -> u128; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call modulo2. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn modulo2(a: u64) -> u64; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call elliptic_curve_add. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn elliptic_curve_add(lhs: Point, rhs: Point) -> Point; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call elliptic_curve_add_and_double. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn elliptic_curve_add_and_double() -> Point; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call variable_base_msm. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn variable_base_msm(scalar_lo: Field, scalar_hi: Field, scalar2_lo: Field, scalar2_hi: Field) -> Point; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call pedersen_commit. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn pedersen_commit(x: Field, y: Field) -> Point; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call conditional_move. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn conditional_move(x: [Field; 1], y: [Field; 1], b: bool) -> [Field; 1]; + + #[contract_library_method] + fn bitwise_ops(x: u32, y: u32) -> u32 { + let mut result: u32 = x & y; + result = result | x; + result = result >> (x % 32_u32); + result = result << (y % 32_u32); + result ^ y + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call u128_addition_overflow. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn u128_addition_overflow() -> u128; + + #[contract_library_method] + fn integer_division(x: u8, y: u8) -> u8 { + x / y + } + + #[contract_library_method] + fn field_division(x: Field, y: Field) -> Field { + x / y + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call to_le_bytes. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn to_le_bytes(input: Field) -> [u8; 10]; + + #[contract_library_method] + fn _to_le_bytes(input: Field) -> [u8; 10] { + input.to_le_bytes() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call to_le_bits. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn to_le_bits(input: Field) -> [bool; 16]; + + #[contract_library_method] + fn _to_le_bits(input: Field) -> [bool; 16] { + input.to_le_bits() + } + + #[contract_library_method] + fn inner_helper_with_failed_assertion() { + let not_true: bool = false; + assert(not_true == true, "This assertion should fail!"); + } + + #[contract_library_method] + fn helper_with_failed_assertion() { + inner_helper_with_failed_assertion(); + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call assertion_failure. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn assertion_failure(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call external_call_to_assertion_failure. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn external_call_to_assertion_failure(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call divide_by_zero. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn divide_by_zero(denominator: u8) -> u8; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call external_call_to_divide_by_zero. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn external_call_to_divide_by_zero(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call external_call_to_divide_by_zero_recovers. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn external_call_to_divide_by_zero_recovers(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call debug_logging. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn debug_logging(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call assert_same. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn assert_same(arg_a: Field, arg_b: Field) -> pub Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call assert_calldata_copy. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn assert_calldata_copy(args: [Field; 3], with_selector: bool); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call assert_calldata_copy_large. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn assert_calldata_copy_large(args: [Field; 300], with_selector: bool); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call returndata_copy_oracle. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn returndata_copy_oracle(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call return_oracle. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn return_oracle() -> [Field; 3]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call revert_oracle. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn revert_oracle() -> [Field; 3]; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call test_get_contract_instance. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn test_get_contract_instance(address: AztecAddress); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call test_get_contract_instance_matches. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn test_get_contract_instance_matches(address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field); + + #[contract_library_method] + fn _test_get_contract_instance_matches(address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field) { + let deployer: Option = get_contract_instance_deployer_avm(address); + let class_id: Option = get_contract_instance_class_id_avm(address); + let initialization_hash: Option = get_contract_instance_initialization_hash_avm(address); + assert(deployer.is_some(), "Contract instance not found when getting DEPLOYER!"); + assert(class_id.is_some(), "Contract instance not found when getting CLASS_ID!"); + assert(initialization_hash.is_some(), "Contract instance not found when getting INIT_HASH!"); + assert(deployer.unwrap().eq(expected_deployer)); + assert(class_id.unwrap().eq(expected_class_id)); + assert(initialization_hash.unwrap().eq(expected_initialization_hash)); + aztec::oracle::logging::debug_log("Get Contract Instance Protocol Contract Instance"); + let fee_juice_class_id: Option = get_contract_instance_class_id_avm(FEE_JUICE_ADDRESS); + assert(fee_juice_class_id.is_some(), "Protocol Contract instance not found when getting CLASS_ID!"); + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_address. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_address() -> AztecAddress; + + #[contract_library_method] + fn _get_address(address: AztecAddress) -> AztecAddress { + address + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_sender. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_sender() -> AztecAddress; + + #[contract_library_method] + fn _get_sender(context: PublicContext) -> AztecAddress { + context.maybe_msg_sender().unwrap() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_transaction_fee. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_transaction_fee() -> Field; + + #[contract_library_method] + fn _get_transaction_fee(context: PublicContext) -> Field { + context.transaction_fee() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_chain_id. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_chain_id() -> Field; + + #[contract_library_method] + fn _get_chain_id(context: PublicContext) -> Field { + context.chain_id() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_version. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_version() -> Field; + + #[contract_library_method] + fn _get_version(context: PublicContext) -> Field { + context.version() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_block_number. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_block_number() -> u32; + + #[contract_library_method] + fn _get_block_number(context: PublicContext) -> u32 { + context.block_number() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_timestamp. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_timestamp() -> u64; + + #[contract_library_method] + fn _get_timestamp(context: PublicContext) -> u64 { + context.timestamp() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_fee_per_l2_gas. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_fee_per_l2_gas() -> u128; + + #[contract_library_method] + fn _get_fee_per_l2_gas(context: PublicContext) -> u128 { + context.min_fee_per_l2_gas() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_fee_per_da_gas. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_fee_per_da_gas() -> u128; + + #[contract_library_method] + fn _get_fee_per_da_gas(context: PublicContext) -> u128 { + context.min_fee_per_da_gas() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_l2_gas_left. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_l2_gas_left() -> u32; + + #[contract_library_method] + fn _get_l2_gas_left(context: PublicContext) -> u32 { + context.l2_gas_left() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_da_gas_left. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_da_gas_left() -> u32; + + #[contract_library_method] + fn _get_da_gas_left(context: PublicContext) -> u32 { + context.da_gas_left() + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_args_hash. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_args_hash(_a: u8, _fields: [Field; 3]) -> Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call emit_public_log. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn emit_public_log(); + + #[contract_library_method] + fn _emit_public_log(context: PublicContext) { + context.emit_public_log_unsafe(0_Field, [10_Field, 20_Field, 30_Field]); + context.emit_public_log_unsafe(0_Field, "Hello, world!"); + let s: CompressedString<2, 44> = CompressedString::<2, 44>::from_string("A long time ago, in a galaxy far far away..."); + context.emit_public_log_unsafe(0_Field, s); + context.emit_public_log_unsafe(0_Field, [1_Field, 2_Field, 3_Field, 4_Field, 5_Field, 6_Field, 7_Field, 8_Field, 9_Field, 10_Field, 11_Field, 12_Field, 13_Field, 14_Field, 15_Field, 16_Field, 17_Field, 18_Field, 19_Field, 20_Field, 21_Field, 22_Field, 23_Field, 24_Field, 25_Field, 26_Field, 27_Field, 28_Field, 29_Field, 30_Field, 31_Field, 32_Field, 33_Field, 34_Field, 35_Field, 36_Field, 37_Field, 38_Field, 39_Field, 40_Field, 41_Field, 42_Field]); + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call note_hash_exists. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn note_hash_exists(note_hash: Field, leaf_index: u64) -> bool; + + #[contract_library_method] + fn _note_hash_exists(context: PublicContext, note_hash: Field, leaf_index: u64) -> bool { + context.note_hash_exists(note_hash, leaf_index) + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call new_note_hash. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn new_note_hash(note_hash: Field); + + #[contract_library_method] + fn _new_note_hash(context: PublicContext, note_hash: Field) { + context.push_note_hash(note_hash); + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call new_nullifier. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn new_nullifier(nullifier: Field); + + #[contract_library_method] + fn _new_nullifier(context: PublicContext, nullifier: Field) { + context.push_nullifier(nullifier); + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call n_storage_writes. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn n_storage_writes(num: u32); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call n_new_note_hashes. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn n_new_note_hashes(num: u32); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call n_new_nullifiers. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn n_new_nullifiers(num: u32); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call n_new_l2_to_l1_msgs. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn n_new_l2_to_l1_msgs(num: u32); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call raw_l2_to_l1_msg. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn raw_l2_to_l1_msg(recipient: EthAddress, content: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call n_new_public_logs. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn n_new_public_logs(num: u32); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nullifier_exists. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nullifier_exists(nullifier: Field) -> bool; + + #[contract_library_method] + fn _nullifier_exists(context: PublicContext, address: AztecAddress, nullifier: Field) -> bool { + context.nullifier_exists_unsafe(nullifier, address) + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call assert_nullifier_exists. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn assert_nullifier_exists(nullifier: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call emit_nullifier_and_check. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn emit_nullifier_and_check(nullifier: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nullifier_collision. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nullifier_collision(nullifier: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call l1_to_l2_msg_exists. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> bool; + + #[contract_library_method] + fn _l1_to_l2_msg_exists(context: PublicContext, msg_hash: Field, msg_leaf_index: Field) -> bool { + context.l1_to_l2_msg_exists(msg_hash, msg_leaf_index) + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call send_l2_to_l1_msg. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn send_l2_to_l1_msg(recipient: EthAddress, content: Field); + + #[contract_library_method] + fn _send_l2_to_l1_msg(context: PublicContext, recipient: EthAddress, content: Field) { + context.message_portal(recipient, content) + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nested_call_to_nothing. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nested_call_to_nothing(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nested_call_to_nothing_recovers. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nested_call_to_nothing_recovers(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nested_call_to_add_with_gas. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nested_call_to_add_with_gas(arg_a: Field, arg_b: Field, l2_gas: u32, da_gas: u32) -> pub Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nested_call_to_add. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nested_call_to_add(arg_a: Field, arg_b: Field) -> pub Field; + + #[contract_library_method] + unconstrained fn _nested_call_to_add(context: PublicContext, address: AztecAddress, arg_a: Field, arg_b: Field) -> Field { + AvmTest::at(address).add_args_return(arg_a, arg_b).call(context) + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nested_call_to_add_n_times_different_addresses. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nested_call_to_add_n_times_different_addresses(addrs: [AztecAddress; 23]); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nested_static_call_to_add. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nested_static_call_to_add(arg_a: Field, arg_b: Field) -> pub Field; + + #[contract_library_method] + unconstrained fn _nested_static_call_to_add(context: PublicContext, address: AztecAddress, arg_a: Field, arg_b: Field) -> Field { + let selector: FunctionSelector = FunctionSelector { inner: 2858633377_u32}; + context.static_call_public_function(address, selector, [arg_a, arg_b], GasOpts::default())[0_u32] + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nested_static_call_to_set_storage. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nested_static_call_to_set_storage(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call create_same_nullifier_in_nested_call. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn create_same_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call create_different_nullifier_in_nested_call. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn create_different_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nested_call_to_assert_same. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nested_call_to_assert_same(arg_a: Field, arg_b: Field) -> pub Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_w_large_calldata. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_w_large_calldata(_arr: [Field; 300]) -> pub Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call nested_call_large_calldata. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn nested_call_large_calldata(arr: [Field; 300]) -> pub Field; + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call enqueue_public_from_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn enqueue_public_from_private(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call call_fee_juice. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn call_fee_juice(); + + #[contract_library_method] + unconstrained fn _call_fee_juice(context: PublicContext, address: AztecAddress) { + let _: u128 = FeeJuice::at(FEE_JUICE_ADDRESS).balance_of_public(address).view(context); + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call call_auth_registry. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn call_auth_registry(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call call_instance_registry. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn call_instance_registry(); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call bulk_testing. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn bulk_testing(args_field: [Field; 10], args_u8: [u8; 10], get_instance_for_address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, skip_strictly_limited_side_effects: bool); + + /// Unpacks an array into a note corresponding to `note_type_id` and then computes its note hash (non-siloed) and inner nullifier (non-siloed) assuming the note has been inserted into the note hash tree with `note_nonce`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + #[allow(dead_code)] + unconstrained fn _compute_note_hash_and_nullifier(packed_note: BoundedVec, owner: AztecAddress, storage_slot: Field, note_type_id: Field, contract_address: AztecAddress, randomness: Field, note_nonce: Field) -> Option { + _compute_note_hash(packed_note, owner, storage_slot, note_type_id, contract_address, randomness).map(|note_hash: Field| -> aztec::messages::discovery::NoteHashAndNullifier { + let siloed_note_hash: Field = aztec::protocol::hash::compute_siloed_note_hash(contract_address, note_hash); + let unique_note_hash: Field = aztec::protocol::hash::compute_unique_note_hash(note_nonce, siloed_note_hash); + let inner_nullifier: Option = _compute_note_nullifier(unique_note_hash, packed_note, owner, storage_slot, note_type_id, contract_address, randomness); + aztec::messages::discovery::NoteHashAndNullifier { note_hash: note_hash, inner_nullifier: inner_nullifier} + }) + } + + /// This contract does not use private notes, so this function should never be called as it will unconditionally fail. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_hash(_packed_note: BoundedVec, _owner: AztecAddress, _storage_slot: Field, _note_type_id: Field, _contract_address: AztecAddress, _randomness: Field) -> Option { + panic(f"This contract does not use private notes") + } + + /// This contract does not use private notes, so this function should never be called as it will unconditionally fail. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_nullifier(_unique_note_hash: Field, _packed_note: BoundedVec, _owner: AztecAddress, _storage_slot: Field, _note_type_id: Field, _contract_address: AztecAddress, _randomness: Field) -> Option { + panic(f"This contract does not use private notes") + } + + /// Receives offchain messages into this contract's offchain inbox for subsequent processing. + /// + /// Each message is routed to the inbox scoped to its `recipient` field. + /// + /// For more details, see `aztec::messages::processing::offchain::receive`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + unconstrained fn offchain_receive(messages: BoundedVec) { + let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::processing::offchain::receive(address, messages); + } + + pub struct AvmTest { + pub target_contract: AztecAddress, + } + + impl AvmTest { + pub fn storage_layout() -> StorageLayoutFields { + STORAGE_LAYOUT_AvmTest.fields + } + + pub fn at(addr: AztecAddress) -> Self { + Self { target_contract: addr} + } + + pub fn interface() -> Self { + Self { target_contract: AztecAddress::zero()} + } + + pub fn assert_calldata_copy(self, args: [Field; 3], with_selector: bool) -> aztec::context::calls::PublicCall<20, 4, ()> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3 * 1] = args.serialize(); + let serialized_member_len: u32 = <[Field; 3] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = with_selector.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3853740100_Field); + aztec::context::calls::PublicCall::<20, 4, ()>::new(self.target_contract, selector, "assert_calldata_copy", serialized_params) + } + + pub fn get_chain_id(self) -> aztec::context::calls::PublicCall<12, 0, Field> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1458572288_Field); + aztec::context::calls::PublicCall::<12, 0, Field>::new(self.target_contract, selector, "get_chain_id", serialized_params) + } + + pub fn get_args_hash(self, _a: u8, _fields: [Field; 3]) -> aztec::context::calls::PublicCall<13, 4, Field> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = _a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 3 * 1] = _fields.serialize(); + let serialized_member_len: u32 = <[Field; 3] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1608415988_Field); + aztec::context::calls::PublicCall::<13, 4, Field>::new(self.target_contract, selector, "get_args_hash", serialized_params) + } + + pub fn external_call_to_divide_by_zero(self) -> aztec::context::calls::PublicCall<31, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3880450065_Field); + aztec::context::calls::PublicCall::<31, 0, ()>::new(self.target_contract, selector, "external_call_to_divide_by_zero", serialized_params) + } + + pub fn n_new_nullifiers(self, num: u32) -> aztec::context::calls::PublicCall<16, 1, ()> { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(592684400_Field); + aztec::context::calls::PublicCall::<16, 1, ()>::new(self.target_contract, selector, "n_new_nullifiers", serialized_params) + } + + pub fn new_note_hash(self, note_hash: Field) -> aztec::context::calls::PublicCall<13, 1, ()> { + let serialized_params: [Field; 1] = note_hash.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1524332459_Field); + aztec::context::calls::PublicCall::<13, 1, ()>::new(self.target_contract, selector, "new_note_hash", serialized_params) + } + + pub fn nullifier_collision(self, nullifier: Field) -> aztec::context::calls::PublicCall<19, 1, ()> { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2417179850_Field); + aztec::context::calls::PublicCall::<19, 1, ()>::new(self.target_contract, selector, "nullifier_collision", serialized_params) + } + + pub fn get_l2_gas_left(self) -> aztec::context::calls::PublicCall<15, 0, u32> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1635524210_Field); + aztec::context::calls::PublicCall::<15, 0, u32>::new(self.target_contract, selector, "get_l2_gas_left", serialized_params) + } + + pub fn l1_to_l2_msg_exists(self, msg_hash: Field, msg_leaf_index: Field) -> aztec::context::calls::PublicCall<19, 2, bool> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = msg_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = msg_leaf_index.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3972971575_Field); + aztec::context::calls::PublicCall::<19, 2, bool>::new(self.target_contract, selector, "l1_to_l2_msg_exists", serialized_params) + } + + pub fn add_storage_map(self, to: AztecAddress, amount: u32) -> aztec::context::calls::PublicCall<15, 2, Field> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = to.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = amount.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2606877757_Field); + aztec::context::calls::PublicCall::<15, 2, Field>::new(self.target_contract, selector, "add_storage_map", serialized_params) + } + + pub fn bulk_testing(self, args_field: [Field; 10], args_u8: [u8; 10], get_instance_for_address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, skip_strictly_limited_side_effects: bool) -> aztec::context::calls::PublicCall<12, 25, ()> { + let mut serialized_params: [Field; 25] = [0_Field; 25]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 10 * 1] = args_field.serialize(); + let serialized_member_len: u32 = <[Field; 10] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 10 * 1] = args_u8.serialize(); + let serialized_member_len: u32 = <[u8; 10] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = get_instance_for_address.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_deployer.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_class_id.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_initialization_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = skip_strictly_limited_side_effects.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_6: u32 = i + offset; + serialized_params[i_6] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(43639379_Field); + aztec::context::calls::PublicCall::<12, 25, ()>::new(self.target_contract, selector, "bulk_testing", serialized_params) + } + + pub fn variable_base_msm(self, scalar_lo: Field, scalar_hi: Field, scalar2_lo: Field, scalar2_hi: Field) -> aztec::context::calls::PublicCall<17, 4, Point> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = scalar_lo.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = scalar_hi.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = scalar2_lo.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = scalar2_hi.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2931784034_Field); + aztec::context::calls::PublicCall::<17, 4, Point>::new(self.target_contract, selector, "variable_base_msm", serialized_params) + } + + pub fn add_args_return(self, arg_a: Field, arg_b: Field) -> aztec::context::calls::PublicCall<15, 2, Field> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2858633377_Field); + aztec::context::calls::PublicCall::<15, 2, Field>::new(self.target_contract, selector, "add_args_return", serialized_params) + } + + pub fn test_get_contract_instance_matches(self, address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field) -> aztec::context::calls::PublicCall<34, 4, ()> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = address.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_deployer.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_class_id.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_initialization_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2723912183_Field); + aztec::context::calls::PublicCall::<34, 4, ()>::new(self.target_contract, selector, "test_get_contract_instance_matches", serialized_params) + } + + pub fn get_sender(self) -> aztec::context::calls::PublicCall<10, 0, AztecAddress> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(301170519_Field); + aztec::context::calls::PublicCall::<10, 0, AztecAddress>::new(self.target_contract, selector, "get_sender", serialized_params) + } + + pub fn n_new_l2_to_l1_msgs(self, num: u32) -> aztec::context::calls::PublicCall<19, 1, ()> { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3921925917_Field); + aztec::context::calls::PublicCall::<19, 1, ()>::new(self.target_contract, selector, "n_new_l2_to_l1_msgs", serialized_params) + } + + pub fn set_storage_list(self, a: Field, b: Field) -> aztec::context::calls::PublicCall<16, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1745164739_Field); + aztec::context::calls::PublicCall::<16, 2, ()>::new(self.target_contract, selector, "set_storage_list", serialized_params) + } + + pub fn pedersen_commit(self, x: Field, y: Field) -> aztec::context::calls::PublicCall<15, 2, Point> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = x.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = y.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2484465428_Field); + aztec::context::calls::PublicCall::<15, 2, Point>::new(self.target_contract, selector, "pedersen_commit", serialized_params) + } + + pub fn nullifier_exists(self, nullifier: Field) -> aztec::context::calls::PublicCall<16, 1, bool> { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2051407563_Field); + aztec::context::calls::PublicCall::<16, 1, bool>::new(self.target_contract, selector, "nullifier_exists", serialized_params) + } + + pub fn read_storage_list(self) -> aztec::context::calls::PublicCall<17, 0, [Field; 2]> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1727615163_Field); + aztec::context::calls::PublicCall::<17, 0, [Field; 2]>::new(self.target_contract, selector, "read_storage_list", serialized_params) + } + + pub fn emit_nullifier_and_check(self, nullifier: Field) -> aztec::context::calls::PublicCall<24, 1, ()> { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2367487025_Field); + aztec::context::calls::PublicCall::<24, 1, ()>::new(self.target_contract, selector, "emit_nullifier_and_check", serialized_params) + } + + pub fn assert_same(self, arg_a: Field, arg_b: Field) -> aztec::context::calls::PublicCall<11, 2, Field> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(290442984_Field); + aztec::context::calls::PublicCall::<11, 2, Field>::new(self.target_contract, selector, "assert_same", serialized_params) + } + + pub fn get_fee_per_da_gas(self) -> aztec::context::calls::PublicCall<18, 0, u128> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(514475538_Field); + aztec::context::calls::PublicCall::<18, 0, u128>::new(self.target_contract, selector, "get_fee_per_da_gas", serialized_params) + } + + pub fn modulo2(self, a: u64) -> aztec::context::calls::PublicCall<7, 1, u64> { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(222531562_Field); + aztec::context::calls::PublicCall::<7, 1, u64>::new(self.target_contract, selector, "modulo2", serialized_params) + } + + pub fn nested_static_call_to_add(self, arg_a: Field, arg_b: Field) -> aztec::context::calls::PublicCall<25, 2, Field> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1362946309_Field); + aztec::context::calls::PublicCall::<25, 2, Field>::new(self.target_contract, selector, "nested_static_call_to_add", serialized_params) + } + + pub fn to_le_bits(self, input: Field) -> aztec::context::calls::PublicCall<10, 1, [bool; 16]> { + let serialized_params: [Field; 1] = input.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2961959597_Field); + aztec::context::calls::PublicCall::<10, 1, [bool; 16]>::new(self.target_contract, selector, "to_le_bits", serialized_params) + } + + pub fn call_auth_registry(self) -> aztec::context::calls::PublicCall<18, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1225767423_Field); + aztec::context::calls::PublicCall::<18, 0, ()>::new(self.target_contract, selector, "call_auth_registry", serialized_params) + } + + pub fn set_opcode_u64(self) -> aztec::context::calls::PublicCall<14, 0, u64> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1435480431_Field); + aztec::context::calls::PublicCall::<14, 0, u64>::new(self.target_contract, selector, "set_opcode_u64", serialized_params) + } + + pub fn return_oracle(self) -> aztec::context::calls::PublicCall<13, 0, [Field; 3]> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3794636397_Field); + aztec::context::calls::PublicCall::<13, 0, [Field; 3]>::new(self.target_contract, selector, "return_oracle", serialized_params) + } + + pub fn test_get_contract_instance(self, address: AztecAddress) -> aztec::context::calls::PublicCall<26, 1, ()> { + let serialized_params: [Field; 1] = address.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2488367864_Field); + aztec::context::calls::PublicCall::<26, 1, ()>::new(self.target_contract, selector, "test_get_contract_instance", serialized_params) + } + + pub fn get_timestamp(self) -> aztec::context::calls::PublicCall<13, 0, u64> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(448989811_Field); + aztec::context::calls::PublicCall::<13, 0, u64>::new(self.target_contract, selector, "get_timestamp", serialized_params) + } + + pub fn to_le_bytes(self, input: Field) -> aztec::context::calls::PublicCall<11, 1, [u8; 10]> { + let serialized_params: [Field; 1] = input.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1975931334_Field); + aztec::context::calls::PublicCall::<11, 1, [u8; 10]>::new(self.target_contract, selector, "to_le_bytes", serialized_params) + } + + pub fn external_call_to_assertion_failure(self) -> aztec::context::calls::PublicCall<34, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(294808228_Field); + aztec::context::calls::PublicCall::<34, 0, ()>::new(self.target_contract, selector, "external_call_to_assertion_failure", serialized_params) + } + + pub fn divide_by_zero(self, denominator: u8) -> aztec::context::calls::PublicCall<14, 1, u8> { + let serialized_params: [Field; 1] = denominator.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(815932481_Field); + aztec::context::calls::PublicCall::<14, 1, u8>::new(self.target_contract, selector, "divide_by_zero", serialized_params) + } + + pub fn emit_public_log(self) -> aztec::context::calls::PublicCall<15, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2033426724_Field); + aztec::context::calls::PublicCall::<15, 0, ()>::new(self.target_contract, selector, "emit_public_log", serialized_params) + } + + pub fn new_nullifier(self, nullifier: Field) -> aztec::context::calls::PublicCall<13, 1, ()> { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); + aztec::context::calls::PublicCall::<13, 1, ()>::new(self.target_contract, selector, "new_nullifier", serialized_params) + } + + pub fn raw_l2_to_l1_msg(self, recipient: EthAddress, content: Field) -> aztec::context::calls::PublicCall<16, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = recipient.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = content.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3409962923_Field); + aztec::context::calls::PublicCall::<16, 2, ()>::new(self.target_contract, selector, "raw_l2_to_l1_msg", serialized_params) + } + + pub fn nested_call_to_nothing_recovers(self) -> aztec::context::calls::PublicCall<31, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1843532057_Field); + aztec::context::calls::PublicCall::<31, 0, ()>::new(self.target_contract, selector, "nested_call_to_nothing_recovers", serialized_params) + } + + pub fn assert_calldata_copy_large(self, args: [Field; 300], with_selector: bool) -> aztec::context::calls::PublicCall<26, 301, ()> { + let mut serialized_params: [Field; 301] = [0_Field; 301]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 300 * 1] = args.serialize(); + let serialized_member_len: u32 = <[Field; 300] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = with_selector.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2293565755_Field); + aztec::context::calls::PublicCall::<26, 301, ()>::new(self.target_contract, selector, "assert_calldata_copy_large", serialized_params) + } + + pub fn set_opcode_really_big_field(self) -> aztec::context::calls::PublicCall<27, 0, Field> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4095821182_Field); + aztec::context::calls::PublicCall::<27, 0, Field>::new(self.target_contract, selector, "set_opcode_really_big_field", serialized_params) + } + + pub fn enqueue_public_from_private(self) -> aztec::context::calls::PrivateCall<27, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2771384488_Field); + aztec::context::calls::PrivateCall::<27, 0, ()>::new(self.target_contract, selector, "enqueue_public_from_private", serialized_params) + } + + pub fn elliptic_curve_add(self, lhs: Point, rhs: Point) -> aztec::context::calls::PublicCall<18, 6, Point> { + let mut serialized_params: [Field; 6] = [0_Field; 6]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3] = lhs.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 3] = rhs.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1700026912_Field); + aztec::context::calls::PublicCall::<18, 6, Point>::new(self.target_contract, selector, "elliptic_curve_add", serialized_params) + } + + pub fn set_read_storage_single(self, a: Field) -> aztec::context::calls::PublicCall<23, 1, Field> { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1932358992_Field); + aztec::context::calls::PublicCall::<23, 1, Field>::new(self.target_contract, selector, "set_read_storage_single", serialized_params) + } + + pub fn returndata_copy_oracle(self) -> aztec::context::calls::PublicCall<22, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4172530660_Field); + aztec::context::calls::PublicCall::<22, 0, ()>::new(self.target_contract, selector, "returndata_copy_oracle", serialized_params) + } + + pub fn conditional_move(self, x: [Field; 1], y: [Field; 1], b: bool) -> aztec::context::calls::PublicCall<16, 3, [Field; 1]> { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1 * 1] = x.serialize(); + let serialized_member_len: u32 = <[Field; 1] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1 * 1] = y.serialize(); + let serialized_member_len: u32 = <[Field; 1] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2633971407_Field); + aztec::context::calls::PublicCall::<16, 3, [Field; 1]>::new(self.target_contract, selector, "conditional_move", serialized_params) + } + + pub fn set_opcode_small_field(self) -> aztec::context::calls::PublicCall<22, 0, Field> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3464175345_Field); + aztec::context::calls::PublicCall::<22, 0, Field>::new(self.target_contract, selector, "set_opcode_small_field", serialized_params) + } + + pub fn n_new_public_logs(self, num: u32) -> aztec::context::calls::PublicCall<17, 1, ()> { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2907114368_Field); + aztec::context::calls::PublicCall::<17, 1, ()>::new(self.target_contract, selector, "n_new_public_logs", serialized_params) + } + + pub fn nested_call_to_nothing(self) -> aztec::context::calls::PublicCall<22, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1183868090_Field); + aztec::context::calls::PublicCall::<22, 0, ()>::new(self.target_contract, selector, "nested_call_to_nothing", serialized_params) + } + + pub fn nested_call_to_add_with_gas(self, arg_a: Field, arg_b: Field, l2_gas: u32, da_gas: u32) -> aztec::context::calls::PublicCall<27, 4, Field> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = l2_gas.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = da_gas.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3561659563_Field); + aztec::context::calls::PublicCall::<27, 4, Field>::new(self.target_contract, selector, "nested_call_to_add_with_gas", serialized_params) + } + + pub fn create_different_nullifier_in_nested_call(self, nestedAddress: AztecAddress, nullifier: Field) -> aztec::context::calls::PublicCall<41, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = nestedAddress.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = nullifier.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1630216043_Field); + aztec::context::calls::PublicCall::<41, 2, ()>::new(self.target_contract, selector, "create_different_nullifier_in_nested_call", serialized_params) + } + + pub fn call_fee_juice(self) -> aztec::context::calls::PublicCall<14, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); + aztec::context::calls::PublicCall::<14, 0, ()>::new(self.target_contract, selector, "call_fee_juice", serialized_params) + } + + pub fn get_transaction_fee(self) -> aztec::context::calls::PublicCall<19, 0, Field> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2524054657_Field); + aztec::context::calls::PublicCall::<19, 0, Field>::new(self.target_contract, selector, "get_transaction_fee", serialized_params) + } + + pub fn get_da_gas_left(self) -> aztec::context::calls::PublicCall<15, 0, u32> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2319460898_Field); + aztec::context::calls::PublicCall::<15, 0, u32>::new(self.target_contract, selector, "get_da_gas_left", serialized_params) + } + + pub fn read_storage_single(self) -> aztec::context::calls::PublicCall<19, 0, Field> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3140392744_Field); + aztec::context::calls::PublicCall::<19, 0, Field>::new(self.target_contract, selector, "read_storage_single", serialized_params) + } + + pub fn set_opcode_u8_view(self) -> aztec::context::calls::PublicStaticCall<18, 0, u8> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(643109956_Field); + aztec::context::calls::PublicStaticCall::<18, 0, u8>::new(self.target_contract, selector, "set_opcode_u8_view", serialized_params) + } + + pub fn assert_nullifier_exists(self, nullifier: Field) -> aztec::context::calls::PublicCall<23, 1, ()> { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2810255355_Field); + aztec::context::calls::PublicCall::<23, 1, ()>::new(self.target_contract, selector, "assert_nullifier_exists", serialized_params) + } + + pub fn assertion_failure(self) -> aztec::context::calls::PublicCall<17, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3276887878_Field); + aztec::context::calls::PublicCall::<17, 0, ()>::new(self.target_contract, selector, "assertion_failure", serialized_params) + } + + pub fn debug_logging(self) -> aztec::context::calls::PublicCall<13, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3667472301_Field); + aztec::context::calls::PublicCall::<13, 0, ()>::new(self.target_contract, selector, "debug_logging", serialized_params) + } + + pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> aztec::context::calls::PublicCall<26, 300, Field> { + let serialized_params: [Field; 300] = arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); + aztec::context::calls::PublicCall::<26, 300, Field>::new(self.target_contract, selector, "nested_call_large_calldata", serialized_params) + } + + pub fn external_call_to_divide_by_zero_recovers(self) -> aztec::context::calls::PublicCall<40, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2245930342_Field); + aztec::context::calls::PublicCall::<40, 0, ()>::new(self.target_contract, selector, "external_call_to_divide_by_zero_recovers", serialized_params) + } + + pub fn set_opcode_u32(self) -> aztec::context::calls::PublicCall<14, 0, u32> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4045556597_Field); + aztec::context::calls::PublicCall::<14, 0, u32>::new(self.target_contract, selector, "set_opcode_u32", serialized_params) + } + + pub fn call_instance_registry(self) -> aztec::context::calls::PublicCall<22, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2336742722_Field); + aztec::context::calls::PublicCall::<22, 0, ()>::new(self.target_contract, selector, "call_instance_registry", serialized_params) + } + + pub fn set_storage_single(self, a: Field) -> aztec::context::calls::PublicCall<18, 1, ()> { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2230419055_Field); + aztec::context::calls::PublicCall::<18, 1, ()>::new(self.target_contract, selector, "set_storage_single", serialized_params) + } + + pub fn nested_call_to_add(self, arg_a: Field, arg_b: Field) -> aztec::context::calls::PublicCall<18, 2, Field> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(94115833_Field); + aztec::context::calls::PublicCall::<18, 2, Field>::new(self.target_contract, selector, "nested_call_to_add", serialized_params) + } + + pub fn revert_oracle(self) -> aztec::context::calls::PublicCall<13, 0, [Field; 3]> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4147614534_Field); + aztec::context::calls::PublicCall::<13, 0, [Field; 3]>::new(self.target_contract, selector, "revert_oracle", serialized_params) + } + + pub fn send_l2_to_l1_msg(self, recipient: EthAddress, content: Field) -> aztec::context::calls::PublicCall<17, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = recipient.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = content.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2709402942_Field); + aztec::context::calls::PublicCall::<17, 2, ()>::new(self.target_contract, selector, "send_l2_to_l1_msg", serialized_params) + } + + pub fn note_hash_exists(self, note_hash: Field, leaf_index: u64) -> aztec::context::calls::PublicCall<16, 2, bool> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = note_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = leaf_index.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(671085844_Field); + aztec::context::calls::PublicCall::<16, 2, bool>::new(self.target_contract, selector, "note_hash_exists", serialized_params) + } + + pub fn read_storage_map(self, address: AztecAddress) -> aztec::context::calls::PublicCall<16, 1, u32> { + let serialized_params: [Field; 1] = address.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(711888726_Field); + aztec::context::calls::PublicCall::<16, 1, u32>::new(self.target_contract, selector, "read_storage_map", serialized_params) + } + + pub fn read_assert_storage_single(self, a: Field) -> aztec::context::calls::PublicCall<26, 1, ()> { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1067389427_Field); + aztec::context::calls::PublicCall::<26, 1, ()>::new(self.target_contract, selector, "read_assert_storage_single", serialized_params) + } + + pub fn elliptic_curve_add_and_double(self) -> aztec::context::calls::PublicCall<29, 0, Point> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1891218722_Field); + aztec::context::calls::PublicCall::<29, 0, Point>::new(self.target_contract, selector, "elliptic_curve_add_and_double", serialized_params) + } + + pub fn get_block_number(self) -> aztec::context::calls::PublicCall<16, 0, u32> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3223336515_Field); + aztec::context::calls::PublicCall::<16, 0, u32>::new(self.target_contract, selector, "get_block_number", serialized_params) + } + + pub fn nested_call_to_assert_same(self, arg_a: Field, arg_b: Field) -> aztec::context::calls::PublicCall<26, 2, Field> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1563037608_Field); + aztec::context::calls::PublicCall::<26, 2, Field>::new(self.target_contract, selector, "nested_call_to_assert_same", serialized_params) + } + + pub fn fn_w_large_calldata(self, _arr: [Field; 300]) -> aztec::context::calls::PublicCall<19, 300, Field> { + let serialized_params: [Field; 300] = _arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3786762676_Field); + aztec::context::calls::PublicCall::<19, 300, Field>::new(self.target_contract, selector, "fn_w_large_calldata", serialized_params) + } + + pub fn get_address(self) -> aztec::context::calls::PublicCall<11, 0, AztecAddress> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1968200506_Field); + aztec::context::calls::PublicCall::<11, 0, AztecAddress>::new(self.target_contract, selector, "get_address", serialized_params) + } + + pub fn set_storage_map(self, to: AztecAddress, amount: u32) -> aztec::context::calls::PublicCall<15, 2, Field> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = to.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = amount.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1756672898_Field); + aztec::context::calls::PublicCall::<15, 2, Field>::new(self.target_contract, selector, "set_storage_map", serialized_params) + } + + pub fn get_version(self) -> aztec::context::calls::PublicCall<11, 0, Field> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(421038220_Field); + aztec::context::calls::PublicCall::<11, 0, Field>::new(self.target_contract, selector, "get_version", serialized_params) + } + + pub fn nested_static_call_to_set_storage(self) -> aztec::context::calls::PublicCall<33, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3861896907_Field); + aztec::context::calls::PublicCall::<33, 0, ()>::new(self.target_contract, selector, "nested_static_call_to_set_storage", serialized_params) + } + + pub fn create_same_nullifier_in_nested_call(self, nestedAddress: AztecAddress, nullifier: Field) -> aztec::context::calls::PublicCall<36, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = nestedAddress.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = nullifier.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1050471208_Field); + aztec::context::calls::PublicCall::<36, 2, ()>::new(self.target_contract, selector, "create_same_nullifier_in_nested_call", serialized_params) + } + + pub fn set_opcode_big_field(self) -> aztec::context::calls::PublicCall<20, 0, Field> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(497423715_Field); + aztec::context::calls::PublicCall::<20, 0, Field>::new(self.target_contract, selector, "set_opcode_big_field", serialized_params) + } + + pub fn u128_addition_overflow(self) -> aztec::context::calls::PublicCall<22, 0, u128> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2520497807_Field); + aztec::context::calls::PublicCall::<22, 0, u128>::new(self.target_contract, selector, "u128_addition_overflow", serialized_params) + } + + pub fn add_u128(self, a: u128, b: u128) -> aztec::context::calls::PublicCall<8, 2, u128> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1408352185_Field); + aztec::context::calls::PublicCall::<8, 2, u128>::new(self.target_contract, selector, "add_u128", serialized_params) + } + + pub fn get_fee_per_l2_gas(self) -> aztec::context::calls::PublicCall<18, 0, u128> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(323255525_Field); + aztec::context::calls::PublicCall::<18, 0, u128>::new(self.target_contract, selector, "get_fee_per_l2_gas", serialized_params) + } + + pub fn n_storage_writes(self, num: u32) -> aztec::context::calls::PublicCall<16, 1, ()> { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2323221248_Field); + aztec::context::calls::PublicCall::<16, 1, ()>::new(self.target_contract, selector, "n_storage_writes", serialized_params) + } + + pub fn set_opcode_u8(self) -> aztec::context::calls::PublicCall<13, 0, u8> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3068438800_Field); + aztec::context::calls::PublicCall::<13, 0, u8>::new(self.target_contract, selector, "set_opcode_u8", serialized_params) + } + + pub fn n_new_note_hashes(self, num: u32) -> aztec::context::calls::PublicCall<17, 1, ()> { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1938641640_Field); + aztec::context::calls::PublicCall::<17, 1, ()>::new(self.target_contract, selector, "n_new_note_hashes", serialized_params) + } + + pub fn nested_call_to_add_n_times_different_addresses(self, addrs: [AztecAddress; 23]) -> aztec::context::calls::PublicCall<46, 23, ()> { + let serialized_params: [Field; 23] = addrs.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2936248969_Field); + aztec::context::calls::PublicCall::<46, 23, ()>::new(self.target_contract, selector, "nested_call_to_add_n_times_different_addresses", serialized_params) + } + + pub fn offchain_receive(self, messages: BoundedVec) -> aztec::context::calls::UtilityCall<16, 321, ()> { + let serialized_params: [Field; 321] = messages.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1396850735_Field); + aztec::context::calls::UtilityCall::<16, 321, ()>::new(self.target_contract, selector, "offchain_receive", serialized_params) + } + } + + #[contract_library_method] + pub fn storage_layout() -> StorageLayoutFields { + STORAGE_LAYOUT_AvmTest.fields + } + + #[contract_library_method] + pub fn at(addr: AztecAddress) -> AvmTest { + AvmTest { target_contract: addr} + } + + #[contract_library_method] + pub fn interface() -> AvmTest { + AvmTest { target_contract: AztecAddress::zero()} + } + + pub struct sync_state_parameters { + pub scope: AztecAddress, + } + + #[abi(functions)] + pub struct sync_state_abi { + parameters: sync_state_parameters, + } + + unconstrained fn sync_state(scope: AztecAddress) { + let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + } + + pub struct offchain_receive_parameters { + pub messages: BoundedVec, + } + + #[abi(functions)] + pub struct offchain_receive_abi { + parameters: offchain_receive_parameters, + } + + pub struct CallSelf { + pub address: AztecAddress, + pub context: Context, + } + + impl CallSelf { + pub fn assert_calldata_copy(self, args: [Field; 3], with_selector: bool) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3 * 1] = args.serialize(); + let serialized_member_len: u32 = <[Field; 3] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = with_selector.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3853740100_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<20, 4, ()>::new(self.address, selector, "assert_calldata_copy", serialized_params).call(self.context) + } + } + + pub fn get_chain_id(self) -> Field { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1458572288_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<12, 0, Field>::new(self.address, selector, "get_chain_id", serialized_params).call(self.context) + } + } + + pub fn get_args_hash(self, _a: u8, _fields: [Field; 3]) -> Field { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = _a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 3 * 1] = _fields.serialize(); + let serialized_member_len: u32 = <[Field; 3] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1608415988_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 4, Field>::new(self.address, selector, "get_args_hash", serialized_params).call(self.context) + } + } + + pub fn external_call_to_divide_by_zero(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3880450065_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<31, 0, ()>::new(self.address, selector, "external_call_to_divide_by_zero", serialized_params).call(self.context) + } + } + + pub fn n_new_nullifiers(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(592684400_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 1, ()>::new(self.address, selector, "n_new_nullifiers", serialized_params).call(self.context) + } + } + + pub fn new_note_hash(self, note_hash: Field) { + let serialized_params: [Field; 1] = note_hash.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1524332459_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 1, ()>::new(self.address, selector, "new_note_hash", serialized_params).call(self.context) + } + } + + pub fn nullifier_collision(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2417179850_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<19, 1, ()>::new(self.address, selector, "nullifier_collision", serialized_params).call(self.context) + } + } + + pub fn get_l2_gas_left(self) -> u32 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1635524210_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 0, u32>::new(self.address, selector, "get_l2_gas_left", serialized_params).call(self.context) + } + } + + pub fn l1_to_l2_msg_exists(self, msg_hash: Field, msg_leaf_index: Field) -> bool { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = msg_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = msg_leaf_index.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3972971575_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<19, 2, bool>::new(self.address, selector, "l1_to_l2_msg_exists", serialized_params).call(self.context) + } + } + + pub fn add_storage_map(self, to: AztecAddress, amount: u32) -> Field { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = to.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = amount.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2606877757_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 2, Field>::new(self.address, selector, "add_storage_map", serialized_params).call(self.context) + } + } + + pub fn bulk_testing(self, args_field: [Field; 10], args_u8: [u8; 10], get_instance_for_address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, skip_strictly_limited_side_effects: bool) { + let mut serialized_params: [Field; 25] = [0_Field; 25]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 10 * 1] = args_field.serialize(); + let serialized_member_len: u32 = <[Field; 10] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 10 * 1] = args_u8.serialize(); + let serialized_member_len: u32 = <[u8; 10] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = get_instance_for_address.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_deployer.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_class_id.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_initialization_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = skip_strictly_limited_side_effects.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_6: u32 = i + offset; + serialized_params[i_6] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(43639379_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<12, 25, ()>::new(self.address, selector, "bulk_testing", serialized_params).call(self.context) + } + } + + pub fn add_args_return(self, arg_a: Field, arg_b: Field) -> Field { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2858633377_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 2, Field>::new(self.address, selector, "add_args_return", serialized_params).call(self.context) + } + } + + pub fn variable_base_msm(self, scalar_lo: Field, scalar_hi: Field, scalar2_lo: Field, scalar2_hi: Field) -> Point { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = scalar_lo.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = scalar_hi.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = scalar2_lo.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = scalar2_hi.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2931784034_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<17, 4, Point>::new(self.address, selector, "variable_base_msm", serialized_params).call(self.context) + } + } + + pub fn test_get_contract_instance_matches(self, address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = address.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_deployer.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_class_id.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_initialization_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2723912183_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<34, 4, ()>::new(self.address, selector, "test_get_contract_instance_matches", serialized_params).call(self.context) + } + } + + pub fn get_sender(self) -> AztecAddress { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(301170519_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<10, 0, AztecAddress>::new(self.address, selector, "get_sender", serialized_params).call(self.context) + } + } + + pub fn n_new_l2_to_l1_msgs(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3921925917_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<19, 1, ()>::new(self.address, selector, "n_new_l2_to_l1_msgs", serialized_params).call(self.context) + } + } + + pub fn set_storage_list(self, a: Field, b: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1745164739_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 2, ()>::new(self.address, selector, "set_storage_list", serialized_params).call(self.context) + } + } + + pub fn pedersen_commit(self, x: Field, y: Field) -> Point { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = x.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = y.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2484465428_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 2, Point>::new(self.address, selector, "pedersen_commit", serialized_params).call(self.context) + } + } + + pub fn nullifier_exists(self, nullifier: Field) -> bool { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2051407563_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 1, bool>::new(self.address, selector, "nullifier_exists", serialized_params).call(self.context) + } + } + + pub fn read_storage_list(self) -> [Field; 2] { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1727615163_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<17, 0, [Field; 2]>::new(self.address, selector, "read_storage_list", serialized_params).call(self.context) + } + } + + pub fn emit_nullifier_and_check(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2367487025_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<24, 1, ()>::new(self.address, selector, "emit_nullifier_and_check", serialized_params).call(self.context) + } + } + + pub fn assert_same(self, arg_a: Field, arg_b: Field) -> Field { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(290442984_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<11, 2, Field>::new(self.address, selector, "assert_same", serialized_params).call(self.context) + } + } + + pub fn get_fee_per_da_gas(self) -> u128 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(514475538_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<18, 0, u128>::new(self.address, selector, "get_fee_per_da_gas", serialized_params).call(self.context) + } + } + + pub fn modulo2(self, a: u64) -> u64 { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(222531562_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<7, 1, u64>::new(self.address, selector, "modulo2", serialized_params).call(self.context) + } + } + + pub fn nested_static_call_to_add(self, arg_a: Field, arg_b: Field) -> Field { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1362946309_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<25, 2, Field>::new(self.address, selector, "nested_static_call_to_add", serialized_params).call(self.context) + } + } + + pub fn to_le_bits(self, input: Field) -> [bool; 16] { + let serialized_params: [Field; 1] = input.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2961959597_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<10, 1, [bool; 16]>::new(self.address, selector, "to_le_bits", serialized_params).call(self.context) + } + } + + pub fn call_auth_registry(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1225767423_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<18, 0, ()>::new(self.address, selector, "call_auth_registry", serialized_params).call(self.context) + } + } + + pub fn set_opcode_u64(self) -> u64 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1435480431_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 0, u64>::new(self.address, selector, "set_opcode_u64", serialized_params).call(self.context) + } + } + + pub fn return_oracle(self) -> [Field; 3] { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3794636397_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 0, [Field; 3]>::new(self.address, selector, "return_oracle", serialized_params).call(self.context) + } + } + + pub fn test_get_contract_instance(self, address: AztecAddress) { + let serialized_params: [Field; 1] = address.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2488367864_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<26, 1, ()>::new(self.address, selector, "test_get_contract_instance", serialized_params).call(self.context) + } + } + + pub fn get_timestamp(self) -> u64 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(448989811_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 0, u64>::new(self.address, selector, "get_timestamp", serialized_params).call(self.context) + } + } + + pub fn to_le_bytes(self, input: Field) -> [u8; 10] { + let serialized_params: [Field; 1] = input.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1975931334_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<11, 1, [u8; 10]>::new(self.address, selector, "to_le_bytes", serialized_params).call(self.context) + } + } + + pub fn external_call_to_assertion_failure(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(294808228_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<34, 0, ()>::new(self.address, selector, "external_call_to_assertion_failure", serialized_params).call(self.context) + } + } + + pub fn new_nullifier(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 1, ()>::new(self.address, selector, "new_nullifier", serialized_params).call(self.context) + } + } + + pub fn divide_by_zero(self, denominator: u8) -> u8 { + let serialized_params: [Field; 1] = denominator.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(815932481_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 1, u8>::new(self.address, selector, "divide_by_zero", serialized_params).call(self.context) + } + } + + pub fn emit_public_log(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2033426724_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 0, ()>::new(self.address, selector, "emit_public_log", serialized_params).call(self.context) + } + } + + pub fn raw_l2_to_l1_msg(self, recipient: EthAddress, content: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = recipient.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = content.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3409962923_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 2, ()>::new(self.address, selector, "raw_l2_to_l1_msg", serialized_params).call(self.context) + } + } + + pub fn nested_call_to_nothing_recovers(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1843532057_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<31, 0, ()>::new(self.address, selector, "nested_call_to_nothing_recovers", serialized_params).call(self.context) + } + } + + pub fn assert_calldata_copy_large(self, args: [Field; 300], with_selector: bool) { + let mut serialized_params: [Field; 301] = [0_Field; 301]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 300 * 1] = args.serialize(); + let serialized_member_len: u32 = <[Field; 300] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = with_selector.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2293565755_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<26, 301, ()>::new(self.address, selector, "assert_calldata_copy_large", serialized_params).call(self.context) + } + } + + pub fn set_opcode_really_big_field(self) -> Field { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4095821182_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<27, 0, Field>::new(self.address, selector, "set_opcode_really_big_field", serialized_params).call(self.context) + } + } + + pub fn elliptic_curve_add(self, lhs: Point, rhs: Point) -> Point { + let mut serialized_params: [Field; 6] = [0_Field; 6]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3] = lhs.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 3] = rhs.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1700026912_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<18, 6, Point>::new(self.address, selector, "elliptic_curve_add", serialized_params).call(self.context) + } + } + + pub fn returndata_copy_oracle(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4172530660_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<22, 0, ()>::new(self.address, selector, "returndata_copy_oracle", serialized_params).call(self.context) + } + } + + pub fn set_read_storage_single(self, a: Field) -> Field { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1932358992_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<23, 1, Field>::new(self.address, selector, "set_read_storage_single", serialized_params).call(self.context) + } + } + + pub fn n_new_public_logs(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2907114368_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<17, 1, ()>::new(self.address, selector, "n_new_public_logs", serialized_params).call(self.context) + } + } + + pub fn conditional_move(self, x: [Field; 1], y: [Field; 1], b: bool) -> [Field; 1] { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1 * 1] = x.serialize(); + let serialized_member_len: u32 = <[Field; 1] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1 * 1] = y.serialize(); + let serialized_member_len: u32 = <[Field; 1] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2633971407_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 3, [Field; 1]>::new(self.address, selector, "conditional_move", serialized_params).call(self.context) + } + } + + pub fn set_opcode_small_field(self) -> Field { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3464175345_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<22, 0, Field>::new(self.address, selector, "set_opcode_small_field", serialized_params).call(self.context) + } + } + + pub fn nested_call_to_nothing(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1183868090_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<22, 0, ()>::new(self.address, selector, "nested_call_to_nothing", serialized_params).call(self.context) + } + } + + pub fn nested_call_to_add_with_gas(self, arg_a: Field, arg_b: Field, l2_gas: u32, da_gas: u32) -> Field { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = l2_gas.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = da_gas.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3561659563_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<27, 4, Field>::new(self.address, selector, "nested_call_to_add_with_gas", serialized_params).call(self.context) + } + } + + pub fn create_different_nullifier_in_nested_call(self, nestedAddress: AztecAddress, nullifier: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = nestedAddress.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = nullifier.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1630216043_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<41, 2, ()>::new(self.address, selector, "create_different_nullifier_in_nested_call", serialized_params).call(self.context) + } + } + + pub fn call_fee_juice(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 0, ()>::new(self.address, selector, "call_fee_juice", serialized_params).call(self.context) + } + } + + pub fn get_da_gas_left(self) -> u32 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2319460898_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 0, u32>::new(self.address, selector, "get_da_gas_left", serialized_params).call(self.context) + } + } + + pub fn get_transaction_fee(self) -> Field { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2524054657_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<19, 0, Field>::new(self.address, selector, "get_transaction_fee", serialized_params).call(self.context) + } + } + + pub fn read_storage_single(self) -> Field { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3140392744_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<19, 0, Field>::new(self.address, selector, "read_storage_single", serialized_params).call(self.context) + } + } + + pub fn assert_nullifier_exists(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2810255355_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<23, 1, ()>::new(self.address, selector, "assert_nullifier_exists", serialized_params).call(self.context) + } + } + + pub fn assertion_failure(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3276887878_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<17, 0, ()>::new(self.address, selector, "assertion_failure", serialized_params).call(self.context) + } + } + + pub fn debug_logging(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3667472301_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 0, ()>::new(self.address, selector, "debug_logging", serialized_params).call(self.context) + } + } + + pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> Field { + let serialized_params: [Field; 300 * 1] = arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<26, 300 * 1, Field>::new(self.address, selector, "nested_call_large_calldata", serialized_params).call(self.context) + } + } + + pub fn external_call_to_divide_by_zero_recovers(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2245930342_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<40, 0, ()>::new(self.address, selector, "external_call_to_divide_by_zero_recovers", serialized_params).call(self.context) + } + } + + pub fn set_opcode_u32(self) -> u32 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4045556597_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 0, u32>::new(self.address, selector, "set_opcode_u32", serialized_params).call(self.context) + } + } + + pub fn call_instance_registry(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2336742722_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<22, 0, ()>::new(self.address, selector, "call_instance_registry", serialized_params).call(self.context) + } + } + + pub fn set_storage_single(self, a: Field) { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2230419055_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<18, 1, ()>::new(self.address, selector, "set_storage_single", serialized_params).call(self.context) + } + } + + pub fn nested_call_to_add(self, arg_a: Field, arg_b: Field) -> Field { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(94115833_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<18, 2, Field>::new(self.address, selector, "nested_call_to_add", serialized_params).call(self.context) + } + } + + pub fn revert_oracle(self) -> [Field; 3] { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4147614534_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 0, [Field; 3]>::new(self.address, selector, "revert_oracle", serialized_params).call(self.context) + } + } + + pub fn send_l2_to_l1_msg(self, recipient: EthAddress, content: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = recipient.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = content.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2709402942_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<17, 2, ()>::new(self.address, selector, "send_l2_to_l1_msg", serialized_params).call(self.context) + } + } + + pub fn note_hash_exists(self, note_hash: Field, leaf_index: u64) -> bool { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = note_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = leaf_index.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(671085844_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 2, bool>::new(self.address, selector, "note_hash_exists", serialized_params).call(self.context) + } + } + + pub fn read_storage_map(self, address: AztecAddress) -> u32 { + let serialized_params: [Field; 1] = address.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(711888726_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 1, u32>::new(self.address, selector, "read_storage_map", serialized_params).call(self.context) + } + } + + pub fn elliptic_curve_add_and_double(self) -> Point { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1891218722_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<29, 0, Point>::new(self.address, selector, "elliptic_curve_add_and_double", serialized_params).call(self.context) + } + } + + pub fn read_assert_storage_single(self, a: Field) { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1067389427_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<26, 1, ()>::new(self.address, selector, "read_assert_storage_single", serialized_params).call(self.context) + } + } + + pub fn get_block_number(self) -> u32 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3223336515_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 0, u32>::new(self.address, selector, "get_block_number", serialized_params).call(self.context) + } + } + + pub fn nested_call_to_assert_same(self, arg_a: Field, arg_b: Field) -> Field { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1563037608_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<26, 2, Field>::new(self.address, selector, "nested_call_to_assert_same", serialized_params).call(self.context) + } + } + + pub fn fn_w_large_calldata(self, _arr: [Field; 300]) -> Field { + let serialized_params: [Field; 300 * 1] = _arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3786762676_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<19, 300 * 1, Field>::new(self.address, selector, "fn_w_large_calldata", serialized_params).call(self.context) + } + } + + pub fn get_address(self) -> AztecAddress { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1968200506_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<11, 0, AztecAddress>::new(self.address, selector, "get_address", serialized_params).call(self.context) + } + } + + pub fn set_storage_map(self, to: AztecAddress, amount: u32) -> Field { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = to.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = amount.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1756672898_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<15, 2, Field>::new(self.address, selector, "set_storage_map", serialized_params).call(self.context) + } + } + + pub fn get_version(self) -> Field { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(421038220_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<11, 0, Field>::new(self.address, selector, "get_version", serialized_params).call(self.context) + } + } + + pub fn nested_static_call_to_set_storage(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3861896907_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<33, 0, ()>::new(self.address, selector, "nested_static_call_to_set_storage", serialized_params).call(self.context) + } + } + + pub fn create_same_nullifier_in_nested_call(self, nestedAddress: AztecAddress, nullifier: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = nestedAddress.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = nullifier.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1050471208_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<36, 2, ()>::new(self.address, selector, "create_same_nullifier_in_nested_call", serialized_params).call(self.context) + } + } + + pub fn set_opcode_big_field(self) -> Field { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(497423715_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<20, 0, Field>::new(self.address, selector, "set_opcode_big_field", serialized_params).call(self.context) + } + } + + pub fn u128_addition_overflow(self) -> u128 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2520497807_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<22, 0, u128>::new(self.address, selector, "u128_addition_overflow", serialized_params).call(self.context) + } + } + + pub fn add_u128(self, a: u128, b: u128) -> u128 { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1408352185_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<8, 2, u128>::new(self.address, selector, "add_u128", serialized_params).call(self.context) + } + } + + pub fn get_fee_per_l2_gas(self) -> u128 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(323255525_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<18, 0, u128>::new(self.address, selector, "get_fee_per_l2_gas", serialized_params).call(self.context) + } + } + + pub fn n_storage_writes(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2323221248_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<16, 1, ()>::new(self.address, selector, "n_storage_writes", serialized_params).call(self.context) + } + } + + pub fn set_opcode_u8(self) -> u8 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3068438800_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 0, u8>::new(self.address, selector, "set_opcode_u8", serialized_params).call(self.context) + } + } + + pub fn n_new_note_hashes(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1938641640_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<17, 1, ()>::new(self.address, selector, "n_new_note_hashes", serialized_params).call(self.context) + } + } + + pub fn nested_call_to_add_n_times_different_addresses(self, addrs: [AztecAddress; 23]) { + let serialized_params: [Field; 23 * 1] = addrs.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2936248969_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<46, 23 * 1, ()>::new(self.address, selector, "nested_call_to_add_n_times_different_addresses", serialized_params).call(self.context) + } + } + } + + impl CallSelf<&mut aztec::context::PrivateContext> { + pub fn enqueue_public_from_private(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2771384488_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + } + + pub struct CallSelfStatic { + pub address: AztecAddress, + pub context: Context, + } + + impl CallSelfStatic { + pub fn set_opcode_u8_view(self) -> u8 { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(643109956_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicStaticCall::<18, 0, u8>::new(self.address, selector, "set_opcode_u8_view", serialized_params).view(self.context) + } + } + } + + pub struct EnqueueSelf { + pub address: AztecAddress, + pub context: Context, + } + + impl EnqueueSelf<&mut aztec::context::PrivateContext> { + pub fn assert_calldata_copy(self, args: [Field; 3], with_selector: bool) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3 * 1] = args.serialize(); + let serialized_member_len: u32 = <[Field; 3] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = with_selector.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3853740100_Field); + let calldata: [Field; 1 + 4] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_chain_id(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1458572288_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_args_hash(self, _a: u8, _fields: [Field; 3]) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = _a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 3 * 1] = _fields.serialize(); + let serialized_member_len: u32 = <[Field; 3] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1608415988_Field); + let calldata: [Field; 1 + 4] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn external_call_to_divide_by_zero(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3880450065_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn n_new_nullifiers(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(592684400_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn new_note_hash(self, note_hash: Field) { + let serialized_params: [Field; 1] = note_hash.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1524332459_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nullifier_collision(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2417179850_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_l2_gas_left(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1635524210_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn l1_to_l2_msg_exists(self, msg_hash: Field, msg_leaf_index: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = msg_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = msg_leaf_index.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3972971575_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn add_storage_map(self, to: AztecAddress, amount: u32) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = to.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = amount.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2606877757_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn bulk_testing(self, args_field: [Field; 10], args_u8: [u8; 10], get_instance_for_address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, skip_strictly_limited_side_effects: bool) { + let mut serialized_params: [Field; 25] = [0_Field; 25]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 10 * 1] = args_field.serialize(); + let serialized_member_len: u32 = <[Field; 10] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 10 * 1] = args_u8.serialize(); + let serialized_member_len: u32 = <[u8; 10] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = get_instance_for_address.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_deployer.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_class_id.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_initialization_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = skip_strictly_limited_side_effects.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_6: u32 = i + offset; + serialized_params[i_6] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(43639379_Field); + let calldata: [Field; 1 + 25] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn add_args_return(self, arg_a: Field, arg_b: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2858633377_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn variable_base_msm(self, scalar_lo: Field, scalar_hi: Field, scalar2_lo: Field, scalar2_hi: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = scalar_lo.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = scalar_hi.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = scalar2_lo.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = scalar2_hi.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2931784034_Field); + let calldata: [Field; 1 + 4] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn test_get_contract_instance_matches(self, address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = address.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_deployer.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_class_id.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = expected_initialization_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2723912183_Field); + let calldata: [Field; 1 + 4] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_sender(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(301170519_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn n_new_l2_to_l1_msgs(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3921925917_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_storage_list(self, a: Field, b: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1745164739_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn pedersen_commit(self, x: Field, y: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = x.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = y.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2484465428_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nullifier_exists(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2051407563_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn read_storage_list(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1727615163_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn emit_nullifier_and_check(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2367487025_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn assert_same(self, arg_a: Field, arg_b: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(290442984_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_fee_per_da_gas(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(514475538_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn modulo2(self, a: u64) { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(222531562_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nested_static_call_to_add(self, arg_a: Field, arg_b: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1362946309_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn to_le_bits(self, input: Field) { + let serialized_params: [Field; 1] = input.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2961959597_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn call_auth_registry(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1225767423_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_opcode_u64(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1435480431_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn return_oracle(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3794636397_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn test_get_contract_instance(self, address: AztecAddress) { + let serialized_params: [Field; 1] = address.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2488367864_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_timestamp(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(448989811_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn to_le_bytes(self, input: Field) { + let serialized_params: [Field; 1] = input.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1975931334_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn external_call_to_assertion_failure(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(294808228_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn new_nullifier(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn divide_by_zero(self, denominator: u8) { + let serialized_params: [Field; 1] = denominator.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(815932481_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn emit_public_log(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2033426724_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn raw_l2_to_l1_msg(self, recipient: EthAddress, content: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = recipient.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = content.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3409962923_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nested_call_to_nothing_recovers(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1843532057_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn assert_calldata_copy_large(self, args: [Field; 300], with_selector: bool) { + let mut serialized_params: [Field; 301] = [0_Field; 301]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 300 * 1] = args.serialize(); + let serialized_member_len: u32 = <[Field; 300] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = with_selector.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2293565755_Field); + let calldata: [Field; 1 + 301] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_opcode_really_big_field(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4095821182_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn elliptic_curve_add(self, lhs: Point, rhs: Point) { + let mut serialized_params: [Field; 6] = [0_Field; 6]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 3] = lhs.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 3] = rhs.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1700026912_Field); + let calldata: [Field; 1 + 6] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn returndata_copy_oracle(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4172530660_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_read_storage_single(self, a: Field) { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1932358992_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn n_new_public_logs(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2907114368_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn conditional_move(self, x: [Field; 1], y: [Field; 1], b: bool) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1 * 1] = x.serialize(); + let serialized_member_len: u32 = <[Field; 1] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1 * 1] = y.serialize(); + let serialized_member_len: u32 = <[Field; 1] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2633971407_Field); + let calldata: [Field; 1 + 3] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_opcode_small_field(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3464175345_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nested_call_to_nothing(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1183868090_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nested_call_to_add_with_gas(self, arg_a: Field, arg_b: Field, l2_gas: u32, da_gas: u32) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = l2_gas.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = da_gas.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(3561659563_Field); + let calldata: [Field; 1 + 4] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn create_different_nullifier_in_nested_call(self, nestedAddress: AztecAddress, nullifier: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = nestedAddress.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = nullifier.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1630216043_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn call_fee_juice(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_da_gas_left(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2319460898_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_transaction_fee(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2524054657_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn read_storage_single(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3140392744_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn assert_nullifier_exists(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2810255355_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn assertion_failure(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3276887878_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn debug_logging(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3667472301_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nested_call_large_calldata(self, arr: [Field; 300]) { + let serialized_params: [Field; 300 * 1] = arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); + let calldata: [Field; 1 + (300 * 1)] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn external_call_to_divide_by_zero_recovers(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2245930342_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_opcode_u32(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4045556597_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn call_instance_registry(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2336742722_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_storage_single(self, a: Field) { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2230419055_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nested_call_to_add(self, arg_a: Field, arg_b: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(94115833_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn revert_oracle(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(4147614534_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn send_l2_to_l1_msg(self, recipient: EthAddress, content: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = recipient.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = content.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(2709402942_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn note_hash_exists(self, note_hash: Field, leaf_index: u64) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = note_hash.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = leaf_index.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(671085844_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn read_storage_map(self, address: AztecAddress) { + let serialized_params: [Field; 1] = address.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(711888726_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn elliptic_curve_add_and_double(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1891218722_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn read_assert_storage_single(self, a: Field) { + let serialized_params: [Field; 1] = a.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1067389427_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_block_number(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3223336515_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nested_call_to_assert_same(self, arg_a: Field, arg_b: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = arg_a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = arg_b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1563037608_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_w_large_calldata(self, _arr: [Field; 300]) { + let serialized_params: [Field; 300 * 1] = _arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3786762676_Field); + let calldata: [Field; 1 + (300 * 1)] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_address(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(1968200506_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_storage_map(self, to: AztecAddress, amount: u32) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = to.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = amount.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1756672898_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_version(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(421038220_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nested_static_call_to_set_storage(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3861896907_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn create_same_nullifier_in_nested_call(self, nestedAddress: AztecAddress, nullifier: Field) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = nestedAddress.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = nullifier.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1050471208_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_opcode_big_field(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(497423715_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn u128_addition_overflow(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2520497807_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn add_u128(self, a: u128, b: u128) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = a.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = b.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: FunctionSelector = FunctionSelector::from_field(1408352185_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn get_fee_per_l2_gas(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(323255525_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn n_storage_writes(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2323221248_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_opcode_u8(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(3068438800_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn n_new_note_hashes(self, num: u32) { + let serialized_params: [Field; 1] = num.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(1938641640_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn nested_call_to_add_n_times_different_addresses(self, addrs: [AztecAddress; 23]) { + let serialized_params: [Field; 23 * 1] = addrs.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(2936248969_Field); + let calldata: [Field; 1 + (23 * 1)] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + } + + pub struct EnqueueSelfStatic { + pub address: AztecAddress, + pub context: Context, + } + + impl EnqueueSelfStatic<&mut aztec::context::PrivateContext> { + pub fn set_opcode_u8_view(self) { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(643109956_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, true, false); + } + } + + pub struct CallSelfUtility { + pub address: AztecAddress, + } + + pub struct CallInternal { + pub context: Context, + } + + pub unconstrained fn public_dispatch(selector: Field) { + if selector == 2230419055_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__set_storage_single(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3140392744_Field { + let return_value: [Field; 1] = __aztec_nr_internals__read_storage_single().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1067389427_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__read_assert_storage_single(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1932358992_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__set_read_storage_single(arg0).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1745164739_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__set_storage_list(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1727615163_Field { + let return_value: [Field; 2 * 1] = __aztec_nr_internals__read_storage_list().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1756672898_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: u32 = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__set_storage_map(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2606877757_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: u32 = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__add_storage_map(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 711888726_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__read_storage_map(arg0).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2858633377_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__add_args_return(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3068438800_Field { + let return_value: [Field; 1] = __aztec_nr_internals__set_opcode_u8().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 643109956_Field { + let return_value: [Field; 1] = __aztec_nr_internals__set_opcode_u8_view().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 4045556597_Field { + let return_value: [Field; 1] = __aztec_nr_internals__set_opcode_u32().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1435480431_Field { + let return_value: [Field; 1] = __aztec_nr_internals__set_opcode_u64().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3464175345_Field { + let return_value: [Field; 1] = __aztec_nr_internals__set_opcode_small_field().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 497423715_Field { + let return_value: [Field; 1] = __aztec_nr_internals__set_opcode_big_field().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 4095821182_Field { + let return_value: [Field; 1] = __aztec_nr_internals__set_opcode_really_big_field().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1408352185_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: u128 = ::stream_deserialize(&mut reader); + let arg1: u128 = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__add_u128(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 222531562_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__modulo2(arg0).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1700026912_Field { + let input_calldata: [Field; 6] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<6> = aztec::protocol::utils::reader::Reader::<6>::new(input_calldata); + let arg0: Point = ::stream_deserialize(&mut reader); + let arg1: Point = ::stream_deserialize(&mut reader); + let return_value: [Field; 3] = __aztec_nr_internals__elliptic_curve_add(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1891218722_Field { + let return_value: [Field; 3] = __aztec_nr_internals__elliptic_curve_add_and_double().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2931784034_Field { + let input_calldata: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + ::N) + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<4> = aztec::protocol::utils::reader::Reader::<4>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + let arg2: Field = ::stream_deserialize(&mut reader); + let arg3: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 3] = __aztec_nr_internals__variable_base_msm(arg0, arg1, arg2, arg3).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2484465428_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 3] = __aztec_nr_internals__pedersen_commit(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2633971407_Field { + let input_calldata: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (<[Field; 1] as Serialize>::N + <[Field; 1] as Serialize>::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<3> = aztec::protocol::utils::reader::Reader::<3>::new(input_calldata); + let arg0: [Field; 1] = <[Field; 1] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let arg1: [Field; 1] = <[Field; 1] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let arg2: bool = ::stream_deserialize(&mut reader); + let return_value: [Field; 1 * 1] = __aztec_nr_internals__conditional_move(arg0, arg1, arg2).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2520497807_Field { + let return_value: [Field; 1] = __aztec_nr_internals__u128_addition_overflow().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1975931334_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 10 * 1] = __aztec_nr_internals__to_le_bytes(arg0).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2961959597_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 16 * 1] = __aztec_nr_internals__to_le_bits(arg0).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3276887878_Field { + __aztec_nr_internals__assertion_failure(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 294808228_Field { + __aztec_nr_internals__external_call_to_assertion_failure(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 815932481_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u8 = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__divide_by_zero(arg0).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3880450065_Field { + __aztec_nr_internals__external_call_to_divide_by_zero(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2245930342_Field { + __aztec_nr_internals__external_call_to_divide_by_zero_recovers(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3667472301_Field { + __aztec_nr_internals__debug_logging(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 290442984_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__assert_same(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3853740100_Field { + let input_calldata: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 3] as Serialize>::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<4> = aztec::protocol::utils::reader::Reader::<4>::new(input_calldata); + let arg0: [Field; 3] = <[Field; 3] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let arg1: bool = ::stream_deserialize(&mut reader); + __aztec_nr_internals__assert_calldata_copy(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2293565755_Field { + let input_calldata: [Field; 301] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 300] as Serialize>::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<301> = aztec::protocol::utils::reader::Reader::<301>::new(input_calldata); + let arg0: [Field; 300] = <[Field; 300] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let arg1: bool = ::stream_deserialize(&mut reader); + __aztec_nr_internals__assert_calldata_copy_large(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 4172530660_Field { + __aztec_nr_internals__returndata_copy_oracle(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3794636397_Field { + let return_value: [Field; 3 * 1] = __aztec_nr_internals__return_oracle().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 4147614534_Field { + let return_value: [Field; 3 * 1] = __aztec_nr_internals__revert_oracle().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2488367864_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + __aztec_nr_internals__test_get_contract_instance(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2723912183_Field { + let input_calldata: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + ::N) + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<4> = aztec::protocol::utils::reader::Reader::<4>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: AztecAddress = ::stream_deserialize(&mut reader); + let arg2: ContractClassId = ::stream_deserialize(&mut reader); + let arg3: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__test_get_contract_instance_matches(arg0, arg1, arg2, arg3); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1968200506_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_address().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 301170519_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_sender().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2524054657_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_transaction_fee().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1458572288_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_chain_id().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 421038220_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_version().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3223336515_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_block_number().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 448989811_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_timestamp().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 323255525_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_fee_per_l2_gas().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 514475538_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_fee_per_da_gas().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1635524210_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_l2_gas_left().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2319460898_Field { + let return_value: [Field; 1] = __aztec_nr_internals__get_da_gas_left().serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1608415988_Field { + let input_calldata: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ::N + <[Field; 3] as Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<4> = aztec::protocol::utils::reader::Reader::<4>::new(input_calldata); + let arg0: u8 = ::stream_deserialize(&mut reader); + let arg1: [Field; 3] = <[Field; 3] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__get_args_hash(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2033426724_Field { + __aztec_nr_internals__emit_public_log(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 671085844_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: u64 = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__note_hash_exists(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1524332459_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__new_note_hash(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3648851082_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__new_nullifier(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2323221248_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u32 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__n_storage_writes(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1938641640_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u32 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__n_new_note_hashes(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 592684400_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u32 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__n_new_nullifiers(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3921925917_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u32 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__n_new_l2_to_l1_msgs(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3409962923_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: EthAddress = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__raw_l2_to_l1_msg(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2907114368_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u32 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__n_new_public_logs(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2051407563_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__nullifier_exists(arg0).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2810255355_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__assert_nullifier_exists(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2367487025_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__emit_nullifier_and_check(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2417179850_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__nullifier_collision(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3972971575_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__l1_to_l2_msg_exists(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2709402942_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: EthAddress = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__send_l2_to_l1_msg(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1183868090_Field { + __aztec_nr_internals__nested_call_to_nothing(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1843532057_Field { + __aztec_nr_internals__nested_call_to_nothing_recovers(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3561659563_Field { + let input_calldata: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + ::N) + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<4> = aztec::protocol::utils::reader::Reader::<4>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + let arg2: u32 = ::stream_deserialize(&mut reader); + let arg3: u32 = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__nested_call_to_add_with_gas(arg0, arg1, arg2, arg3).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 94115833_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__nested_call_to_add(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2936248969_Field { + let input_calldata: [Field; 23 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[AztecAddress; 23] as Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<23 * 1> = aztec::protocol::utils::reader::Reader::<23 * 1>::new(input_calldata); + let arg0: [AztecAddress; 23] = <[AztecAddress; 23] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + __aztec_nr_internals__nested_call_to_add_n_times_different_addresses(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1362946309_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__nested_static_call_to_add(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3861896907_Field { + __aztec_nr_internals__nested_static_call_to_set_storage(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1050471208_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__create_same_nullifier_in_nested_call(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1630216043_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__create_different_nullifier_in_nested_call(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1563037608_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: Field = ::stream_deserialize(&mut reader); + let arg1: Field = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__nested_call_to_assert_same(arg0, arg1).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3786762676_Field { + let input_calldata: [Field; 300 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 300] as Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<300 * 1> = aztec::protocol::utils::reader::Reader::<300 * 1>::new(input_calldata); + let arg0: [Field; 300] = <[Field; 300] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__fn_w_large_calldata(arg0).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 14812432_Field { + let input_calldata: [Field; 300 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 300] as Serialize>::N); + let mut reader: aztec::protocol::utils::reader::Reader<300 * 1> = aztec::protocol::utils::reader::Reader::<300 * 1>::new(input_calldata); + let arg0: [Field; 300] = <[Field; 300] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let return_value: [Field; 1] = __aztec_nr_internals__nested_call_large_calldata(arg0).serialize(); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2734888597_Field { + __aztec_nr_internals__call_fee_juice(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1225767423_Field { + __aztec_nr_internals__call_auth_registry(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2336742722_Field { + __aztec_nr_internals__call_instance_registry(); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 43639379_Field { + let input_calldata: [Field; 25] = aztec::oracle::avm::calldata_copy(1_u32, (((((<[Field; 10] as Serialize>::N + <[u8; 10] as Serialize>::N) + ::N) + ::N) + ::N) + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<25> = aztec::protocol::utils::reader::Reader::<25>::new(input_calldata); + let arg0: [Field; 10] = <[Field; 10] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let arg1: [u8; 10] = <[u8; 10] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let arg2: AztecAddress = ::stream_deserialize(&mut reader); + let arg3: AztecAddress = ::stream_deserialize(&mut reader); + let arg4: ContractClassId = ::stream_deserialize(&mut reader); + let arg5: Field = ::stream_deserialize(&mut reader); + let arg6: bool = ::stream_deserialize(&mut reader); + __aztec_nr_internals__bulk_testing(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + aztec::oracle::avm::avm_return([].as_slice()); + }; + panic(f"Unknown selector {selector}") + } + + pub struct add_args_return_parameters { + pub arg_a: Field, + pub arg_b: Field, + } + + pub struct add_storage_map_parameters { + pub to: AztecAddress, + pub amount: u32, + } + + pub struct add_u128_parameters { + pub a: u128, + pub b: u128, + } + + pub struct assert_calldata_copy_large_parameters { + pub args: [Field; 300], + pub with_selector: bool, + } + + pub struct assert_calldata_copy_parameters { + pub args: [Field; 3], + pub with_selector: bool, + } + + pub struct assert_nullifier_exists_parameters { + pub nullifier: Field, + } + + pub struct assert_same_parameters { + pub arg_a: Field, + pub arg_b: Field, + } + + pub struct assertion_failure_parameters { + } + + pub struct bulk_testing_parameters { + pub args_field: [Field; 10], + pub args_u8: [u8; 10], + pub get_instance_for_address: AztecAddress, + pub expected_deployer: AztecAddress, + pub expected_class_id: ContractClassId, + pub expected_initialization_hash: Field, + pub skip_strictly_limited_side_effects: bool, + } + + pub struct call_auth_registry_parameters { + } + + pub struct call_fee_juice_parameters { + } + + pub struct call_instance_registry_parameters { + } + + pub struct conditional_move_parameters { + pub x: [Field; 1], + pub y: [Field; 1], + pub b: bool, + } + + pub struct create_different_nullifier_in_nested_call_parameters { + pub nestedAddress: AztecAddress, + pub nullifier: Field, + } + + pub struct create_same_nullifier_in_nested_call_parameters { + pub nestedAddress: AztecAddress, + pub nullifier: Field, + } + + pub struct debug_logging_parameters { + } + + pub struct divide_by_zero_parameters { + pub denominator: u8, + } + + pub struct elliptic_curve_add_and_double_parameters { + } + + pub struct elliptic_curve_add_parameters { + pub lhs: Point, + pub rhs: Point, + } + + pub struct emit_nullifier_and_check_parameters { + pub nullifier: Field, + } + + pub struct emit_public_log_parameters { + } + + pub struct enqueue_public_from_private_parameters { + } + + pub struct external_call_to_assertion_failure_parameters { + } + + pub struct external_call_to_divide_by_zero_parameters { + } + + pub struct external_call_to_divide_by_zero_recovers_parameters { + } + + pub struct fn_w_large_calldata_parameters { + pub _arr: [Field; 300], + } + + pub struct get_address_parameters { + } + + pub struct get_args_hash_parameters { + pub _a: u8, + pub _fields: [Field; 3], + } + + pub struct get_block_number_parameters { + } + + pub struct get_chain_id_parameters { + } + + pub struct get_da_gas_left_parameters { + } + + pub struct get_fee_per_da_gas_parameters { + } + + pub struct get_fee_per_l2_gas_parameters { + } + + pub struct get_l2_gas_left_parameters { + } + + pub struct get_sender_parameters { + } + + pub struct get_timestamp_parameters { + } + + pub struct get_transaction_fee_parameters { + } + + pub struct get_version_parameters { + } + + pub struct l1_to_l2_msg_exists_parameters { + pub msg_hash: Field, + pub msg_leaf_index: Field, + } + + pub struct modulo2_parameters { + pub a: u64, + } + + pub struct n_new_l2_to_l1_msgs_parameters { + pub num: u32, + } + + pub struct n_new_note_hashes_parameters { + pub num: u32, + } + + pub struct n_new_nullifiers_parameters { + pub num: u32, + } + + pub struct n_new_public_logs_parameters { + pub num: u32, + } + + pub struct n_storage_writes_parameters { + pub num: u32, + } + + pub struct nested_call_large_calldata_parameters { + pub arr: [Field; 300], + } + + pub struct nested_call_to_add_n_times_different_addresses_parameters { + pub addrs: [AztecAddress; 23], + } + + pub struct nested_call_to_add_parameters { + pub arg_a: Field, + pub arg_b: Field, + } + + pub struct nested_call_to_add_with_gas_parameters { + pub arg_a: Field, + pub arg_b: Field, + pub l2_gas: u32, + pub da_gas: u32, + } + + pub struct nested_call_to_assert_same_parameters { + pub arg_a: Field, + pub arg_b: Field, + } + + pub struct nested_call_to_nothing_parameters { + } + + pub struct nested_call_to_nothing_recovers_parameters { + } + + pub struct nested_static_call_to_add_parameters { + pub arg_a: Field, + pub arg_b: Field, + } + + pub struct nested_static_call_to_set_storage_parameters { + } + + pub struct new_note_hash_parameters { + pub note_hash: Field, + } + + pub struct new_nullifier_parameters { + pub nullifier: Field, + } + + pub struct note_hash_exists_parameters { + pub note_hash: Field, + pub leaf_index: u64, + } + + pub struct nullifier_collision_parameters { + pub nullifier: Field, + } + + pub struct nullifier_exists_parameters { + pub nullifier: Field, + } + + pub struct pedersen_commit_parameters { + pub x: Field, + pub y: Field, + } + + pub struct raw_l2_to_l1_msg_parameters { + pub recipient: EthAddress, + pub content: Field, + } + + pub struct read_assert_storage_single_parameters { + pub a: Field, + } + + pub struct read_storage_list_parameters { + } + + pub struct read_storage_map_parameters { + pub address: AztecAddress, + } + + pub struct read_storage_single_parameters { + } + + pub struct return_oracle_parameters { + } + + pub struct returndata_copy_oracle_parameters { + } + + pub struct revert_oracle_parameters { + } + + pub struct send_l2_to_l1_msg_parameters { + pub recipient: EthAddress, + pub content: Field, + } + + pub struct set_opcode_big_field_parameters { + } + + pub struct set_opcode_really_big_field_parameters { + } + + pub struct set_opcode_small_field_parameters { + } + + pub struct set_opcode_u32_parameters { + } + + pub struct set_opcode_u64_parameters { + } + + pub struct set_opcode_u8_parameters { + } + + pub struct set_opcode_u8_view_parameters { + } + + pub struct set_read_storage_single_parameters { + pub a: Field, + } + + pub struct set_storage_list_parameters { + pub a: Field, + pub b: Field, + } + + pub struct set_storage_map_parameters { + pub to: AztecAddress, + pub amount: u32, + } + + pub struct set_storage_single_parameters { + pub a: Field, + } + + pub struct test_get_contract_instance_matches_parameters { + pub address: AztecAddress, + pub expected_deployer: AztecAddress, + pub expected_class_id: ContractClassId, + pub expected_initialization_hash: Field, + } + + pub struct test_get_contract_instance_parameters { + pub address: AztecAddress, + } + + pub struct to_le_bits_parameters { + pub input: Field, + } + + pub struct to_le_bytes_parameters { + pub input: Field, + } + + pub struct u128_addition_overflow_parameters { + } + + pub struct variable_base_msm_parameters { + pub scalar_lo: Field, + pub scalar_hi: Field, + pub scalar2_lo: Field, + pub scalar2_hi: Field, + } + + #[abi(functions)] + pub struct add_args_return_abi { + parameters: add_args_return_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct add_storage_map_abi { + parameters: add_storage_map_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct add_u128_abi { + parameters: add_u128_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct assert_calldata_copy_abi { + parameters: assert_calldata_copy_parameters, + } + + #[abi(functions)] + pub struct assert_calldata_copy_large_abi { + parameters: assert_calldata_copy_large_parameters, + } + + #[abi(functions)] + pub struct assert_nullifier_exists_abi { + parameters: assert_nullifier_exists_parameters, + } + + #[abi(functions)] + pub struct assert_same_abi { + parameters: assert_same_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct assertion_failure_abi { + parameters: assertion_failure_parameters, + } + + #[abi(functions)] + pub struct bulk_testing_abi { + parameters: bulk_testing_parameters, + } + + #[abi(functions)] + pub struct call_auth_registry_abi { + parameters: call_auth_registry_parameters, + } + + #[abi(functions)] + pub struct call_fee_juice_abi { + parameters: call_fee_juice_parameters, + } + + #[abi(functions)] + pub struct call_instance_registry_abi { + parameters: call_instance_registry_parameters, + } + + #[abi(functions)] + pub struct conditional_move_abi { + parameters: conditional_move_parameters, + return_type: [Field; 1], + } + + #[abi(functions)] + pub struct create_different_nullifier_in_nested_call_abi { + parameters: create_different_nullifier_in_nested_call_parameters, + } + + #[abi(functions)] + pub struct create_same_nullifier_in_nested_call_abi { + parameters: create_same_nullifier_in_nested_call_parameters, + } + + #[abi(functions)] + pub struct debug_logging_abi { + parameters: debug_logging_parameters, + } + + #[abi(functions)] + pub struct divide_by_zero_abi { + parameters: divide_by_zero_parameters, + return_type: u8, + } + + #[abi(functions)] + pub struct elliptic_curve_add_abi { + parameters: elliptic_curve_add_parameters, + return_type: Point, + } + + #[abi(functions)] + pub struct elliptic_curve_add_and_double_abi { + parameters: elliptic_curve_add_and_double_parameters, + return_type: Point, + } + + #[abi(functions)] + pub struct emit_nullifier_and_check_abi { + parameters: emit_nullifier_and_check_parameters, + } + + #[abi(functions)] + pub struct emit_public_log_abi { + parameters: emit_public_log_parameters, + } + + #[abi(functions)] + pub struct enqueue_public_from_private_abi { + parameters: enqueue_public_from_private_parameters, + } + + #[abi(functions)] + pub struct external_call_to_assertion_failure_abi { + parameters: external_call_to_assertion_failure_parameters, + } + + #[abi(functions)] + pub struct external_call_to_divide_by_zero_abi { + parameters: external_call_to_divide_by_zero_parameters, + } + + #[abi(functions)] + pub struct external_call_to_divide_by_zero_recovers_abi { + parameters: external_call_to_divide_by_zero_recovers_parameters, + } + + #[abi(functions)] + pub struct fn_w_large_calldata_abi { + parameters: fn_w_large_calldata_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct get_address_abi { + parameters: get_address_parameters, + return_type: AztecAddress, + } + + #[abi(functions)] + pub struct get_args_hash_abi { + parameters: get_args_hash_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct get_block_number_abi { + parameters: get_block_number_parameters, + return_type: u32, + } + + #[abi(functions)] + pub struct get_chain_id_abi { + parameters: get_chain_id_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct get_da_gas_left_abi { + parameters: get_da_gas_left_parameters, + return_type: u32, + } + + #[abi(functions)] + pub struct get_fee_per_da_gas_abi { + parameters: get_fee_per_da_gas_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct get_fee_per_l2_gas_abi { + parameters: get_fee_per_l2_gas_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct get_l2_gas_left_abi { + parameters: get_l2_gas_left_parameters, + return_type: u32, + } + + #[abi(functions)] + pub struct get_sender_abi { + parameters: get_sender_parameters, + return_type: AztecAddress, + } + + #[abi(functions)] + pub struct get_timestamp_abi { + parameters: get_timestamp_parameters, + return_type: u64, + } + + #[abi(functions)] + pub struct get_transaction_fee_abi { + parameters: get_transaction_fee_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct get_version_abi { + parameters: get_version_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct l1_to_l2_msg_exists_abi { + parameters: l1_to_l2_msg_exists_parameters, + return_type: bool, + } + + #[abi(functions)] + pub struct modulo2_abi { + parameters: modulo2_parameters, + return_type: u64, + } + + #[abi(functions)] + pub struct n_new_l2_to_l1_msgs_abi { + parameters: n_new_l2_to_l1_msgs_parameters, + } + + #[abi(functions)] + pub struct n_new_note_hashes_abi { + parameters: n_new_note_hashes_parameters, + } + + #[abi(functions)] + pub struct n_new_nullifiers_abi { + parameters: n_new_nullifiers_parameters, + } + + #[abi(functions)] + pub struct n_new_public_logs_abi { + parameters: n_new_public_logs_parameters, + } + + #[abi(functions)] + pub struct n_storage_writes_abi { + parameters: n_storage_writes_parameters, + } + + #[abi(functions)] + pub struct nested_call_large_calldata_abi { + parameters: nested_call_large_calldata_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct nested_call_to_add_abi { + parameters: nested_call_to_add_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct nested_call_to_add_n_times_different_addresses_abi { + parameters: nested_call_to_add_n_times_different_addresses_parameters, + } + + #[abi(functions)] + pub struct nested_call_to_add_with_gas_abi { + parameters: nested_call_to_add_with_gas_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct nested_call_to_assert_same_abi { + parameters: nested_call_to_assert_same_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct nested_call_to_nothing_abi { + parameters: nested_call_to_nothing_parameters, + } + + #[abi(functions)] + pub struct nested_call_to_nothing_recovers_abi { + parameters: nested_call_to_nothing_recovers_parameters, + } + + #[abi(functions)] + pub struct nested_static_call_to_add_abi { + parameters: nested_static_call_to_add_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct nested_static_call_to_set_storage_abi { + parameters: nested_static_call_to_set_storage_parameters, + } + + #[abi(functions)] + pub struct new_note_hash_abi { + parameters: new_note_hash_parameters, + } + + #[abi(functions)] + pub struct new_nullifier_abi { + parameters: new_nullifier_parameters, + } + + #[abi(functions)] + pub struct note_hash_exists_abi { + parameters: note_hash_exists_parameters, + return_type: bool, + } + + #[abi(functions)] + pub struct nullifier_collision_abi { + parameters: nullifier_collision_parameters, + } + + #[abi(functions)] + pub struct nullifier_exists_abi { + parameters: nullifier_exists_parameters, + return_type: bool, + } + + #[abi(functions)] + pub struct pedersen_commit_abi { + parameters: pedersen_commit_parameters, + return_type: Point, + } + + #[abi(functions)] + pub struct raw_l2_to_l1_msg_abi { + parameters: raw_l2_to_l1_msg_parameters, + } + + #[abi(functions)] + pub struct read_assert_storage_single_abi { + parameters: read_assert_storage_single_parameters, + } + + #[abi(functions)] + pub struct read_storage_list_abi { + parameters: read_storage_list_parameters, + return_type: [Field; 2], + } + + #[abi(functions)] + pub struct read_storage_map_abi { + parameters: read_storage_map_parameters, + return_type: u32, + } + + #[abi(functions)] + pub struct read_storage_single_abi { + parameters: read_storage_single_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct return_oracle_abi { + parameters: return_oracle_parameters, + return_type: [Field; 3], + } + + #[abi(functions)] + pub struct returndata_copy_oracle_abi { + parameters: returndata_copy_oracle_parameters, + } + + #[abi(functions)] + pub struct revert_oracle_abi { + parameters: revert_oracle_parameters, + return_type: [Field; 3], + } + + #[abi(functions)] + pub struct send_l2_to_l1_msg_abi { + parameters: send_l2_to_l1_msg_parameters, + } + + #[abi(functions)] + pub struct set_opcode_big_field_abi { + parameters: set_opcode_big_field_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct set_opcode_really_big_field_abi { + parameters: set_opcode_really_big_field_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct set_opcode_small_field_abi { + parameters: set_opcode_small_field_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct set_opcode_u32_abi { + parameters: set_opcode_u32_parameters, + return_type: u32, + } + + #[abi(functions)] + pub struct set_opcode_u64_abi { + parameters: set_opcode_u64_parameters, + return_type: u64, + } + + #[abi(functions)] + pub struct set_opcode_u8_abi { + parameters: set_opcode_u8_parameters, + return_type: u8, + } + + #[abi(functions)] + pub struct set_opcode_u8_view_abi { + parameters: set_opcode_u8_view_parameters, + return_type: u8, + } + + #[abi(functions)] + pub struct set_read_storage_single_abi { + parameters: set_read_storage_single_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct set_storage_list_abi { + parameters: set_storage_list_parameters, + } + + #[abi(functions)] + pub struct set_storage_map_abi { + parameters: set_storage_map_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct set_storage_single_abi { + parameters: set_storage_single_parameters, + } + + #[abi(functions)] + pub struct test_get_contract_instance_abi { + parameters: test_get_contract_instance_parameters, + } + + #[abi(functions)] + pub struct test_get_contract_instance_matches_abi { + parameters: test_get_contract_instance_matches_parameters, + } + + #[abi(functions)] + pub struct to_le_bits_abi { + parameters: to_le_bits_parameters, + return_type: [bool; 16], + } + + #[abi(functions)] + pub struct to_le_bytes_abi { + parameters: to_le_bytes_parameters, + return_type: [u8; 10], + } + + #[abi(functions)] + pub struct u128_addition_overflow_abi { + parameters: u128_addition_overflow_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct variable_base_msm_abi { + parameters: variable_base_msm_parameters, + return_type: Point, + } + + fn __aztec_nr_internals__enqueue_public_from_private(inputs: aztec::context::inputs::PrivateContextInputs) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility> = { + let serialized_params: [Field; 0] = []; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: aztec::context::PrivateContext = aztec::context::PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut aztec::context::PrivateContext> = Storage::<&mut aztec::context::PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut aztec::context::PrivateContext> = CallSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut aztec::context::PrivateContext> = EnqueueSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut aztec::context::PrivateContext> = CallSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut aztec::context::PrivateContext> = EnqueueSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut aztec::context::PrivateContext> = CallInternal::<&mut aztec::context::PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + self.enqueue_self_static.set_opcode_u8_view(); + self.enqueue_self.set_read_storage_single(5_Field); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + unconstrained fn __aztec_nr_internals__add_args_return(arg_a: Field, arg_b: Field) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + add(arg_a, arg_b) + } + } + + unconstrained fn __aztec_nr_internals__add_storage_map(to: AztecAddress, amount: u32) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _add_storage_map(self.storage, to, amount) + } + } + + unconstrained fn __aztec_nr_internals__add_u128(a: u128, b: u128) -> pub u128 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + a + b + } + } + + unconstrained fn __aztec_nr_internals__assert_calldata_copy(args: [Field; 3], with_selector: bool) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 3] as Serialize>::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let offset: u32 = with_selector as u32; + let cd: [Field; 3] = aztec::oracle::avm::calldata_copy(offset, 3_u32); + assert(cd == args, "Calldata copy failed"); + } + } + + unconstrained fn __aztec_nr_internals__assert_calldata_copy_large(args: [Field; 300], with_selector: bool) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 301] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 300] as Serialize>::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let offset: u32 = with_selector as u32; + let cd: [Field; 300] = aztec::oracle::avm::calldata_copy(offset, 300_u32); + assert(cd == args, "Calldata copy failed"); + } + } + + unconstrained fn __aztec_nr_internals__assert_nullifier_exists(nullifier: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + assert(self.context.nullifier_exists_unsafe(nullifier, self.address), "Nullifier doesn't exist!"); + } + } + + unconstrained fn __aztec_nr_internals__assert_same(arg_a: Field, arg_b: Field) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + assert(arg_a == arg_b, "Values are not equal"); + 1_Field + } + } + + unconstrained fn __aztec_nr_internals__assertion_failure() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + helper_with_failed_assertion() + } + } + + unconstrained fn __aztec_nr_internals__bulk_testing(args_field: [Field; 10], args_u8: [u8; 10], get_instance_for_address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field, skip_strictly_limited_side_effects: bool) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 25] = aztec::oracle::avm::calldata_copy(1_u32, (((((<[Field; 10] as Serialize>::N + <[u8; 10] as Serialize>::N) + ::N) + ::N) + ::N) + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + aztec::oracle::logging::debug_log("biwise_ops"); + let num: u32 = self.context.block_number(); + let _: u32 = bitwise_ops(num, num); + aztec::oracle::logging::debug_log("set_storage_single"); + _set_storage_single(self.storage, 30_Field); + aztec::oracle::logging::debug_log("set_storage_list"); + _set_storage_list(self.storage, 40_Field, 50_Field); + aztec::oracle::logging::debug_log("read_storage_list"); + let _: Field = _set_storage_map(self.storage, self.address, 60_u32); + aztec::oracle::logging::debug_log("add_storage_map"); + let _: Field = _add_storage_map(self.storage, self.address, 10_u32); + aztec::oracle::logging::debug_log("read_storage_map"); + let _: u32 = _read_storage_map(self.storage, self.address); + aztec::oracle::logging::debug_log("keccak_hash"); + let _: [u8; 32] = keccak256::keccak256(args_u8, args_u8.len()); + aztec::oracle::logging::debug_log("sha256_hash"); + let _: [u8; 32] = sha256::sha256_var(args_u8, args_u8.len()); + aztec::oracle::logging::debug_log("poseidon2_hash"); + let _: Field = poseidon::poseidon2::Poseidon2::hash(args_field, args_field.len()); + aztec::oracle::logging::debug_log("pedersen_hash"); + let _: Field = std::hash::pedersen_hash(args_field); + aztec::oracle::logging::debug_log("pedersen_hash_with_index"); + let _: Field = std::hash::pedersen_hash_with_separator(args_field, 20_u32); + aztec::oracle::logging::debug_log("integer_division"); + let _: u8 = integer_division(args_u8[0_u32], args_u8[1_u32]); + aztec::oracle::logging::debug_log("field_division"); + let _: Field = field_division(args_field[0_u32], args_field[1_u32]); + aztec::oracle::logging::debug_log("test_get_contract_instance"); + _test_get_contract_instance_matches(get_instance_for_address, expected_deployer, expected_class_id, expected_initialization_hash); + aztec::oracle::logging::debug_log("get_address"); + let _: AztecAddress = _get_address(self.address); + aztec::oracle::logging::debug_log("get_sender"); + let _: AztecAddress = _get_sender(self.context); + aztec::oracle::logging::debug_log("get_transaction_fee"); + let _: Field = _get_transaction_fee(self.context); + aztec::oracle::logging::debug_log("get_chain_id"); + let _: Field = _get_chain_id(self.context); + aztec::oracle::logging::debug_log("get_version"); + let _: Field = _get_version(self.context); + aztec::oracle::logging::debug_log("get_block_number"); + let _: u32 = _get_block_number(self.context); + aztec::oracle::logging::debug_log("get_timestamp"); + let _: u64 = _get_timestamp(self.context); + aztec::oracle::logging::debug_log("get_fee_per_l2_gas"); + let _: u128 = _get_fee_per_l2_gas(self.context); + aztec::oracle::logging::debug_log("get_fee_per_da_gas"); + let _: u128 = _get_fee_per_da_gas(self.context); + aztec::oracle::logging::debug_log("get_l2_gas_left"); + let _: u32 = _get_l2_gas_left(self.context); + aztec::oracle::logging::debug_log("get_da_gas_left"); + let _: u32 = _get_da_gas_left(self.context); + if !skip_strictly_limited_side_effects { + aztec::oracle::logging::debug_log("emit_public_log"); + _emit_public_log(self.context); + }; + aztec::oracle::logging::debug_log("note_hash_exists"); + let _: bool = _note_hash_exists(self.context, 1_Field, 2_u64); + aztec::oracle::logging::debug_log("new_note_hash"); + _new_note_hash(self.context, 1_Field); + aztec::oracle::logging::debug_log("new_nullifier"); + _new_nullifier(self.context, args_field[0_u32]); + aztec::oracle::logging::debug_log("nullifier_exists"); + let _: bool = _nullifier_exists(self.context, self.address, 1_Field); + aztec::oracle::logging::debug_log("l1_to_l2_msg_exists"); + let _: bool = _l1_to_l2_msg_exists(self.context, 1_Field, 2_Field); + if !skip_strictly_limited_side_effects { + aztec::oracle::logging::debug_log("send_l2_to_l1_msg"); + _send_l2_to_l1_msg(self.context, EthAddress::from_field(8224_Field), 1_Field); + }; + aztec::oracle::logging::debug_log("storage_read_and_write"); + _set_storage_single(self.storage, _read_storage_single(self.storage)); + aztec::oracle::logging::debug_log("nested_call_to_add"); + let _: Field = _nested_call_to_add(self.context, self.address, 1_Field, 2_Field); + aztec::oracle::logging::debug_log("nested_static_call_to_add"); + let _: Field = _nested_static_call_to_add(self.context, self.address, 1_Field, 2_Field); + aztec::oracle::logging::debug_log("nested_call_to_protocol_contract"); + _call_fee_juice(self.context, self.address); + aztec::oracle::logging::debug_log("to_le_bytes"); + let first_byte: u8 = _to_le_bytes(args_field[0_u32])[0_u32]; + assert(first_byte != 0_u8); + aztec::oracle::logging::debug_log("to_le_bits"); + let first_bit: bool = _to_le_bits(args_field[0_u32])[0_u32]; + assert(first_bit); + } + } + + unconstrained fn __aztec_nr_internals__call_auth_registry() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let _: bool = AuthRegistry::at(CANONICAL_AUTH_REGISTRY_ADDRESS).is_reject_all(self.address).view(self.context); + } + } + + unconstrained fn __aztec_nr_internals__call_fee_juice() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _call_fee_juice(self.context, self.address); + } + } + + unconstrained fn __aztec_nr_internals__call_instance_registry() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let _: u64 = self.view(ContractInstanceRegistry::at(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS).get_update_delay()); + } + } + + unconstrained fn __aztec_nr_internals__conditional_move(x: [Field; 1], y: [Field; 1], b: bool) -> pub [Field; 1] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (<[Field; 1] as Serialize>::N + <[Field; 1] as Serialize>::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + if b { + x + } else { + y + } + } + } + + unconstrained fn __aztec_nr_internals__create_different_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.context.push_nullifier(nullifier); + self.call(AvmTest::at(nestedAddress).new_nullifier(nullifier + 1_Field)); + } + } + + unconstrained fn __aztec_nr_internals__create_same_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.context.push_nullifier(nullifier); + self.call(AvmTest::at(nestedAddress).new_nullifier(nullifier)); + } + } + + unconstrained fn __aztec_nr_internals__debug_logging() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + aztec::oracle::logging::debug_log("just text"); + aztec::oracle::logging::debug_log_format("second: {1}", [1_Field, 2_Field, 3_Field, 4_Field]); + aztec::oracle::logging::debug_log_format("whole array: {}", [1_Field, 2_Field, 3_Field, 4_Field]); + aztec::oracle::logging::debug_log("tabs and newlines\n\t- first\n\t- second"); + aztec::oracle::logging::fatal_log("fatal error"); + aztec::oracle::logging::trace_log_format("trace format: {}", [1_Field, 3_Field, 3_Field, 7_Field]); + } + } + + unconstrained fn __aztec_nr_internals__divide_by_zero(denominator: u8) -> pub u8 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + 1_u8 / denominator + } + } + + unconstrained fn __aztec_nr_internals__elliptic_curve_add(lhs: Point, rhs: Point) -> pub Point { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 6] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + lhs + rhs + } + } + + unconstrained fn __aztec_nr_internals__elliptic_curve_add_and_double() -> pub Point { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let g: Point = Point { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y, is_infinite: false}; + let doubled: Point = g + g; + let added: Point = g + doubled; + added + } + } + + unconstrained fn __aztec_nr_internals__emit_nullifier_and_check(nullifier: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.context.push_nullifier(nullifier); + let exists: bool = self.context.nullifier_exists_unsafe(nullifier, self.address); + assert(exists, "Nullifier was just created, but its existence wasn't detected!"); + } + } + + unconstrained fn __aztec_nr_internals__emit_public_log() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _emit_public_log(self.context); + } + } + + unconstrained fn __aztec_nr_internals__external_call_to_assertion_failure() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.call_self.assertion_failure(); + } + } + + unconstrained fn __aztec_nr_internals__external_call_to_divide_by_zero() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let _: u8 = self.call_self.divide_by_zero(0_u8); + } + } + + unconstrained fn __aztec_nr_internals__external_call_to_divide_by_zero_recovers() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let l2_gas_left: u32 = self.context.l2_gas_left(); + let da_gas_left: u32 = self.context.da_gas_left(); + let selector: FunctionSelector = FunctionSelector::from_signature("divide_by_zero(u8)"); + call(l2_gas_left - 200000_u32, da_gas_left - 200000_u32, self.address, [selector.to_field(), 0_Field]); + let success: bool = success_copy(); + assert(!success, "Nested CALL instruction should return failure on exceptional halt"); + assert(returndata_size() == 0_u32, "Returndata should be empty when nested call exceptionally halts"); + } + } + + unconstrained fn __aztec_nr_internals__fn_w_large_calldata(_arr: [Field; 300]) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 300 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 300] as Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + 5_Field + } + } + + unconstrained fn __aztec_nr_internals__get_address() -> pub AztecAddress { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_address(self.address) + } + } + + unconstrained fn __aztec_nr_internals__get_args_hash(_a: u8, _fields: [Field; 3]) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ::N + <[Field; 3] as Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.context.get_args_hash() + } + } + + unconstrained fn __aztec_nr_internals__get_block_number() -> pub u32 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_block_number(self.context) + } + } + + unconstrained fn __aztec_nr_internals__get_chain_id() -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_chain_id(self.context) + } + } + + unconstrained fn __aztec_nr_internals__get_da_gas_left() -> pub u32 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_da_gas_left(self.context) + } + } + + unconstrained fn __aztec_nr_internals__get_fee_per_da_gas() -> pub u128 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_fee_per_da_gas(self.context) + } + } + + unconstrained fn __aztec_nr_internals__get_fee_per_l2_gas() -> pub u128 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_fee_per_l2_gas(self.context) + } + } + + unconstrained fn __aztec_nr_internals__get_l2_gas_left() -> pub u32 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_l2_gas_left(self.context) + } + } + + unconstrained fn __aztec_nr_internals__get_sender() -> pub AztecAddress { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_sender(self.context) + } + } + + unconstrained fn __aztec_nr_internals__get_timestamp() -> pub u64 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_timestamp(self.context) + } + } + + unconstrained fn __aztec_nr_internals__get_transaction_fee() -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_transaction_fee(self.context) + } + } + + unconstrained fn __aztec_nr_internals__get_version() -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _get_version(self.context) + } + } + + unconstrained fn __aztec_nr_internals__l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> pub bool { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _l1_to_l2_msg_exists(self.context, msg_hash, msg_leaf_index) + } + } + + unconstrained fn __aztec_nr_internals__modulo2(a: u64) -> pub u64 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + a % 2_u64 + } + } + + unconstrained fn __aztec_nr_internals__n_new_l2_to_l1_msgs(num: u32) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + for i in 0_u32..num { + self.context.message_portal(EthAddress::from_field(i as Field), i as Field) + } + } + } + + unconstrained fn __aztec_nr_internals__n_new_note_hashes(num: u32) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + for i in 0_u32..num { + self.context.push_note_hash(i as Field); + } + } + } + + unconstrained fn __aztec_nr_internals__n_new_nullifiers(num: u32) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + for i in 0_u32..num { + self.context.push_nullifier(i as Field); + } + } + } + + unconstrained fn __aztec_nr_internals__n_new_public_logs(num: u32) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + for i in 0_u32..num { + self.context.emit_public_log_unsafe(0_Field, [i as Field]); + } + } + } + + unconstrained fn __aztec_nr_internals__n_storage_writes(num: u32) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + for i in 0_u32..num { + self.storage.map.at(AztecAddress::from_field(i as Field)).write(i); + } + } + } + + unconstrained fn __aztec_nr_internals__nested_call_large_calldata(arr: [Field; 300]) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 300 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[Field; 300] as Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.call_self.fn_w_large_calldata(arr) + } + } + + unconstrained fn __aztec_nr_internals__nested_call_to_add(arg_a: Field, arg_b: Field) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _nested_call_to_add(self.context, self.address, arg_a, arg_b) + } + } + + unconstrained fn __aztec_nr_internals__nested_call_to_add_n_times_different_addresses(addrs: [AztecAddress; 23]) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 23 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[AztecAddress; 23] as Serialize>::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + for i in 0_u32..MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS + 2_u32 { + let addr: AztecAddress = addrs[i]; + if addr != AztecAddress::empty() { + let _: Field = self.call(AvmTest::at(addr).add_args_return(1_Field, 2_Field)); + } + } + } + } + + unconstrained fn __aztec_nr_internals__nested_call_to_add_with_gas(arg_a: Field, arg_b: Field, l2_gas: u32, da_gas: u32) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + ::N) + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.call(AvmTest::at(self.address).add_args_return(arg_a, arg_b).with_gas(GasOpts::new(l2_gas, da_gas))) + } + } + + unconstrained fn __aztec_nr_internals__nested_call_to_assert_same(arg_a: Field, arg_b: Field) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.call_self.assert_same(arg_a, arg_b) + } + } + + unconstrained fn __aztec_nr_internals__nested_call_to_nothing() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let garbageAddress: AztecAddress = AztecAddress::from_field(42_Field); + self.call(AvmTest::at(garbageAddress).nested_call_to_nothing()) + } + } + + unconstrained fn __aztec_nr_internals__nested_call_to_nothing_recovers() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let garbageAddress: AztecAddress = AztecAddress::from_field(42_Field); + call(1_u32, 1_u32, garbageAddress, []); + let success: bool = success_copy(); + assert(!success, "Nested CALL instruction should return failure if target contract does not exist"); + } + } + + unconstrained fn __aztec_nr_internals__nested_static_call_to_add(arg_a: Field, arg_b: Field) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _nested_static_call_to_add(self.context, self.address, arg_a, arg_b) + } + } + + unconstrained fn __aztec_nr_internals__nested_static_call_to_set_storage() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let selector: FunctionSelector = FunctionSelector { inner: 2230419055_u32}; + let args: [Field; 1] = [20_Field as Field]; + let _: [Field] = self.context.static_call_public_function(self.address, selector, args, GasOpts::default()); + } + } + + unconstrained fn __aztec_nr_internals__new_note_hash(note_hash: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _new_note_hash(self.context, note_hash); + } + } + + unconstrained fn __aztec_nr_internals__new_nullifier(nullifier: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _new_nullifier(self.context, nullifier); + } + } + + unconstrained fn __aztec_nr_internals__note_hash_exists(note_hash: Field, leaf_index: u64) -> pub bool { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _note_hash_exists(self.context, note_hash, leaf_index) + } + } + + unconstrained fn __aztec_nr_internals__nullifier_collision(nullifier: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.context.push_nullifier(nullifier); + self.context.push_nullifier(nullifier); + } + } + + unconstrained fn __aztec_nr_internals__nullifier_exists(nullifier: Field) -> pub bool { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _nullifier_exists(self.context, self.address, nullifier) + } + } + + unconstrained fn __aztec_nr_internals__pedersen_commit(x: Field, y: Field) -> pub Point { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let commitment: std::embedded_curve_ops::EmbeddedCurvePoint = std::hash::pedersen_commitment_with_separator([x, y], 20_u32); + commitment.into() + } + } + + unconstrained fn __aztec_nr_internals__raw_l2_to_l1_msg(recipient: EthAddress, content: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.context.message_portal(recipient, content) + } + } + + unconstrained fn __aztec_nr_internals__read_assert_storage_single(a: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + assert(a == self.storage.single.read(), "Storage value does not match input"); + } + } + + unconstrained fn __aztec_nr_internals__read_storage_list() -> pub [Field; 2] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _read_storage_list(self.storage) + } + } + + unconstrained fn __aztec_nr_internals__read_storage_map(address: AztecAddress) -> pub u32 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _read_storage_map(self.storage, address) + } + } + + unconstrained fn __aztec_nr_internals__read_storage_single() -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _read_storage_single(self.storage) + } + } + + unconstrained fn __aztec_nr_internals__return_oracle() -> pub [Field; 3] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + avm_return([1_Field, 2_Field, 3_Field].as_slice()); + [4_Field, 5_Field, 6_Field] + } + } + + unconstrained fn __aztec_nr_internals__returndata_copy_oracle() { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let _: [Field; 3] = self.call_self.return_oracle(); + let returndatasize: u32 = returndata_size(); + let returndata: [Field] = returndata_copy(0_u32, returndatasize); + assert(returndata == @[1_Field, 2_Field, 3_Field], "Returndata copy failed"); + } + } + + unconstrained fn __aztec_nr_internals__revert_oracle() -> pub [Field; 3] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + revert([1_Field, 2_Field, 3_Field].as_slice()); + [4_Field, 5_Field, 6_Field] + } + } + + unconstrained fn __aztec_nr_internals__send_l2_to_l1_msg(recipient: EthAddress, content: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _send_l2_to_l1_msg(self.context, recipient, content); + } + } + + unconstrained fn __aztec_nr_internals__set_opcode_big_field() -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + big_field_136_bits + } + } + + unconstrained fn __aztec_nr_internals__set_opcode_really_big_field() -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + big_field_254_bits + } + } + + unconstrained fn __aztec_nr_internals__set_opcode_small_field() -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + big_field_128_bits + } + } + + unconstrained fn __aztec_nr_internals__set_opcode_u32() -> pub u32 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + 1_u32 << 30_u32 + } + } + + unconstrained fn __aztec_nr_internals__set_opcode_u64() -> pub u64 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + 1_u64 << 60_u64 + } + } + + unconstrained fn __aztec_nr_internals__set_opcode_u8() -> pub u8 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + 8_u8 + } + } + + unconstrained fn __aztec_nr_internals__set_opcode_u8_view() -> pub u8 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.context.is_static_call(), "Function set_opcode_u8_view can only be called statically"); + { + 8_u8 + } + } + + unconstrained fn __aztec_nr_internals__set_read_storage_single(a: Field) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + self.storage.single.write(a); + self.storage.single.read() + } + } + + unconstrained fn __aztec_nr_internals__set_storage_list(a: Field, b: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _set_storage_list(self.storage, a, b); + } + } + + unconstrained fn __aztec_nr_internals__set_storage_map(to: AztecAddress, amount: u32) -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _set_storage_map(self.storage, to, amount) + } + } + + unconstrained fn __aztec_nr_internals__set_storage_single(a: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _set_storage_single(self.storage, a); + } + } + + unconstrained fn __aztec_nr_internals__test_get_contract_instance(address: AztecAddress) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let deployer: Option = get_contract_instance_deployer_avm(address); + let class_id: Option = get_contract_instance_class_id_avm(address); + let initialization_hash: Option = get_contract_instance_initialization_hash_avm(address); + assert(deployer.is_some(), "Contract instance not found when getting DEPLOYER!"); + assert(class_id.is_some(), "Contract instance not found when getting CLASS_ID!"); + assert(initialization_hash.is_some(), "Contract instance not found when getting INIT_HASH!"); + assert(deployer.unwrap().eq(AztecAddress::from_field(1110_Field))); + assert(class_id.unwrap().eq(ContractClassId::from_field(1929_Field))); + assert(initialization_hash.unwrap() == 1052946_Field); + } + } + + unconstrained fn __aztec_nr_internals__test_get_contract_instance_matches(address: AztecAddress, expected_deployer: AztecAddress, expected_class_id: ContractClassId, expected_initialization_hash: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + ::N) + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _test_get_contract_instance_matches(address, expected_deployer, expected_class_id, expected_initialization_hash); + } + } + + unconstrained fn __aztec_nr_internals__to_le_bits(input: Field) -> pub [bool; 16] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _to_le_bits(input) + } + } + + unconstrained fn __aztec_nr_internals__to_le_bytes(input: Field) -> pub [u8; 10] { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + _to_le_bytes(input) + } + } + + unconstrained fn __aztec_nr_internals__u128_addition_overflow() -> pub u128 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let max_u128: u128 = 340282366920938463463374607431768211455_u128; + let one: u128 = 1_u128; + max_u128 + one + } + } + + unconstrained fn __aztec_nr_internals__variable_base_msm(scalar_lo: Field, scalar_hi: Field, scalar2_lo: Field, scalar2_hi: Field) -> pub Point { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: PublicContext = PublicContext::new(|| -> Field { + let serialized_args: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + ::N) + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let g: Point = Point { x: GRUMPKIN_ONE_X, y: GRUMPKIN_ONE_Y, is_infinite: false}; + let triple_g: std::embedded_curve_ops::EmbeddedCurvePoint = multi_scalar_mul([g.to_embedded(), g.to_embedded()], [Scalar { lo: scalar_lo, hi: scalar_hi}, Scalar { lo: scalar2_lo, hi: scalar2_hi}]); + triple_g.into() + } + } + + pub struct StorageLayoutFields { + pub single: aztec::state_vars::Storable, + pub list: aztec::state_vars::Storable, + pub map: aztec::state_vars::Storable, + } + + pub struct StorageLayout { + pub contract_name: str, + pub fields: StorageLayoutFields, + } +} + +mod note { + use std::meta::derive; + use aztec::protocol::traits::Deserialize; + use aztec::protocol::traits::Packable; + use aztec::protocol::traits::Serialize; + + pub struct Note { + pub a: Field, + pub b: Field, + } + + impl Packable for Note { + let N: u32 = 2; + + #[inline_always] + fn pack(self) -> [Field; 2] { + let mut result: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let packed_member: [Field; 1] = self.a.pack(); + let packed_member_len: u32 = ::N; + for i in 0_u32..packed_member_len { + { + let i_0: u32 = i + offset; + result[i_0] = packed_member[i]; + } + }; + offset = offset + packed_member_len; + let packed_member: [Field; 1] = self.b.pack(); + let packed_member_len: u32 = ::N; + for i in 0_u32..packed_member_len { + { + let i_1: u32 = i + offset; + result[i_1] = packed_member[i]; + } + }; + offset = offset + packed_member_len; + result + } + + #[inline_always] + fn unpack(packed: [Field; 2]) -> Self { + let mut offset: u32 = 0_u32; + let mut member_fields: [Field; 1] = [0_Field; 1]; + for i in 0_u32..::N { + member_fields[i] = packed[i + offset]; + }; + let a: Field = ::unpack(member_fields); + offset = offset + ::N; + let mut member_fields: [Field; 1] = [0_Field; 1]; + for i in 0_u32..::N { + member_fields[i] = packed[i + offset]; + }; + let b: Field = ::unpack(member_fields); + offset = offset + ::N; + Self { a: a, b: b} + } + } + + impl Serialize for Note { + let N: u32 = 2; + + fn serialize(self) -> [Field; 2] { + let mut writer: aztec::protocol::utils::writer::Writer<2> = aztec::protocol::utils::writer::Writer::<2>::new(); + self.stream_serialize(&mut writer); + writer.finish() + } + + #[inline_always] + fn stream_serialize(self, writer: &mut aztec::protocol::utils::writer::Writer) { + self.a.stream_serialize(writer); + self.b.stream_serialize(writer); + } + } + + impl Deserialize for Note { + let N: u32 = 2; + + fn deserialize(fields: [Field; 2]) -> Self { + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(fields); + let result: Self = Self::stream_deserialize(&mut reader); + reader.finish(); + result + } + + #[inline_always] + fn stream_deserialize(reader: &mut aztec::protocol::utils::reader::Reader) -> Self { + let a: Field = ::stream_deserialize(reader); + let b: Field = ::stream_deserialize(reader); + Self { a: a, b: b} + } + } +} + +// Warning: the generated code has syntax errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/storage_proof_test_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/storage_proof_test_contract/snapshots__expanded.snap new file mode 100644 index 000000000000..0bb78f0095c8 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/storage_proof_test_contract/snapshots__expanded.snap @@ -0,0 +1,2146 @@ +--- +source: tests/snapshots.rs +expression: stdout +--- +use aztec::macros::aztec; +use aztec::macros::aztec; + +contract StorageProofTest { + use crate::storage_proofs::account_hash::compute_account_hash; + use crate::storage_proofs::keccak::keccak256; + use crate::storage_proofs::keccak::KeccakHasher; + use crate::storage_proofs::path_verification::verify_path_section; + use crate::storage_proofs::slot_hash::compute_slot_hash; + use crate::storage_proofs::types::Account; + use crate::storage_proofs::types::Node; + use crate::storage_proofs::types::StorageSlot; + use crate::storage_proofs::utils::to_nibbles; + use aztec::context::calls::PrivateCall; + use aztec::macros::functions::external; + use aztec::macros::functions::internal; + use aztec::macros::functions::only_self; + use aztec::macros::functions::view; + use aztec::oracle::capsules; + use aztec::protocol::address::AztecAddress; + use aztec::protocol::address::EthAddress; + use aztec::protocol::hash::poseidon2_hash; + use aztec::protocol::traits::Deserialize; + use aztec::protocol::traits::Serialize; + use aztec::protocol::traits::ToField; + + global MAX_ACCOUNT_PROOF_LENGTH: u32 = 15; + + global NUM_NODES_VERIFIED_PER_CALL: u32 = 3; + + global ACCOUNT_CAPSULE_KEY_SEPARATOR: u32 = 100; + + global ACCOUNT_PROOF_CAPSULE_KEY_SEPARATOR: u32 = 101; + + global STORAGE_PROOF_CAPSULE_KEY_SEPARATOR: u32 = 102; + + global STORAGE_PROOF_NODE_CAPSULE_KEY_SEPARATOR: u32 = 103; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call account_proof. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn account_proof(account: Account, root: [u64; 4], nodes: [Node; 15], node_length: u32); + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call storage_proof. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn storage_proof(address: EthAddress, slot_key: [u8; 32], slot_contents: StorageSlot, eth_storage_root: [u64; 4]); + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call verify_storage_proof_path_recursively. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn verify_storage_proof_path_recursively(num_processed_nodes: u32, num_total_nodes: u32, start_nibble_index: u32, parent_hash: [u64; 4], storage_trie_key_nibbles: [u8; 64], storage_proof_capsule_key: Field) -> ([u64; 4], u32); + + #[no_predicates] + #[contract_library_method] + fn call_verify_storage_proof_path_recursively(this_address: AztecAddress, num_processed_nodes: u32, num_total_nodes: u32, start_nibble_index: u32, parent_hash: [u64; 4], storage_trie_key_nibbles: [u8; 64], storage_proof_capsule_key: Field) -> PrivateCall<37, 72, ([u64; 4], u32)> { + StorageProofTest::at(this_address).verify_storage_proof_path_recursively(num_processed_nodes, num_total_nodes, start_nibble_index, parent_hash, storage_trie_key_nibbles, storage_proof_capsule_key) + } + + #[contract_library_method] + fn compute_address_capsule_key(eth_storage_root: [u64; 4], address: EthAddress) -> Field { + poseidon2_hash((ACCOUNT_CAPSULE_KEY_SEPARATOR, eth_storage_root, address).serialize()) + } + + #[contract_library_method] + fn compute_account_proof_capsule_key(address_capsule_key: Field) -> Field { + poseidon2_hash((ACCOUNT_PROOF_CAPSULE_KEY_SEPARATOR, address_capsule_key).serialize()) + } + + #[contract_library_method] + fn compute_storage_proof_capsule_key(address_capsule_key: Field, slot_key: [u8; 32]) -> Field { + poseidon2_hash((STORAGE_PROOF_CAPSULE_KEY_SEPARATOR, address_capsule_key, slot_key).serialize()) + } + + #[contract_library_method] + fn compute_node_capsule_key(storage_proof_capsule_key: Field, index: u32) -> Field { + poseidon2_hash((STORAGE_PROOF_NODE_CAPSULE_KEY_SEPARATOR, storage_proof_capsule_key, index).serialize()) + } + + /// Unpacks an array into a note corresponding to `note_type_id` and then computes its note hash (non-siloed) and inner nullifier (non-siloed) assuming the note has been inserted into the note hash tree with `note_nonce`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + #[allow(dead_code)] + unconstrained fn _compute_note_hash_and_nullifier(packed_note: BoundedVec, owner: AztecAddress, storage_slot: Field, note_type_id: Field, contract_address: AztecAddress, randomness: Field, note_nonce: Field) -> Option { + _compute_note_hash(packed_note, owner, storage_slot, note_type_id, contract_address, randomness).map(|note_hash: Field| -> aztec::messages::discovery::NoteHashAndNullifier { + let siloed_note_hash: Field = aztec::protocol::hash::compute_siloed_note_hash(contract_address, note_hash); + let unique_note_hash: Field = aztec::protocol::hash::compute_unique_note_hash(note_nonce, siloed_note_hash); + let inner_nullifier: Option = _compute_note_nullifier(unique_note_hash, packed_note, owner, storage_slot, note_type_id, contract_address, randomness); + aztec::messages::discovery::NoteHashAndNullifier { note_hash: note_hash, inner_nullifier: inner_nullifier} + }) + } + + /// This contract does not use private notes, so this function should never be called as it will unconditionally fail. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_hash(_packed_note: BoundedVec, _owner: AztecAddress, _storage_slot: Field, _note_type_id: Field, _contract_address: AztecAddress, _randomness: Field) -> Option { + panic(f"This contract does not use private notes") + } + + /// This contract does not use private notes, so this function should never be called as it will unconditionally fail. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_nullifier(_unique_note_hash: Field, _packed_note: BoundedVec, _owner: AztecAddress, _storage_slot: Field, _note_type_id: Field, _contract_address: AztecAddress, _randomness: Field) -> Option { + panic(f"This contract does not use private notes") + } + + /// Receives offchain messages into this contract's offchain inbox for subsequent processing. + /// + /// Each message is routed to the inbox scoped to its `recipient` field. + /// + /// For more details, see `aztec::messages::processing::offchain::receive`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + unconstrained fn offchain_receive(messages: BoundedVec) { + let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::processing::offchain::receive(address, messages); + } + + pub struct StorageProofTest { + pub target_contract: AztecAddress, + } + + impl StorageProofTest { + pub fn at(addr: AztecAddress) -> Self { + Self { target_contract: addr} + } + + pub fn interface() -> Self { + Self { target_contract: AztecAddress::zero()} + } + + pub fn verify_storage_proof_path_recursively(self, num_processed_nodes: u32, num_total_nodes: u32, start_nibble_index: u32, parent_hash: [u64; 4], storage_trie_key_nibbles: [u8; 64], storage_proof_capsule_key: Field) -> PrivateCall<37, 72, ([u64; 4], u32)> { + let mut serialized_params: [Field; 72] = [0_Field; 72]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = num_processed_nodes.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = num_total_nodes.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = start_nibble_index.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 4 * 1] = parent_hash.serialize(); + let serialized_member_len: u32 = <[u64; 4] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 64 * 1] = storage_trie_key_nibbles.serialize(); + let serialized_member_len: u32 = <[u8; 64] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = storage_proof_capsule_key.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2237949917_Field); + PrivateCall::<37, 72, ([u64; 4], u32)>::new(self.target_contract, selector, "verify_storage_proof_path_recursively", serialized_params) + } + + pub fn storage_proof(self, address: EthAddress, slot_key: [u8; 32], slot_contents: StorageSlot, eth_storage_root: [u64; 4]) -> PrivateCall<13, 70, ()> { + let mut serialized_params: [Field; 70] = [0_Field; 70]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = address.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 32 * 1] = slot_key.serialize(); + let serialized_member_len: u32 = <[u8; 32] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 33] = slot_contents.serialize(); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 4 * 1] = eth_storage_root.serialize(); + let serialized_member_len: u32 = <[u64; 4] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2067008734_Field); + PrivateCall::<13, 70, ()>::new(self.target_contract, selector, "storage_proof", serialized_params) + } + + pub fn account_proof(self, account: Account, root: [u64; 4], nodes: [Node; 15], node_length: u32) -> aztec::context::calls::PublicStaticCall<13, 1290, ()> { + let mut serialized_params: [Field; 1290] = [0_Field; 1290]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 70] = account.serialize(); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 4 * 1] = root.serialize(); + let serialized_member_len: u32 = <[u64; 4] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 15 * 81] = nodes.serialize(); + let serialized_member_len: u32 = <[Node; 15] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = node_length.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(693284113_Field); + aztec::context::calls::PublicStaticCall::<13, 1290, ()>::new(self.target_contract, selector, "account_proof", serialized_params) + } + + pub fn offchain_receive(self, messages: BoundedVec) -> aztec::context::calls::UtilityCall<16, 321, ()> { + let serialized_params: [Field; 321] = messages.serialize(); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1396850735_Field); + aztec::context::calls::UtilityCall::<16, 321, ()>::new(self.target_contract, selector, "offchain_receive", serialized_params) + } + } + + #[contract_library_method] + pub fn at(addr: AztecAddress) -> StorageProofTest { + StorageProofTest { target_contract: addr} + } + + #[contract_library_method] + pub fn interface() -> StorageProofTest { + StorageProofTest { target_contract: AztecAddress::zero()} + } + + pub struct sync_state_parameters { + pub scope: AztecAddress, + } + + #[abi(functions)] + pub struct sync_state_abi { + parameters: sync_state_parameters, + } + + unconstrained fn sync_state(scope: AztecAddress) { + let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + } + + pub struct offchain_receive_parameters { + pub messages: BoundedVec, + } + + #[abi(functions)] + pub struct offchain_receive_abi { + parameters: offchain_receive_parameters, + } + + pub struct CallSelf { + pub address: AztecAddress, + pub context: Context, + } + + impl CallSelf<&mut aztec::context::PrivateContext> { + pub fn storage_proof(self, address: EthAddress, slot_key: [u8; 32], slot_contents: StorageSlot, eth_storage_root: [u64; 4]) { + let mut serialized_params: [Field; 70] = [0_Field; 70]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = address.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 32 * 1] = slot_key.serialize(); + let serialized_member_len: u32 = <[u8; 32] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 33] = slot_contents.serialize(); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 4 * 1] = eth_storage_root.serialize(); + let serialized_member_len: u32 = <[u64; 4] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2067008734_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn verify_storage_proof_path_recursively(self, num_processed_nodes: u32, num_total_nodes: u32, start_nibble_index: u32, parent_hash: [u64; 4], storage_trie_key_nibbles: [u8; 64], storage_proof_capsule_key: Field) -> ([u64; 4], u32) { + let mut serialized_params: [Field; 72] = [0_Field; 72]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = num_processed_nodes.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = num_total_nodes.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = start_nibble_index.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 4 * 1] = parent_hash.serialize(); + let serialized_member_len: u32 = <[u64; 4] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 64 * 1] = storage_trie_key_nibbles.serialize(); + let serialized_member_len: u32 = <[u8; 64] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = storage_proof_capsule_key.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2237949917_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + } + + pub struct CallSelfStatic { + pub address: AztecAddress, + pub context: Context, + } + + impl CallSelfStatic { + pub fn account_proof(self, account: Account, root: [u64; 4], nodes: [Node; 15], node_length: u32) { + let mut serialized_params: [Field; 1290] = [0_Field; 1290]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 70] = account.serialize(); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 4 * 1] = root.serialize(); + let serialized_member_len: u32 = <[u64; 4] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 15 * 81] = nodes.serialize(); + let serialized_member_len: u32 = <[Node; 15] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = node_length.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(693284113_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicStaticCall::<13, 1290, ()>::new(self.address, selector, "account_proof", serialized_params).view(self.context) + } + } + } + + pub struct EnqueueSelf { + pub address: AztecAddress, + pub context: Context, + } + + pub struct EnqueueSelfStatic { + pub address: AztecAddress, + pub context: Context, + } + + impl EnqueueSelfStatic<&mut aztec::context::PrivateContext> { + pub fn account_proof(self, account: Account, root: [u64; 4], nodes: [Node; 15], node_length: u32) { + let mut serialized_params: [Field; 1290] = [0_Field; 1290]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 70] = account.serialize(); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 4 * 1] = root.serialize(); + let serialized_member_len: u32 = <[u64; 4] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 15 * 81] = nodes.serialize(); + let serialized_member_len: u32 = <[Node; 15] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = node_length.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(693284113_Field); + let calldata: [Field; 1 + 1290] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, true, false); + } + } + + pub struct CallSelfUtility { + pub address: AztecAddress, + } + + pub struct CallInternal { + pub context: Context, + } + + pub unconstrained fn public_dispatch(selector: Field) { + if selector == 693284113_Field { + let input_calldata: [Field; 1290] = aztec::oracle::avm::calldata_copy(1_u32, ((>::N + <[u64; 4] as Serialize>::N) + <[Node; 15] as Serialize>::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1290> = aztec::protocol::utils::reader::Reader::<1290>::new(input_calldata); + let arg0: Account = >::stream_deserialize(&mut reader); + let arg1: [u64; 4] = <[u64; 4] as Deserialize>::stream_deserialize(&mut reader); + let arg2: [Node; 15] = <[Node; 15] as Deserialize>::stream_deserialize(&mut reader); + let arg3: u32 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__account_proof(arg0, arg1, arg2, arg3); + aztec::oracle::avm::avm_return([].as_slice()); + }; + panic(f"Unknown selector {selector}") + } + + pub struct account_proof_parameters { + pub account: Account, + pub root: [u64; 4], + pub nodes: [Node; 15], + pub node_length: u32, + } + + pub struct storage_proof_parameters { + pub address: EthAddress, + pub slot_key: [u8; 32], + pub slot_contents: StorageSlot, + pub eth_storage_root: [u64; 4], + } + + pub struct verify_storage_proof_path_recursively_parameters { + pub num_processed_nodes: u32, + pub num_total_nodes: u32, + pub start_nibble_index: u32, + pub parent_hash: [u64; 4], + pub storage_trie_key_nibbles: [u8; 64], + pub storage_proof_capsule_key: Field, + } + + #[abi(functions)] + pub struct account_proof_abi { + parameters: account_proof_parameters, + } + + #[abi(functions)] + pub struct storage_proof_abi { + parameters: storage_proof_parameters, + } + + #[abi(functions)] + pub struct verify_storage_proof_path_recursively_abi { + parameters: verify_storage_proof_path_recursively_parameters, + return_type: ([u64; 4], u32), + } + + fn __aztec_nr_internals__storage_proof(inputs: aztec::context::inputs::PrivateContextInputs, address: EthAddress, slot_key: [u8; 32], slot_contents: StorageSlot, eth_storage_root: [u64; 4]) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate<(), CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 70] = [0_Field; 70]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = address.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 32 * 1] = slot_key.serialize(); + let serialized_member_len: u32 = <[u8; 32] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 33] = slot_contents.serialize(); + let serialized_member_len: u32 = >::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 4 * 1] = eth_storage_root.serialize(); + let serialized_member_len: u32 = <[u64; 4] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: aztec::context::PrivateContext = aztec::context::PrivateContext::new(inputs, args_hash); + let storage: () = (); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut aztec::context::PrivateContext> = CallSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut aztec::context::PrivateContext> = EnqueueSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut aztec::context::PrivateContext> = CallSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut aztec::context::PrivateContext> = EnqueueSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut aztec::context::PrivateContext> = CallInternal::<&mut aztec::context::PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::<(), CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + let address_capsule_key: Field = compute_address_capsule_key(eth_storage_root, address); + // Safety: comment added by `nargo expand` + let hinted_account: Account = unsafe { + Account::deserialize(capsules::load(self.address, address_capsule_key, AztecAddress::zero()).unwrap()) + }; + assert(hinted_account.address == address.to_field().to_be_bytes::<20>()); + let account_proof_capsule_key: Field = compute_account_proof_capsule_key(address_capsule_key); + // Safety: comment added by `nargo expand` + let (hinted_account_proof_length, hinted_nodes): (u32, [Node; 15]) = unsafe { + <(u32, [Node; 15]) as Deserialize>::deserialize(capsules::load(self.address, account_proof_capsule_key, AztecAddress::zero()).unwrap()) + }; + self.enqueue_self_static.account_proof(hinted_account, eth_storage_root, hinted_nodes, hinted_account_proof_length); + let storage_proof_capsule_key: Field = compute_storage_proof_capsule_key(address_capsule_key, slot_key); + // Safety: comment added by `nargo expand` + let hinted_storage_proof_length: u32 = unsafe { + u32::deserialize(capsules::load(self.address, storage_proof_capsule_key, AztecAddress::zero()).unwrap()) + }; + assert(hinted_storage_proof_length > 0_u32, "Storage proof length must be greater than 0"); + let storage_trie_key: [u8; 32] = keccak256(slot_key, 32_u32); + let (slot_leaf_hash, slot_nibble_index): ([u64; 4], u32) = call_verify_storage_proof_path_recursively(self.address, 0_u32, hinted_storage_proof_length, 0_u32, hinted_account.storage_hash, to_nibbles(storage_trie_key), storage_proof_capsule_key).call(self.context); + assert(slot_leaf_hash == compute_slot_hash(slot_contents, slot_nibble_index, storage_trie_key)); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__verify_storage_proof_path_recursively(inputs: aztec::context::inputs::PrivateContextInputs, num_processed_nodes: u32, num_total_nodes: u32, start_nibble_index: u32, parent_hash: [u64; 4], storage_trie_key_nibbles: [u8; 64], storage_proof_capsule_key: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate<(), CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 72] = [0_Field; 72]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = num_processed_nodes.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = num_total_nodes.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = start_nibble_index.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 4 * 1] = parent_hash.serialize(); + let serialized_member_len: u32 = <[u64; 4] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 64 * 1] = storage_trie_key_nibbles.serialize(); + let serialized_member_len: u32 = <[u8; 64] as Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_4: u32 = i + offset; + serialized_params[i_4] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = storage_proof_capsule_key.serialize(); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_5: u32 = i + offset; + serialized_params[i_5] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: aztec::context::PrivateContext = aztec::context::PrivateContext::new(inputs, args_hash); + let storage: () = (); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut aztec::context::PrivateContext> = CallSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut aztec::context::PrivateContext> = EnqueueSelf::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut aztec::context::PrivateContext> = CallSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut aztec::context::PrivateContext> = EnqueueSelfStatic::<&mut aztec::context::PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut aztec::context::PrivateContext> = CallInternal::<&mut aztec::context::PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::<(), CallSelf<&mut aztec::context::PrivateContext>, EnqueueSelf<&mut aztec::context::PrivateContext>, CallSelfStatic<&mut aztec::context::PrivateContext>, EnqueueSelfStatic<&mut aztec::context::PrivateContext>, CallInternal<&mut aztec::context::PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + assert(self.msg_sender() == self.address, "Function verify_storage_proof_path_recursively can only be called by the same contract"); + let mut hinted_nodes: [Node; 3] = std::mem::zeroed(); + let num_nodes_remaining: u32 = num_total_nodes - num_processed_nodes; + let num_nodes_to_process: u32 = if num_nodes_remaining > NUM_NODES_VERIFIED_PER_CALL { + NUM_NODES_VERIFIED_PER_CALL + } else { + num_nodes_remaining + }; + for i in 0_u32..NUM_NODES_VERIFIED_PER_CALL { + let node_capsule_key: Field = compute_node_capsule_key(storage_proof_capsule_key, num_processed_nodes + i); + if i < num_nodes_to_process { + // Safety: comment added by `nargo expand` + hinted_nodes[i] = unsafe { + Node::deserialize(capsules::load(self.address, node_capsule_key, AztecAddress::zero()).unwrap()) + }; + } + }; + let (child_hash, end_nibble_index): ([u64; 4], u32) = verify_path_section(hinted_nodes, num_nodes_to_process, start_nibble_index, parent_hash, storage_trie_key_nibbles); + let new_num_processed_nodes: u32 = num_processed_nodes + num_nodes_to_process; + let macro__returned__values: ([u64; 4], u32) = if new_num_processed_nodes == num_total_nodes { + (child_hash, end_nibble_index) + } else { + call_verify_storage_proof_path_recursively(self.address, new_num_processed_nodes, num_total_nodes, end_nibble_index, child_hash, storage_trie_key_nibbles, storage_proof_capsule_key).call(self.context) + }; + let serialized_params: [Field; (4 * 1) + 1] = macro__returned__values.serialize(); + self.context.set_return_hash(serialized_params); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + unconstrained fn __aztec_nr_internals__account_proof(account: Account, root: [u64; 4], nodes: [Node; 15], node_length: u32) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1290] = aztec::oracle::avm::calldata_copy(1_u32, ((>::N + <[u64; 4] as Serialize>::N) + <[Node; 15] as Serialize>::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: () = (); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.context.is_static_call(), "Function account_proof can only be called statically"); + { + let trie_key: [u8; 32] = KeccakHasher::hash_bytes(account.address, 20_u32); + let (leaf_hash, new_index): ([u64; 4], u32) = verify_path_section(nodes, node_length, 0_u32, root, to_nibbles(trie_key)); + assert(leaf_hash == compute_account_hash(account, new_index, trie_key)); + } + } +} + +mod storage_proofs { + pub mod account_hash { + use super::bytes_sink::BytesChecker; + use super::bytes_sink::BytesSink; + use super::bytes_sink::BytesWriter; + use super::keccak::keccak256_limbs; + use super::keccak::KeccakHasher; + use super::types::Account; + use super::utils::get_low_nibble; + use super::utils::get_rlp_length; + use super::utils::runtime_loop; + use super::utils::unroll_loop; + + global ACCOUNT_RLP_MAX_LENGTH: u32 = 147; + + #[inline_always] + fn rlp_encode_to_sink(account: Account, start_nibble_idx: u32, trie_key: [u8; 32], sink: &mut S) where S: BytesSink { + let mut current_nibble_idx: u32 = start_nibble_idx; + let first_key_byte: u8 = if (current_nibble_idx % 2_u32) == 0_u32 { + 32_u8 + } else { + let first_byte: u8 = trie_key[(current_nibble_idx / 2_u32) as u32]; + current_nibble_idx = current_nibble_idx + 1_u32; + 48_u8 + get_low_nibble(first_byte) + }; + let key_length: u8 = (32_u8 - ((current_nibble_idx as u8) / 2_u8)) + 1_u8; + let leaf_key_rlp_length: u8 = get_rlp_length(first_key_byte, key_length); + assert(account.nonce_length <= 8_u8); + let leaf_value_rlp_data_length: u8 = ((get_rlp_length(account.balance[0_u32], account.balance_length) + get_rlp_length(account.nonce[0_u32], account.nonce_length)) + 33_u8) + 33_u8; + let leaf_rlp_total_length: u8 = ((leaf_key_rlp_length + leaf_value_rlp_data_length) + 2_u8) + 2_u8; + sink.add_byte(248_u8); + sink.add_byte(leaf_rlp_total_length); + if (key_length == 1_u8) & (first_key_byte <= 127_u8) { + sink.add_byte(first_key_byte); + } else { + sink.add_byte(128_u8 + key_length); + sink.add_byte(first_key_byte); + let start_byte_idx: u32 = current_nibble_idx / 2_u32; + let end_byte_idx: u32 = start_byte_idx + ((key_length - 1_u8) as u32); + { + assert(start_byte_idx <= end_byte_idx); + assert(end_byte_idx <= trie_key.len()); + if std::runtime::is_unconstrained() { + for i in start_byte_idx..end_byte_idx { + sink.add_byte(trie_key[i]); + () + } + } else { + for i in 0_u32..trie_key.len() { + if (i >= start_byte_idx) & (i < end_byte_idx) { + sink.add_byte(trie_key[i]); + () + } + } + } + }; + }; + sink.add_byte(184_u8); + sink.add_byte(leaf_value_rlp_data_length + 2_u8); + sink.add_byte(248_u8); + sink.add_byte(leaf_value_rlp_data_length); + if account.nonce_length == 0_u8 { + sink.add_byte(128_u8); + } else if (account.nonce_length == 1_u8) & (account.nonce[0_u32] <= 127_u8) { + sink.add_byte(account.nonce[0_u32]); + } else { + sink.add_byte(128_u8 + account.nonce_length); + { + assert(0_u32 <= (account.nonce_length as u32)); + assert((account.nonce_length as u32) <= 32_u32); + if std::runtime::is_unconstrained() { + for i in 0_u32..account.nonce_length as u32 { + sink.add_byte(account.nonce[i]); + () + } + } else { + for i in 0_u32..32_u32 { + if (i >= 0_u32) & (i < (account.nonce_length as u32)) { + sink.add_byte(account.nonce[i]); + () + } + } + } + }; + }; + if account.balance_length == 0_u8 { + sink.add_byte(128_u8); + } else if (account.balance_length == 1_u8) & (account.balance[0_u32] <= 127_u8) { + sink.add_byte(account.balance[0_u32]); + } else { + sink.add_byte(128_u8 + account.balance_length); + { + assert(0_u32 <= (account.balance_length as u32)); + assert((account.balance_length as u32) <= 32_u32); + if std::runtime::is_unconstrained() { + for i in 0_u32..account.balance_length as u32 { + sink.add_byte(account.balance[i]); + () + } + } else { + for i in 0_u32..32_u32 { + if (i >= 0_u32) & (i < (account.balance_length as u32)) { + sink.add_byte(account.balance[i]); + () + } + } + } + }; + }; + sink.add_byte(160_u8); + { + sink.add_u64(account.storage_hash[0_u32]); + sink.add_u64(account.storage_hash[1_u32]); + sink.add_u64(account.storage_hash[2_u32]); + sink.add_u64(account.storage_hash[3_u32]); + }; + sink.add_byte(160_u8); + { + sink.add_u64(account.code_hash[0_u32]); + sink.add_u64(account.code_hash[1_u32]); + sink.add_u64(account.code_hash[2_u32]); + sink.add_u64(account.code_hash[3_u32]); + }; + } + + unconstrained fn rlp_encode_unconstrained(account: Account, start_nibble_idx: u32, trie_key: [u8; 32]) -> ([u8; 147], u32) { + let mut writer: BytesWriter<147> = BytesWriter::<147>::new(); + rlp_encode_to_sink(account, start_nibble_idx, trie_key, &mut writer); + writer.finish() + } + + pub fn compute_account_hash(account: Account, start_nibble_idx: u32, trie_key: [u8; 32]) -> [u64; 4] { + if std::runtime::is_unconstrained() { + let mut hasher: KeccakHasher = KeccakHasher::new(); + rlp_encode_to_sink(account, start_nibble_idx, trie_key, &mut hasher); + hasher.finish_to_limbs() + } else { + // Safety: comment added by `nargo expand` + let (bytes, length): ([u8; 147], u32) = unsafe { + rlp_encode_unconstrained(account, start_nibble_idx, trie_key) + }; + let mut checker: BytesChecker<147> = BytesChecker::<147>::new(bytes, length); + rlp_encode_to_sink(account, start_nibble_idx, trie_key, &mut checker); + checker.finish(); + keccak256_limbs(bytes, length) + } + } + } + + pub mod branch_hash { + use super::bytes_sink::BytesChecker; + use super::bytes_sink::BytesSink; + use super::bytes_sink::BytesWriter; + use super::keccak::keccak256_limbs; + use super::keccak::KeccakHasher; + use super::types::Node; + use super::utils::unroll_loop; + + global BRANCH_RLP_MAX_LENGTH: u32 = 532; + + #[inline_always] + fn compute_rlp_length(node: Node) -> u16 { + let mut len: u16 = 0_u16; + { + if node.row_exist[0_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[1_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[2_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[3_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[4_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[5_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[6_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[7_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[8_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[9_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[10_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[11_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[12_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[13_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[14_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + }; + if node.row_exist[15_u32] { + len = len + 33_u16; + } else { + len = len + 1_u16; + } + }; + len = len + 1_u16; + len + } + + #[inline_always] + fn rlp_encode_to_sink(node: Node, sink: &mut S) where S: BytesSink { + let len: u16 = compute_rlp_length(node); + if len <= 55_u16 { + sink.add_byte(192_u8 + (len as u8)); + } else if len <= 255_u16 { + sink.add_byte(248_u8); + sink.add_byte(len as u8); + } else { + sink.add_byte(249_u8); + sink.add_byte((len >> 8_u16) as u8); + sink.add_byte((len & 255_u16) as u8); + }; + { + if node.row_exist[0_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[0_u32][0_u32]); + sink.add_u64(node.rows[0_u32][1_u32]); + sink.add_u64(node.rows[0_u32][2_u32]); + sink.add_u64(node.rows[0_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[1_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[1_u32][0_u32]); + sink.add_u64(node.rows[1_u32][1_u32]); + sink.add_u64(node.rows[1_u32][2_u32]); + sink.add_u64(node.rows[1_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[2_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[2_u32][0_u32]); + sink.add_u64(node.rows[2_u32][1_u32]); + sink.add_u64(node.rows[2_u32][2_u32]); + sink.add_u64(node.rows[2_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[3_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[3_u32][0_u32]); + sink.add_u64(node.rows[3_u32][1_u32]); + sink.add_u64(node.rows[3_u32][2_u32]); + sink.add_u64(node.rows[3_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[4_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[4_u32][0_u32]); + sink.add_u64(node.rows[4_u32][1_u32]); + sink.add_u64(node.rows[4_u32][2_u32]); + sink.add_u64(node.rows[4_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[5_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[5_u32][0_u32]); + sink.add_u64(node.rows[5_u32][1_u32]); + sink.add_u64(node.rows[5_u32][2_u32]); + sink.add_u64(node.rows[5_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[6_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[6_u32][0_u32]); + sink.add_u64(node.rows[6_u32][1_u32]); + sink.add_u64(node.rows[6_u32][2_u32]); + sink.add_u64(node.rows[6_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[7_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[7_u32][0_u32]); + sink.add_u64(node.rows[7_u32][1_u32]); + sink.add_u64(node.rows[7_u32][2_u32]); + sink.add_u64(node.rows[7_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[8_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[8_u32][0_u32]); + sink.add_u64(node.rows[8_u32][1_u32]); + sink.add_u64(node.rows[8_u32][2_u32]); + sink.add_u64(node.rows[8_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[9_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[9_u32][0_u32]); + sink.add_u64(node.rows[9_u32][1_u32]); + sink.add_u64(node.rows[9_u32][2_u32]); + sink.add_u64(node.rows[9_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[10_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[10_u32][0_u32]); + sink.add_u64(node.rows[10_u32][1_u32]); + sink.add_u64(node.rows[10_u32][2_u32]); + sink.add_u64(node.rows[10_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[11_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[11_u32][0_u32]); + sink.add_u64(node.rows[11_u32][1_u32]); + sink.add_u64(node.rows[11_u32][2_u32]); + sink.add_u64(node.rows[11_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[12_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[12_u32][0_u32]); + sink.add_u64(node.rows[12_u32][1_u32]); + sink.add_u64(node.rows[12_u32][2_u32]); + sink.add_u64(node.rows[12_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[13_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[13_u32][0_u32]); + sink.add_u64(node.rows[13_u32][1_u32]); + sink.add_u64(node.rows[13_u32][2_u32]); + sink.add_u64(node.rows[13_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[14_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[14_u32][0_u32]); + sink.add_u64(node.rows[14_u32][1_u32]); + sink.add_u64(node.rows[14_u32][2_u32]); + sink.add_u64(node.rows[14_u32][3_u32]); + } else { + sink.add_byte(128_u8); + }; + if node.row_exist[15_u32] { + sink.add_byte(160_u8); + sink.add_u64(node.rows[15_u32][0_u32]); + sink.add_u64(node.rows[15_u32][1_u32]); + sink.add_u64(node.rows[15_u32][2_u32]); + sink.add_u64(node.rows[15_u32][3_u32]); + } else { + sink.add_byte(128_u8); + } + }; + sink.add_byte(128_u8); + } + + unconstrained fn rlp_encode_unconstrained(node: Node) -> ([u8; 532], u32) { + let mut writer: BytesWriter<532> = BytesWriter::<532>::new(); + rlp_encode_to_sink(node, &mut writer); + writer.finish() + } + + pub fn rlp_and_hash_branch_node(node: Node) -> [u64; 4] { + if std::runtime::is_unconstrained() { + let mut hasher: KeccakHasher = KeccakHasher::new(); + rlp_encode_to_sink(node, &mut hasher); + hasher.finish_to_limbs() + } else { + // Safety: comment added by `nargo expand` + let (bytes, length): ([u8; 532], u32) = unsafe { + rlp_encode_unconstrained(node) + }; + let mut checker: BytesChecker<532> = BytesChecker::<532>::new(bytes, length); + rlp_encode_to_sink(node, &mut checker); + checker.finish(); + keccak256_limbs(bytes, length) + } + } + } + + pub mod bytes_sink { + use super::keccak::KeccakHasher; + + pub trait BytesSink { + fn add_byte(&mut self, byte: u8); + + fn add_u64(&mut self, value: u64); + } + + /// Writes bytes to an array. + pub struct BytesWriter { + bytes: [u8; N], + index: u32, + } + + impl BytesWriter { + pub fn new() -> Self { + Self { bytes: [0_u8; N], index: 0_u32} + } + + pub fn finish(self) -> ([u8; N], u32) { + (self.bytes, self.index) + } + } + + impl BytesSink for BytesWriter { + fn add_byte(&mut self, byte: u8) { + self.bytes[self.index] = byte; + self.index = self.index + 1_u32; + } + + fn add_u64(&mut self, mut value: u64) { + for _ in 0_u32..8_u32 { + self.add_byte(value as u8); + value = value >> 8_u64; + } + } + } + + /// Checks that a given array matches the expected bytes written, up to a given length. + pub struct BytesChecker { + bytes: [u8; N], + index: u32, + expected_length: u32, + } + + impl BytesChecker { + pub fn new(bytes: [u8; N], expected_length: u32) -> Self { + Self { bytes: bytes, index: 0_u32, expected_length: expected_length} + } + + pub fn finish(self) { + assert(self.index == self.expected_length); + } + } + + impl BytesSink for BytesChecker { + fn add_byte(&mut self, byte: u8) { + assert(self.bytes[self.index] == byte); + self.index = self.index + 1_u32; + } + + fn add_u64(&mut self, mut value: u64) { + for _ in 0_u32..8_u32 { + self.add_byte(value as u8); + value = value >> 8_u64; + } + } + } + } + + pub mod extension_hash { + use super::bytes_sink::BytesChecker; + use super::bytes_sink::BytesSink; + use super::bytes_sink::BytesWriter; + use super::keccak::keccak256_limbs; + use super::keccak::KeccakHasher; + use super::types::ExtensionHeader; + use super::types::Node; + use super::utils::unroll_loop; + + global EXTENSION_RLP_MAX_LENGTH: u32 = 68; + + #[inline_always] + fn rlp_encode_to_sink(node: Node, header: ExtensionHeader, sink: &mut S) where S: BytesSink { + let extension_length_size: u8 = header.extension_length + 1_u8; + let rlp_data_length: u8 = (extension_length_size + 33_u8) + ((extension_length_size != 1_u8) as u8); + if rlp_data_length > 55_u8 { + sink.add_byte(248_u8); + sink.add_byte(rlp_data_length); + } else { + sink.add_byte(192_u8 + rlp_data_length); + }; + if extension_length_size != 1_u8 { + sink.add_byte(128_u8 + extension_length_size); + }; + sink.add_byte(((header.is_odd as u8) << 4_u8) + header.first_nibble); + { + if (0_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 0_u32)); + }; + if (1_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 1_u32)); + }; + if (2_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 2_u32)); + }; + if (3_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 3_u32)); + }; + if (4_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 4_u32)); + }; + if (5_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 5_u32)); + }; + if (6_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 6_u32)); + }; + if (7_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 7_u32)); + }; + if (8_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 8_u32)); + }; + if (9_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 9_u32)); + }; + if (10_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 10_u32)); + }; + if (11_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 11_u32)); + }; + if (12_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 12_u32)); + }; + if (13_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 13_u32)); + }; + if (14_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 14_u32)); + }; + if (15_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 15_u32)); + }; + if (16_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 16_u32)); + }; + if (17_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 17_u32)); + }; + if (18_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 18_u32)); + }; + if (19_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 19_u32)); + }; + if (20_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 20_u32)); + }; + if (21_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 21_u32)); + }; + if (22_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 22_u32)); + }; + if (23_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 23_u32)); + }; + if (24_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 24_u32)); + }; + if (25_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 25_u32)); + }; + if (26_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 26_u32)); + }; + if (27_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 27_u32)); + }; + if (28_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 28_u32)); + }; + if (29_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 29_u32)); + }; + if (30_u32 as u8) < header.extension_length { + sink.add_byte(node.get_row_byte(1_u32, 30_u32)); + } + }; + sink.add_byte(160_u8); + { + sink.add_u64(node.rows[2_u32][0_u32]); + sink.add_u64(node.rows[2_u32][1_u32]); + sink.add_u64(node.rows[2_u32][2_u32]); + sink.add_u64(node.rows[2_u32][3_u32]); + }; + } + + unconstrained fn rlp_encode_unconstrained(node: Node, header: ExtensionHeader) -> ([u8; 68], u32) { + let mut writer: BytesWriter<68> = BytesWriter::<68>::new(); + rlp_encode_to_sink(node, header, &mut writer); + writer.finish() + } + + pub fn rlp_and_hash_extension_node(node: Node, header: ExtensionHeader) -> [u64; 4] { + if std::runtime::is_unconstrained() { + let mut hasher: KeccakHasher = KeccakHasher::new(); + rlp_encode_to_sink(node, header, &mut hasher); + hasher.finish_to_limbs() + } else { + // Safety: comment added by `nargo expand` + let (bytes, length): ([u8; 68], u32) = unsafe { + rlp_encode_unconstrained(node, header) + }; + let mut checker: BytesChecker<68> = BytesChecker::<68>::new(bytes, length); + rlp_encode_to_sink(node, header, &mut checker); + checker.finish(); + keccak256_limbs(bytes, length) + } + } + } + + pub mod keccak { + use keccak256::keccak256 as keccak256lib; + use keccak256::keccak256 as keccak256lib; + use std::hash::keccakf1600; + + global BLOCK_SIZE_IN_BYTES: u32 = 136; + + global WORD_SIZE: u32 = 8; + + global LIMBS_PER_BLOCK: u32 = 17; + + global NUM_KECCAK_LANES: u32 = 25; + + pub struct KeccakHasher { + state: [u64; 25], + limb_index_to_write: u32, + current_limb: u64, + current_limb_shift: u64, + } + + impl KeccakHasher { + pub fn new() -> Self { + Self { state: [0_u64; 25], limb_index_to_write: 0_u32, current_limb: 0_u64, current_limb_shift: 0_u64} + } + + pub fn hash_bytes(bytes: [u8; N], length: u32) -> [u8; 32] { + let mut hasher: Self = Self::new(); + for i in 0_u32..length { + hasher.add_byte(bytes[i]); + }; + hasher.finish() + } + + pub fn hash_bytes_to_limbs(bytes: [u8; N], length: u32) -> [u64; 4] { + let mut hasher: Self = Self::new(); + for i in 0_u32..length { + hasher.add_byte(bytes[i]); + }; + hasher.finish_to_limbs() + } + + pub fn add_byte(&mut self, byte: u8) { + let byte_as_u64: u64 = byte as u64; + let shifted_byte: u64 = byte_as_u64 << self.current_limb_shift; + self.current_limb = self.current_limb + shifted_byte; + if self.current_limb_shift == 56_u64 { + self.finish_limb(); + } else { + self.current_limb_shift = self.current_limb_shift + 8_u64; + } + } + + pub fn add_u64(&mut self, value: u64) { + if self.current_limb_shift == 0_u64 { + self.current_limb = value; + self.finish_limb(); + } else { + let shift: u64 = self.current_limb_shift; + self.current_limb = self.current_limb + (value << shift); + self.finish_limb(); + self.current_limb = value >> (64_u64 - shift); + self.current_limb_shift = shift; + } + } + + #[inline_always] + fn finish_limb(&mut self) { + self.state[self.limb_index_to_write] = self.state[self.limb_index_to_write] ^ self.current_limb; + self.current_limb_shift = 0_u64; + self.current_limb = 0_u64; + if self.limb_index_to_write == (LIMBS_PER_BLOCK - 1_u32) { + self.finish_block(); + } else { + self.limb_index_to_write = self.limb_index_to_write + 1_u32; + } + } + + #[inline_always] + fn finish_block(&mut self) { + self.state = keccakf1600(self.state); + self.limb_index_to_write = 0_u32; + } + + #[inline_always] + fn apply_padding(&mut self) { + self.state[self.limb_index_to_write] = self.state[self.limb_index_to_write] ^ (self.current_limb + (1_u64 << self.current_limb_shift)); + { + let i_0: u32 = LIMBS_PER_BLOCK - 1_u32; + self.state[i_0] = self.state[LIMBS_PER_BLOCK - 1_u32] ^ (128_u64 << 56_u64); + } + } + + pub fn finish_to_limbs(mut self) -> [u64; 4] { + self.apply_padding(); + self.finish_block(); + [self.state[0_u32], self.state[1_u32], self.state[2_u32], self.state[3_u32]] + } + + pub fn finish(mut self) -> [u8; 32] { + self.apply_padding(); + self.finish_block(); + let mut result: [u8; 32] = [0_u8; 32]; + for i in 0_u32..4_u32 { + let lane: Field = self.state[i] as Field; + let lane_le: [u8; 8] = lane.to_be_bytes(); + for j in 0_u32..8_u32 { + { + let i_0: u32 = (8_u32 * i) + j; + result[i_0] = lane_le[7_u32 - j]; + } + } + }; + result + } + } + + impl super::bytes_sink::BytesSink for KeccakHasher { + fn add_byte(&mut self, byte: u8) { + self.add_byte(byte); + } + + fn add_u64(&mut self, mut value: u64) { + self.add_u64(value); + } + } + + pub fn keccak256(input: [u8; N], message_size: u32) -> [u8; 32] { + keccak256lib(input, message_size) + } + + pub fn keccak256_limbs(input: [u8; N], message_size: u32) -> [u64; 4] { + let bytes: [u8; 32] = keccak256lib(input, message_size); + bytes_to_u64(bytes) + } + + fn bytes_to_u64(bytes: [u8; N]) -> [u64; K] { + std::static_assert((K * 8_u32) == N, "Invalid number of u64s for given number of bytes"); + let mut result: [u64; K] = [0_u64; K]; + for i in 0_u32..K { + let mut value: u64 = 0_u64; + for j in 0_u32..8_u32 { + let byte: u8 = bytes[(i * 8_u32) + j]; + value = value + ((byte as u64) << ((8_u32 * j) as u64)); + }; + result[i] = value; + }; + result + } + } + + pub mod path_verification { + use super::branch_hash; + use super::extension_hash; + use super::types::Node; + use super::utils::runtime_loop; + + pub fn verify_path_section(nodes: [Node; MAX_PATH_LENGTH], node_length: u32, start_trie_key_index: u32, mut parent: [u64; 4], trie_key_nibbles: [u8; 64]) -> ([u64; 4], u32) { + let mut current_nibble_idx: u32 = start_trie_key_index; + { + assert(0_u32 <= node_length); + assert(node_length <= MAX_PATH_LENGTH); + if std::runtime::is_unconstrained() { + for i in 0_u32..node_length { + let node: Node = nodes[i]; + if node.is_branch_node() { + let hash: [u64; 4] = branch_hash::rlp_and_hash_branch_node(node); + assert(hash == parent); + let index: u32 = trie_key_nibbles[current_nibble_idx] as u32; + parent = node.rows[index]; + current_nibble_idx = current_nibble_idx + 1_u32; + } else if node.is_extension_node() { + let header: super::types::ExtensionHeader = node.extract_extension_header(); + let hash: [u64; 4] = extension_hash::rlp_and_hash_extension_node(node, header); + assert(hash == parent); + if header.is_odd { + assert(trie_key_nibbles[current_nibble_idx] == header.first_nibble); + current_nibble_idx = current_nibble_idx + 1_u32; + }; + { + assert(0_u32 <= (header.extension_length as u32)); + assert((header.extension_length as u32) <= 32_u32); + if std::runtime::is_unconstrained() { + for j in 0_u32..header.extension_length as u32 { + let high_key_nibble: u8 = trie_key_nibbles[current_nibble_idx]; + let low_key_nibble: u8 = trie_key_nibbles[current_nibble_idx + 1_u32]; + let key_byte: u8 = (high_key_nibble << 4_u8) + low_key_nibble; + current_nibble_idx = current_nibble_idx + 2_u32; + let extension_byte: u8 = node.get_row_byte(1_u32, j); + assert(key_byte == extension_byte); + () + } + } else { + for j in 0_u32..32_u32 { + if (j >= 0_u32) & (j < (header.extension_length as u32)) { + let high_key_nibble: u8 = trie_key_nibbles[current_nibble_idx]; + let low_key_nibble: u8 = trie_key_nibbles[current_nibble_idx + 1_u32]; + let key_byte: u8 = (high_key_nibble << 4_u8) + low_key_nibble; + current_nibble_idx = current_nibble_idx + 2_u32; + let extension_byte: u8 = node.get_row_byte(1_u32, j); + assert(key_byte == extension_byte); + () + } + } + } + }; + parent = node.rows[2_u32]; + } else { + assert(false); + }; + () + } + } else { + for i in 0_u32..MAX_PATH_LENGTH { + if (i >= 0_u32) & (i < node_length) { + let node: Node = nodes[i]; + if node.is_branch_node() { + let hash: [u64; 4] = branch_hash::rlp_and_hash_branch_node(node); + assert(hash == parent); + let index: u32 = trie_key_nibbles[current_nibble_idx] as u32; + parent = node.rows[index]; + current_nibble_idx = current_nibble_idx + 1_u32; + } else if node.is_extension_node() { + let header: super::types::ExtensionHeader = node.extract_extension_header(); + let hash: [u64; 4] = extension_hash::rlp_and_hash_extension_node(node, header); + assert(hash == parent); + if header.is_odd { + assert(trie_key_nibbles[current_nibble_idx] == header.first_nibble); + current_nibble_idx = current_nibble_idx + 1_u32; + }; + { + assert(0_u32 <= (header.extension_length as u32)); + assert((header.extension_length as u32) <= 32_u32); + if std::runtime::is_unconstrained() { + for j in 0_u32..header.extension_length as u32 { + let high_key_nibble: u8 = trie_key_nibbles[current_nibble_idx]; + let low_key_nibble: u8 = trie_key_nibbles[current_nibble_idx + 1_u32]; + let key_byte: u8 = (high_key_nibble << 4_u8) + low_key_nibble; + current_nibble_idx = current_nibble_idx + 2_u32; + let extension_byte: u8 = node.get_row_byte(1_u32, j); + assert(key_byte == extension_byte); + () + } + } else { + for j in 0_u32..32_u32 { + if (j >= 0_u32) & (j < (header.extension_length as u32)) { + let high_key_nibble: u8 = trie_key_nibbles[current_nibble_idx]; + let low_key_nibble: u8 = trie_key_nibbles[current_nibble_idx + 1_u32]; + let key_byte: u8 = (high_key_nibble << 4_u8) + low_key_nibble; + current_nibble_idx = current_nibble_idx + 2_u32; + let extension_byte: u8 = node.get_row_byte(1_u32, j); + assert(key_byte == extension_byte); + () + } + } + } + }; + parent = node.rows[2_u32]; + } else { + assert(false); + }; + () + } + } + } + }; + (parent, current_nibble_idx) + } + } + + pub mod slot_hash { + use super::bytes_sink::BytesChecker; + use super::bytes_sink::BytesSink; + use super::bytes_sink::BytesWriter; + use super::keccak::keccak256_limbs; + use super::keccak::KeccakHasher; + use super::types::StorageSlot; + use super::utils::get_low_nibble; + use super::utils::get_rlp_length; + use super::utils::runtime_loop; + + global SLOT_RLP_MAX_LENGTH: u32 = 69; + + #[inline_always] + fn rlp_encode_to_sink(slot: StorageSlot, start_nibble_idx: u32, trie_key: [u8; 32], sink: &mut S) where S: BytesSink { + let mut current_nibble_idx: u32 = start_nibble_idx; + let first_key_byte: u8 = if (current_nibble_idx % 2_u32) == 0_u32 { + 32_u8 + } else { + let first_byte: u8 = trie_key[(current_nibble_idx / 2_u32) as u32]; + current_nibble_idx = current_nibble_idx + 1_u32; + 48_u8 + get_low_nibble(first_byte) + }; + let key_length: u8 = (32_u8 - ((current_nibble_idx as u8) / 2_u8)) + 1_u8; + let leaf_key_rlp_length: u8 = get_rlp_length(first_key_byte, key_length); + assert(slot.value_length <= 32_u8); + let inner_rlp_length: u8 = get_rlp_length(slot.value[0_u32], slot.value_length); + let inner_first_byte: u8 = if slot.value_length == 0_u8 { + 128_u8 + } else if (slot.value_length == 1_u8) & (slot.value[0_u32] <= 127_u8) { + slot.value[0_u32] + } else { + 128_u8 + slot.value_length + }; + let outer_rlp_length: u8 = get_rlp_length(inner_first_byte, inner_rlp_length); + let leaf_rlp_total_length: u8 = leaf_key_rlp_length + outer_rlp_length; + if leaf_rlp_total_length <= 55_u8 { + sink.add_byte(192_u8 + leaf_rlp_total_length); + } else { + sink.add_byte(248_u8); + sink.add_byte(leaf_rlp_total_length); + }; + if (key_length == 1_u8) & (first_key_byte <= 127_u8) { + sink.add_byte(first_key_byte); + } else { + sink.add_byte(128_u8 + key_length); + sink.add_byte(first_key_byte); + let start_byte_idx: u32 = current_nibble_idx / 2_u32; + let end_byte_idx: u32 = start_byte_idx + ((key_length - 1_u8) as u32); + { + assert(start_byte_idx <= end_byte_idx); + assert(end_byte_idx <= trie_key.len()); + if std::runtime::is_unconstrained() { + for i in start_byte_idx..end_byte_idx { + sink.add_byte(trie_key[i]); + () + } + } else { + for i in 0_u32..trie_key.len() { + if (i >= start_byte_idx) & (i < end_byte_idx) { + sink.add_byte(trie_key[i]); + () + } + } + } + }; + }; + if (inner_rlp_length == 1_u8) & (inner_first_byte <= 127_u8) { + } else { + sink.add_byte(128_u8 + inner_rlp_length); + }; + if slot.value_length == 0_u8 { + sink.add_byte(128_u8); + } else if (slot.value_length == 1_u8) & (slot.value[0_u32] <= 127_u8) { + sink.add_byte(slot.value[0_u32]); + } else { + sink.add_byte(128_u8 + slot.value_length); + { + assert(0_u32 <= (slot.value_length as u32)); + assert((slot.value_length as u32) <= 32_u32); + if std::runtime::is_unconstrained() { + for i in 0_u32..slot.value_length as u32 { + sink.add_byte(slot.value[i]); + () + } + } else { + for i in 0_u32..32_u32 { + if (i >= 0_u32) & (i < (slot.value_length as u32)) { + sink.add_byte(slot.value[i]); + () + } + } + } + }; + } + } + + unconstrained fn rlp_encode_unconstrained(slot: StorageSlot, start_nibble_idx: u32, trie_key: [u8; 32]) -> ([u8; 69], u32) { + let mut writer: BytesWriter<69> = BytesWriter::<69>::new(); + rlp_encode_to_sink(slot, start_nibble_idx, trie_key, &mut writer); + writer.finish() + } + + pub fn compute_slot_hash(slot: StorageSlot, start_nibble_idx: u32, trie_key: [u8; 32]) -> [u64; 4] { + if std::runtime::is_unconstrained() { + let mut hasher: KeccakHasher = KeccakHasher::new(); + rlp_encode_to_sink(slot, start_nibble_idx, trie_key, &mut hasher); + hasher.finish_to_limbs() + } else { + // Safety: comment added by `nargo expand` + let (bytes, length): ([u8; 69], u32) = unsafe { + rlp_encode_unconstrained(slot, start_nibble_idx, trie_key) + }; + let mut checker: BytesChecker<69> = BytesChecker::<69>::new(bytes, length); + rlp_encode_to_sink(slot, start_nibble_idx, trie_key, &mut checker); + checker.finish(); + keccak256_limbs(bytes, length) + } + } + } + + pub mod types { + use super::utils::get_low_nibble; + use aztec::protocol::traits::Deserialize; + use aztec::protocol::traits::Serialize; + + pub struct ExtensionHeader { + pub is_odd: bool, + pub first_nibble: u8, + pub extension_length: u8, + } + + pub struct Node { + pub rows: [[u64; 4]; 16], + pub row_exist: [bool; 16], + pub node_type: u8, + } + + impl Node { + #[inline_always] + pub fn is_branch_node(self) -> bool { + self.node_type == 0_u8 + } + + #[inline_always] + pub fn is_extension_node(self) -> bool { + self.node_type == 1_u8 + } + + #[inline_always] + pub fn get_row_byte(self, row: u32, byte_index: u32) -> u8 { + let limb_index: u32 = byte_index / 8_u32; + let shift: u64 = ((byte_index % 8_u32) * 8_u32) as u64; + (self.rows[row][limb_index] >> shift) as u8 + } + + pub fn extract_extension_header(self) -> ExtensionHeader { + let is_odd: bool = self.rows[0_u32][0_u32] != 0_u64; + let first_nibble: u8 = if is_odd { + get_low_nibble(self.rows[0_u32][1_u32] as u8) + } else { + 0_u8 + }; + let extension_length: u8 = self.rows[0_u32][2_u32] as u8; + ExtensionHeader { is_odd: is_odd, first_nibble: first_nibble, extension_length: extension_length} + } + } + + impl Serialize for Node { + let N: u32 = 81; + + fn serialize(self) -> [Field; 81] { + let mut writer: aztec::protocol::utils::writer::Writer<81> = aztec::protocol::utils::writer::Writer::<81>::new(); + self.stream_serialize(&mut writer); + writer.finish() + } + + #[inline_always] + fn stream_serialize(self, writer: &mut aztec::protocol::utils::writer::Writer) { + self.rows.stream_serialize(writer); + self.row_exist.stream_serialize(writer); + self.node_type.stream_serialize(writer); + } + } + + impl Deserialize for Node { + let N: u32 = 81; + + fn deserialize(fields: [Field; 81]) -> Self { + let mut reader: aztec::protocol::utils::reader::Reader<81> = aztec::protocol::utils::reader::Reader::<81>::new(fields); + let result: Self = Self::stream_deserialize(&mut reader); + reader.finish(); + result + } + + #[inline_always] + fn stream_deserialize(reader: &mut aztec::protocol::utils::reader::Reader) -> Self { + let rows: [[u64; 4]; 16] = <[[u64; 4]; 16] as Deserialize>::stream_deserialize(reader); + let row_exist: [bool; 16] = <[bool; 16] as Deserialize>::stream_deserialize(reader); + let node_type: u8 = ::stream_deserialize(reader); + Self { rows: rows, row_exist: row_exist, node_type: node_type} + } + } + + pub struct Account { + pub nonce: [u8; 8], + pub balance: [u8; 32], + pub address: [u8; 20], + pub nonce_length: u8, + pub balance_length: u8, + pub storage_hash: [u64; 4], + pub code_hash: [u64; 4], + } + + impl Serialize for Account { + let N: u32 = 70; + + fn serialize(self) -> [Field; 70] { + let mut writer: aztec::protocol::utils::writer::Writer<70> = aztec::protocol::utils::writer::Writer::<70>::new(); + self.stream_serialize(&mut writer); + writer.finish() + } + + #[inline_always] + fn stream_serialize(self, writer: &mut aztec::protocol::utils::writer::Writer) { + self.nonce.stream_serialize(writer); + self.balance.stream_serialize(writer); + self.address.stream_serialize(writer); + self.nonce_length.stream_serialize(writer); + self.balance_length.stream_serialize(writer); + self.storage_hash.stream_serialize(writer); + self.code_hash.stream_serialize(writer); + } + } + + impl Deserialize for Account { + let N: u32 = 70; + + fn deserialize(fields: [Field; 70]) -> Self { + let mut reader: aztec::protocol::utils::reader::Reader<70> = aztec::protocol::utils::reader::Reader::<70>::new(fields); + let result: Self = Self::stream_deserialize(&mut reader); + reader.finish(); + result + } + + #[inline_always] + fn stream_deserialize(reader: &mut aztec::protocol::utils::reader::Reader) -> Self { + let nonce: [u8; 8] = <[u8; 8] as Deserialize>::stream_deserialize(reader); + let balance: [u8; 32] = <[u8; 32] as Deserialize>::stream_deserialize(reader); + let address: [u8; 20] = <[u8; 20] as Deserialize>::stream_deserialize(reader); + let nonce_length: u8 = ::stream_deserialize(reader); + let balance_length: u8 = ::stream_deserialize(reader); + let storage_hash: [u64; 4] = <[u64; 4] as Deserialize>::stream_deserialize(reader); + let code_hash: [u64; 4] = <[u64; 4] as Deserialize>::stream_deserialize(reader); + Self { nonce: nonce, balance: balance, address: address, nonce_length: nonce_length, balance_length: balance_length, storage_hash: storage_hash, code_hash: code_hash} + } + } + + pub struct StorageSlot { + pub value: [u8; 32], + pub value_length: u8, + } + + impl Serialize for StorageSlot { + let N: u32 = 33; + + fn serialize(self) -> [Field; 33] { + let mut writer: aztec::protocol::utils::writer::Writer<33> = aztec::protocol::utils::writer::Writer::<33>::new(); + self.stream_serialize(&mut writer); + writer.finish() + } + + #[inline_always] + fn stream_serialize(self, writer: &mut aztec::protocol::utils::writer::Writer) { + self.value.stream_serialize(writer); + self.value_length.stream_serialize(writer); + } + } + + impl Deserialize for StorageSlot { + let N: u32 = 33; + + fn deserialize(fields: [Field; 33]) -> Self { + let mut reader: aztec::protocol::utils::reader::Reader<33> = aztec::protocol::utils::reader::Reader::<33>::new(fields); + let result: Self = Self::stream_deserialize(&mut reader); + reader.finish(); + result + } + + #[inline_always] + fn stream_deserialize(reader: &mut aztec::protocol::utils::reader::Reader) -> Self { + let value: [u8; 32] = <[u8; 32] as Deserialize>::stream_deserialize(reader); + let value_length: u8 = ::stream_deserialize(reader); + Self { value: value, value_length: value_length} + } + } + } + + pub mod utils { + use std::static_assert; + + /// Unrolls a loop at comptime + pub comptime fn unroll_loop(start: u32, end: u32, body: fn(u32) -> Quoted) -> Quoted { + let mut iterations: [Quoted] = @[]; + for i in start..end { + iterations = iterations.push_back(body(i)); + }; + iterations.join(quote { }) + } + + /// Creates a loop that: + /// - In ACIR: iterates from 0 to upper bound, and conditions body on index >= start_variable & index < end_variable + /// - In BRILLIG: iterates from start_variable to end_variable + pub comptime fn runtime_loop(iterator: Quoted, start_variable: Quoted, end_variable: Quoted, upper_bound: Quoted, body: Quoted) -> Quoted { + quote { + assert($start_variable <= $end_variable); + assert($end_variable <= $upper_bound); + if std::runtime::is_unconstrained() { + for $iterator in $start_variable..$end_variable { + $body() + } + } else { + for $iterator in 0..$upper_bound { + if $iterator >= $start_variable & $iterator < $end_variable { + $body() + } + } + } + } + } + + pub fn balance_to_field(balance: [u8; 32], balance_length: u8) -> Field { + let mut result: Field = 0_Field; + { + assert(0_u32 <= (balance_length as u32)); + assert((balance_length as u32) <= 32_u32); + if std::runtime::is_unconstrained() { + for i in 0_u32..balance_length as u32 { + result = result * 256_Field; + result = result + (balance[i] as Field); + () + } + } else { + for i in 0_u32..32_u32 { + if (i >= 0_u32) & (i < (balance_length as u32)) { + result = result * 256_Field; + result = result + (balance[i] as Field); + () + } + } + } + }; + result + } + + pub fn to_nibbles(bytes: [u8; N]) -> [u8; K] { + static_assert((N * 2_u32) == K, "Nibble amount should be double the byte amount"); + let mut nibbles: [u8; K] = [0_u8; K]; + for i in 0_u32..N { + let byte: u8 = bytes[i]; + { + let i_0: u32 = i * 2_u32; + nibbles[i_0] = byte >> 4_u8; + }; + { + let i_1: u32 = (i * 2_u32) + 1_u32; + nibbles[i_1] = (byte << 4_u8) >> 4_u8; + } + }; + nibbles + } + + #[inline_always] + pub fn get_low_nibble(byte: u8) -> u8 { + (byte << 4_u8) >> 4_u8 + } + + #[inline_always] + pub fn get_high_nibble(byte: u8) -> u8 { + byte >> 4_u8 + } + + pub fn get_rlp_length(first_elem: u8, length: u8) -> u8 { + let mut rlp_length: u8 = 0_u8; + if length == 0_u8 { + rlp_length = 1_u8; + } else if length == 1_u8 { + if first_elem <= 127_u8 { + rlp_length = 1_u8; + } else { + rlp_length = 2_u8; + } + } else { + rlp_length = 1_u8 + length; + }; + rlp_length + } + } +} + +// Warning: the generated code has syntax errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/token_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/token_contract/snapshots__expanded.snap new file mode 100644 index 000000000000..ca20d6e6efd9 --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/token_contract/snapshots__expanded.snap @@ -0,0 +1,4965 @@ +--- +source: tests/snapshots.rs +expression: stdout +--- +use aztec::macros::aztec; +use aztec::macros::aztec; + +pub contract Token { + use std::ops::Add; + use std::ops::Sub; + use compressed_string::FieldCompressedString; + use aztec::authwit::auth::compute_authwit_nullifier; + use aztec::context::calls::PrivateCall; + use aztec::context::PrivateContext; + use aztec::macros::events::event; + use aztec::macros::functions::authorize_once; + use aztec::macros::functions::external; + use aztec::macros::functions::initializer; + use aztec::macros::functions::internal; + use aztec::macros::functions::only_self; + use aztec::macros::functions::view; + use aztec::macros::storage::storage; + use aztec::messages::message_delivery::MessageDelivery; + use aztec::protocol::address::AztecAddress; + use aztec::protocol::traits::ToField; + use aztec::state_vars::Map; + use aztec::state_vars::Owned; + use aztec::state_vars::PublicImmutable; + use aztec::state_vars::PublicMutable; + use aztec::state_vars::StateVariable; + use uint_note::PartialUintNote; + use uint_note::UintNote; + use balance_set::BalanceSet; + + global INITIAL_TRANSFER_CALL_MAX_NOTES: u32 = 2; + + global RECURSIVE_TRANSFER_CALL_MAX_NOTES: u32 = 8; + + #[abi(events)] + struct Transfer { + from: AztecAddress, + to: AztecAddress, + amount: u128, + } + + impl aztec::event::event_interface::EventInterface for Transfer { + fn get_event_type_id() -> aztec::event::EventSelector { + ::from_field(1889634638_Field) + } + } + + impl aztec::protocol::traits::Serialize for Transfer { + let N: u32 = 3; + + fn serialize(self) -> [Field; 3] { + let mut writer: aztec::protocol::utils::writer::Writer<3> = aztec::protocol::utils::writer::Writer::<3>::new(); + >::stream_serialize(self, &mut writer); + writer.finish() + } + + #[inline_always] + fn stream_serialize(self, writer: &mut aztec::protocol::utils::writer::Writer) { + ::stream_serialize(self.from, writer); + ::stream_serialize(self.to, writer); + ::stream_serialize(self.amount, writer); + } + } + + struct Storage { + admin: PublicMutable, + minters: Map, Context>, + balances: Owned, Context>, + total_supply: PublicMutable, + public_balances: Map, Context>, + symbol: PublicImmutable, + name: PublicImmutable, + decimals: PublicImmutable, + } + + impl Storage { + fn init(context: Context) -> Self { + Self { admin: as StateVariable<1, Context>>::new(context, 1_Field), minters: , Context> as StateVariable<1, Context>>::new(context, 2_Field), balances: , Context> as StateVariable<1, Context>>::new(context, 3_Field), total_supply: as StateVariable<1, Context>>::new(context, 4_Field), public_balances: , Context> as StateVariable<1, Context>>::new(context, 5_Field), symbol: as StateVariable<2, Context>>::new(context, 6_Field), name: as StateVariable<2, Context>>::new(context, 8_Field), decimals: as StateVariable<2, Context>>::new(context, 10_Field)} + } + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call constructor. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn constructor(admin: AztecAddress, name: str<31>, symbol: str<31>, decimals: u8); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_admin. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_admin(new_admin: AztecAddress); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call public_get_name. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn public_get_name() -> FieldCompressedString; + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call private_get_name. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn private_get_name() -> FieldCompressedString; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call public_get_symbol. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn public_get_symbol() -> pub FieldCompressedString; + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call private_get_symbol. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn private_get_symbol() -> pub FieldCompressedString; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call public_get_decimals. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn public_get_decimals() -> pub u8; + + #[abi(storage)] + pub global STORAGE_LAYOUT_Token: StorageLayout<5> = StorageLayout::<5> { + contract_name: "Token", + fields: StorageLayoutFields { + decimals: aztec::state_vars::Storable { + slot: 0x0a, + }, + symbol: aztec::state_vars::Storable { + slot: 0x06, + }, + total_supply: aztec::state_vars::Storable { + slot: 0x04, + }, + minters: aztec::state_vars::Storable { + slot: 0x02, + }, + public_balances: aztec::state_vars::Storable { + slot: 0x05, + }, + admin: aztec::state_vars::Storable { + slot: 0x01, + }, + name: aztec::state_vars::Storable { + slot: 0x08, + }, + balances: aztec::state_vars::Storable { + slot: 0x03, + }, + }, + }; + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call private_get_decimals. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn private_get_decimals() -> pub u8; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call get_admin. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn get_admin() -> Field; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call is_minter. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn is_minter(minter: AztecAddress) -> bool; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call total_supply. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn total_supply() -> u128; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call balance_of_public. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn balance_of_public(owner: AztecAddress) -> u128; + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call set_minter. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn set_minter(minter: AztecAddress, approve: bool); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call mint_to_public. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn mint_to_public(to: AztecAddress, amount: u128); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call transfer_in_public. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn transfer_in_public(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call burn_public. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn burn_public(from: AztecAddress, amount: u128, authwit_nonce: Field); + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call transfer_to_public. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn transfer_to_public(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field); + + /// Transfers tokens from private balance of `from` to public balance of `to` and prepares a partial note for + /// receiving change for `from`. + /// + /// This is an optimization that combines two operations into one to reduce contract calls: + /// 1. Transfers `amount` tokens from `from`'s private balance to `to`'s public balance + /// 2. Creates a partial note that can later be used to receive change back to `from`'s private balance + /// + /// This pattern is useful when interacting with contracts that: + /// - Receive tokens from a user's private balance + /// - Need to wait until public execution to determine how many tokens to return (e.g. AMM, FPC) + /// - Will return tokens to the user's private balance + /// + /// The contract can use the returned partial note to complete the transfer back to private + /// once the final amount is known during public execution. + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call transfer_to_public_and_prepare_private_balance_increase. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn transfer_to_public_and_prepare_private_balance_increase(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> PartialUintNote; + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call transfer. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn transfer(to: AztecAddress, amount: u128); + + #[deprecated(deny, "Direct invocation of private internal functions is not supported. You attempted to call subtract_balance. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn subtract_balance(account: AztecAddress, amount: u128, max_notes: u32) -> u128; + + #[no_predicates] + #[contract_library_method] + fn compute_recurse_subtract_balance_call(context: PrivateContext, account: AztecAddress, remaining: u128) -> PrivateCall<25, 2, u128> { + Token::at(context.this_address())._recurse_subtract_balance(account, remaining) + } + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call _recurse_subtract_balance. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _recurse_subtract_balance(account: AztecAddress, amount: u128) -> u128; + + /// Cancel a private authentication witness. + /// @param inner_hash The inner hash of the authwit to cancel. + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call cancel_authwit. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn cancel_authwit(inner_hash: Field); + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call transfer_in_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn transfer_in_private(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field); + + /// Mirrors `transfer_in_private` but delivers the resulting notes via offchain messages. + /// + /// Offchain messages are returned to the caller as encrypted payloads. The sender is responsible for getting the + /// recipient's note to them (typically by encoding it into a link, QR code, or direct message). The recipient + /// ingests it by calling `offchain_receive` on their environment. + /// + /// A `Transfer` event is also emitted to be delivered offchain. + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call transfer_in_private_with_offchain_delivery. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn transfer_in_private_with_offchain_delivery(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field); + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call burn_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn burn_private(from: AztecAddress, amount: u128, authwit_nonce: Field); + + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call transfer_to_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn transfer_to_private(to: AztecAddress, amount: u128); + + /// Prepares an increase of private balance of `to` (partial note). The increase needs to be finalized by calling + /// some of the finalization functions (`finalize_transfer_to_private`, `finalize_mint_to_private`) with the + /// returned partial note. + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call prepare_private_balance_increase. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn prepare_private_balance_increase(to: AztecAddress) -> PartialUintNote; + + /// This function exists separately from `prepare_private_balance_increase` solely as an optimization as it allows + /// us to have it inlined in the `transfer_to_private` function which results in one fewer kernel iteration. Note + /// that in this case we don't pass `completer` as an argument to this function because in all the callsites we + /// want to use the message sender as the completer anyway. + #[deprecated(deny, "Direct invocation of private internal functions is not supported. You attempted to call _prepare_private_balance_increase. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _prepare_private_balance_increase(to: AztecAddress) -> PartialUintNote; + + /// Finalizes a transfer of token `amount` from public balance of `msg_sender` to a private balance of `to`. + /// The transfer must be prepared by calling `prepare_private_balance_increase` from `msg_sender` account and + /// the resulting `partial_note` must be passed as an argument to this function. + /// + /// Note that this contract does not protect against a `partial_note` being used multiple times and it is up to + /// the caller of this function to ensure that it doesn't happen. If the same `partial_note` is used multiple + /// times, the token `amount` would most likely get lost (the partial note log processing functionality would fail + /// to find the pending partial note when trying to complete it). + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call finalize_transfer_to_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn finalize_transfer_to_private(amount: u128, partial_note: PartialUintNote); + + /// Finalizes a transfer of token `amount` from private balance of `from` to a private balance of `to`. + /// The transfer must be prepared by calling `prepare_private_balance_increase` from `from` account and + /// the resulting `partial_note` must be passed as an argument to this function. + /// + /// Note that this contract does not protect against a `partial_note` being used multiple times and it is up to + /// the caller of this function to ensure that it doesn't happen. If the same `partial_note` is used multiple + /// times, the token `amount` would most likely get lost (the partial note log processing functionality would fail + /// to find the pending partial note when trying to complete it). + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call finalize_transfer_to_private_from_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn finalize_transfer_to_private_from_private(from: AztecAddress, partial_note: PartialUintNote, amount: u128, authwit_nonce: Field); + + /// This is a wrapper around `_finalize_transfer_to_private` placed here so that a call + /// to `_finalize_transfer_to_private` can be enqueued. Called unsafe as it does not check `from_and_completer` + /// (this has to be done in the calling function). + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call _finalize_transfer_to_private_unsafe. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _finalize_transfer_to_private_unsafe(from_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote); + + #[deprecated(deny, "Direct invocation of public internal functions is not supported. You attempted to call _finalize_transfer_to_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _finalize_transfer_to_private(from_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote); + + /// Mints token `amount` to a private balance of `to`. Message sender has to have minter permissions (checked + /// in the enqueued call). + #[deprecated(deny, "Direct invocation of private functions is not supported. You attempted to call mint_to_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn mint_to_private(to: AztecAddress, amount: u128); + + /// Finalizes a mint of token `amount` to a private balance of `to`. The mint must be prepared by calling + /// `prepare_private_balance_increase` first and the resulting + /// `partial_note` must be passed as an argument to this function. + /// + /// Note: This function is only an optimization as it could be replaced by a combination of `mint_to_public` + /// and `finalize_transfer_to_private`. It is however used very commonly so it makes sense to optimize it + /// (e.g. used during token bridging, in AMM liquidity token etc.). + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call finalize_mint_to_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn finalize_mint_to_private(amount: u128, partial_note: PartialUintNote); + + /// This is a wrapper around `_finalize_mint_to_private` placed here so that a call + /// to `_finalize_mint_to_private` can be enqueued. Called unsafe as it does not check `minter_and_completer` (this + /// has to be done in the calling function). + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call _finalize_mint_to_private_unsafe. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _finalize_mint_to_private_unsafe(minter_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote); + + #[deprecated(deny, "Direct invocation of public internal functions is not supported. You attempted to call _finalize_mint_to_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _finalize_mint_to_private(completer: AztecAddress, amount: u128, partial_note: PartialUintNote); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call _increase_public_balance. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _increase_public_balance(to: AztecAddress, amount: u128); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call _reduce_total_supply. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn _reduce_total_supply(amount: u128); + + #[deprecated(deny, "Direct invocation of utility functions is not supported. You attempted to call balance_of_private. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + unconstrained fn balance_of_private(owner: AztecAddress) -> u128; + + /// Unpacks an array into a note corresponding to `note_type_id` and then computes its note hash (non-siloed) and inner nullifier (non-siloed) assuming the note has been inserted into the note hash tree with `note_nonce`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + #[allow(dead_code)] + unconstrained fn _compute_note_hash_and_nullifier(packed_note: BoundedVec, owner: AztecAddress, storage_slot: Field, note_type_id: Field, contract_address: AztecAddress, randomness: Field, note_nonce: Field) -> Option { + _compute_note_hash(packed_note, owner, storage_slot, note_type_id, contract_address, randomness).map(|note_hash: Field| -> aztec::messages::discovery::NoteHashAndNullifier { + let siloed_note_hash: Field = aztec::protocol::hash::compute_siloed_note_hash(contract_address, note_hash); + let unique_note_hash: Field = aztec::protocol::hash::compute_unique_note_hash(note_nonce, siloed_note_hash); + let inner_nullifier: Option = _compute_note_nullifier(unique_note_hash, packed_note, owner, storage_slot, note_type_id, contract_address, randomness); + aztec::messages::discovery::NoteHashAndNullifier { note_hash: note_hash, inner_nullifier: inner_nullifier} + }) + } + + /// Unpacks an array into a note corresponding to `note_type_id` and then computes its note hash (non-siloed). + /// + /// The signature of this function notably matches the `aztec::messages::discovery::ComputeNoteHash` type, and so it can be used to call functions from that module such as `do_sync_state` and `attempt_note_discovery`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_hash(packed_note: BoundedVec, owner: AztecAddress, storage_slot: Field, note_type_id: Field, _contract_address: AztecAddress, randomness: Field) -> Option { + if note_type_id == ::get_id() { + let expected_len: u32 = ::N; + let actual_len: u32 = packed_note.len(); + if actual_len != expected_len { + (|args: [Field; 3]| aztec::oracle::logging::warn_log_format("[aztec-nr] Packed note length mismatch for note type id {0}: expected {1} fields, got {2}. Skipping note.", args))([note_type_id, expected_len as Field, actual_len as Field]); + Option::::none() + } else { + let note: UintNote = ::unpack(aztec::utils::array::subarray::subarray(packed_note.storage(), 0_u32)); + Option::::some(::compute_note_hash(note, owner, storage_slot, randomness)) + } + } else { + (|args: [Field; 1]| aztec::oracle::logging::warn_log_format("[aztec-nr] Unknown note type id {0}. Skipping note.", args))([note_type_id]); + Option::::none() + } + } + + /// Computes a note's inner nullifier (non-siloed) given its unique note hash, preimage and extra data. + /// + /// The signature of this function notably matches the `aztec::messages::discovery::ComputeNoteNullifier` type, and so it can be used to call functions from that module such as `do_sync_state` and `attempt_note_discovery`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_nullifier(unique_note_hash: Field, packed_note: BoundedVec, owner: AztecAddress, _storage_slot: Field, note_type_id: Field, _contract_address: AztecAddress, _randomness: Field) -> Option { + if note_type_id == ::get_id() { + let expected_len: u32 = ::N; + let actual_len: u32 = packed_note.len(); + if actual_len != expected_len { + (|args: [Field; 3]| aztec::oracle::logging::warn_log_format("[aztec-nr] Packed note length mismatch for note type id {0}: expected {1} fields, got {2}. Skipping note.", args))([note_type_id, expected_len as Field, actual_len as Field]); + Option::::none() + } else { + let note: UintNote = ::unpack(aztec::utils::array::subarray::subarray(packed_note.storage(), 0_u32)); + ::compute_nullifier_unconstrained(note, owner, unique_note_hash) + } + } else { + (|args: [Field; 1]| aztec::oracle::logging::warn_log_format("[aztec-nr] Unknown note type id {0}. Skipping note.", args))([note_type_id]); + Option::::none() + } + } + + /// Receives offchain messages into this contract's offchain inbox for subsequent processing. + /// + /// Each message is routed to the inbox scoped to its `recipient` field. + /// + /// For more details, see `aztec::messages::processing::offchain::receive`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + unconstrained fn offchain_receive(messages: BoundedVec) { + let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::processing::offchain::receive(address, messages); + } + + pub struct Token { + pub target_contract: AztecAddress, + } + + impl Token { + pub fn storage_layout() -> StorageLayoutFields { + STORAGE_LAYOUT_Token.fields + } + + pub fn at(addr: AztecAddress) -> Self { + Self { target_contract: addr} + } + + pub fn interface() -> Self { + Self { target_contract: AztecAddress::zero()} + } + + pub fn burn_public(self, from: AztecAddress, amount: u128, authwit_nonce: Field) -> aztec::context::calls::PublicCall<11, 3, ()> { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3323048133_Field); + aztec::context::calls::PublicCall::<11, 3, ()>::new(self.target_contract, selector, "burn_public", serialized_params) + } + + pub fn transfer(self, to: AztecAddress, amount: u128) -> PrivateCall<8, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1968158567_Field); + PrivateCall::<8, 2, ()>::new(self.target_contract, selector, "transfer", serialized_params) + } + + pub fn finalize_transfer_to_private_from_private(self, from: AztecAddress, partial_note: PartialUintNote, amount: u128, authwit_nonce: Field) -> PrivateCall<41, 4, ()> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4221842038_Field); + PrivateCall::<41, 4, ()>::new(self.target_contract, selector, "finalize_transfer_to_private_from_private", serialized_params) + } + + pub fn mint_to_public(self, to: AztecAddress, amount: u128) -> aztec::context::calls::PublicCall<14, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1159421870_Field); + aztec::context::calls::PublicCall::<14, 2, ()>::new(self.target_contract, selector, "mint_to_public", serialized_params) + } + + pub fn is_minter(self, minter: AztecAddress) -> aztec::context::calls::PublicStaticCall<9, 1, bool> { + let serialized_params: [Field; 1] = ::serialize(minter); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3315237398_Field); + aztec::context::calls::PublicStaticCall::<9, 1, bool>::new(self.target_contract, selector, "is_minter", serialized_params) + } + + pub fn cancel_authwit(self, inner_hash: Field) -> PrivateCall<14, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(inner_hash); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3755840242_Field); + PrivateCall::<14, 1, ()>::new(self.target_contract, selector, "cancel_authwit", serialized_params) + } + + pub fn set_admin(self, new_admin: AztecAddress) -> aztec::context::calls::PublicCall<9, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(new_admin); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2519591682_Field); + aztec::context::calls::PublicCall::<9, 1, ()>::new(self.target_contract, selector, "set_admin", serialized_params) + } + + pub fn total_supply(self) -> aztec::context::calls::PublicStaticCall<12, 0, u128> { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2379449068_Field); + aztec::context::calls::PublicStaticCall::<12, 0, u128>::new(self.target_contract, selector, "total_supply", serialized_params) + } + + pub fn private_get_decimals(self) -> aztec::context::calls::PrivateStaticCall<20, 0, u8> { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2520508119_Field); + aztec::context::calls::PrivateStaticCall::<20, 0, u8>::new(self.target_contract, selector, "private_get_decimals", serialized_params) + } + + pub fn get_admin(self) -> aztec::context::calls::PublicStaticCall<9, 0, Field> { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(722579866_Field); + aztec::context::calls::PublicStaticCall::<9, 0, Field>::new(self.target_contract, selector, "get_admin", serialized_params) + } + + pub fn transfer_to_public(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> PrivateCall<18, 4, ()> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3880081865_Field); + PrivateCall::<18, 4, ()>::new(self.target_contract, selector, "transfer_to_public", serialized_params) + } + + pub fn transfer_in_private_with_offchain_delivery(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> PrivateCall<42, 4, ()> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2994585803_Field); + PrivateCall::<42, 4, ()>::new(self.target_contract, selector, "transfer_in_private_with_offchain_delivery", serialized_params) + } + + pub fn mint_to_private(self, to: AztecAddress, amount: u128) -> PrivateCall<15, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4177019161_Field); + PrivateCall::<15, 2, ()>::new(self.target_contract, selector, "mint_to_private", serialized_params) + } + + pub fn transfer_to_private(self, to: AztecAddress, amount: u128) -> PrivateCall<19, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2306181952_Field); + PrivateCall::<19, 2, ()>::new(self.target_contract, selector, "transfer_to_private", serialized_params) + } + + pub fn public_get_name(self) -> aztec::context::calls::PublicStaticCall<15, 0, FieldCompressedString> { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3367753652_Field); + aztec::context::calls::PublicStaticCall::<15, 0, FieldCompressedString>::new(self.target_contract, selector, "public_get_name", serialized_params) + } + + pub fn _recurse_subtract_balance(self, account: AztecAddress, amount: u128) -> PrivateCall<25, 2, u128> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(account); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1536394406_Field); + PrivateCall::<25, 2, u128>::new(self.target_contract, selector, "_recurse_subtract_balance", serialized_params) + } + + pub fn _finalize_transfer_to_private_unsafe(self, from_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) -> aztec::context::calls::PublicCall<36, 3, ()> { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from_and_completer); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1930102437_Field); + aztec::context::calls::PublicCall::<36, 3, ()>::new(self.target_contract, selector, "_finalize_transfer_to_private_unsafe", serialized_params) + } + + pub fn constructor(self, admin: AztecAddress, name: str<31>, symbol: str<31>, decimals: u8) -> aztec::context::calls::PublicCall<11, 64, ()> { + let mut serialized_params: [Field; 64] = [0_Field; 64]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(admin); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(name); + let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(symbol); + let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(decimals); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1578322623_Field); + aztec::context::calls::PublicCall::<11, 64, ()>::new(self.target_contract, selector, "constructor", serialized_params) + } + + pub fn finalize_transfer_to_private(self, amount: u128, partial_note: PartialUintNote) -> aztec::context::calls::PublicCall<28, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2599745508_Field); + aztec::context::calls::PublicCall::<28, 2, ()>::new(self.target_contract, selector, "finalize_transfer_to_private", serialized_params) + } + + pub fn finalize_mint_to_private(self, amount: u128, partial_note: PartialUintNote) -> aztec::context::calls::PublicCall<24, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1065137297_Field); + aztec::context::calls::PublicCall::<24, 2, ()>::new(self.target_contract, selector, "finalize_mint_to_private", serialized_params) + } + + pub fn _reduce_total_supply(self, amount: u128) -> aztec::context::calls::PublicCall<20, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(amount); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2253390209_Field); + aztec::context::calls::PublicCall::<20, 1, ()>::new(self.target_contract, selector, "_reduce_total_supply", serialized_params) + } + + pub fn transfer_in_public(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> aztec::context::calls::PublicCall<18, 4, ()> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2359186546_Field); + aztec::context::calls::PublicCall::<18, 4, ()>::new(self.target_contract, selector, "transfer_in_public", serialized_params) + } + + pub fn prepare_private_balance_increase(self, to: AztecAddress) -> PrivateCall<32, 1, PartialUintNote> { + let serialized_params: [Field; 1] = ::serialize(to); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1824243228_Field); + PrivateCall::<32, 1, PartialUintNote>::new(self.target_contract, selector, "prepare_private_balance_increase", serialized_params) + } + + pub fn transfer_to_public_and_prepare_private_balance_increase(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> PrivateCall<55, 4, PartialUintNote> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2936463891_Field); + PrivateCall::<55, 4, PartialUintNote>::new(self.target_contract, selector, "transfer_to_public_and_prepare_private_balance_increase", serialized_params) + } + + pub fn balance_of_public(self, owner: AztecAddress) -> aztec::context::calls::PublicStaticCall<17, 1, u128> { + let serialized_params: [Field; 1] = ::serialize(owner); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4286138866_Field); + aztec::context::calls::PublicStaticCall::<17, 1, u128>::new(self.target_contract, selector, "balance_of_public", serialized_params) + } + + pub fn set_minter(self, minter: AztecAddress, approve: bool) -> aztec::context::calls::PublicCall<10, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(minter); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(approve); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1957439757_Field); + aztec::context::calls::PublicCall::<10, 2, ()>::new(self.target_contract, selector, "set_minter", serialized_params) + } + + pub fn _finalize_mint_to_private_unsafe(self, minter_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) -> aztec::context::calls::PublicCall<32, 3, ()> { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(minter_and_completer); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4058507562_Field); + aztec::context::calls::PublicCall::<32, 3, ()>::new(self.target_contract, selector, "_finalize_mint_to_private_unsafe", serialized_params) + } + + pub fn private_get_symbol(self) -> aztec::context::calls::PrivateStaticCall<18, 0, FieldCompressedString> { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1295669651_Field); + aztec::context::calls::PrivateStaticCall::<18, 0, FieldCompressedString>::new(self.target_contract, selector, "private_get_symbol", serialized_params) + } + + pub fn private_get_name(self) -> aztec::context::calls::PrivateStaticCall<16, 0, FieldCompressedString> { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3516522363_Field); + aztec::context::calls::PrivateStaticCall::<16, 0, FieldCompressedString>::new(self.target_contract, selector, "private_get_name", serialized_params) + } + + pub fn transfer_in_private(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> PrivateCall<19, 4, ()> { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3610465468_Field); + PrivateCall::<19, 4, ()>::new(self.target_contract, selector, "transfer_in_private", serialized_params) + } + + pub fn public_get_decimals(self) -> aztec::context::calls::PublicStaticCall<19, 0, u8> { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1613003496_Field); + aztec::context::calls::PublicStaticCall::<19, 0, u8>::new(self.target_contract, selector, "public_get_decimals", serialized_params) + } + + pub fn burn_private(self, from: AztecAddress, amount: u128, authwit_nonce: Field) -> PrivateCall<12, 3, ()> { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3263360377_Field); + PrivateCall::<12, 3, ()>::new(self.target_contract, selector, "burn_private", serialized_params) + } + + pub fn _increase_public_balance(self, to: AztecAddress, amount: u128) -> aztec::context::calls::PublicCall<24, 2, ()> { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3891283455_Field); + aztec::context::calls::PublicCall::<24, 2, ()>::new(self.target_contract, selector, "_increase_public_balance", serialized_params) + } + + pub fn public_get_symbol(self) -> aztec::context::calls::PublicStaticCall<17, 0, FieldCompressedString> { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3454394185_Field); + aztec::context::calls::PublicStaticCall::<17, 0, FieldCompressedString>::new(self.target_contract, selector, "public_get_symbol", serialized_params) + } + + pub fn balance_of_private(self, owner: AztecAddress) -> aztec::context::calls::UtilityCall<18, 1, u128> { + let serialized_params: [Field; 1] = ::serialize(owner); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1131770492_Field); + aztec::context::calls::UtilityCall::<18, 1, u128>::new(self.target_contract, selector, "balance_of_private", serialized_params) + } + + pub fn offchain_receive(self, messages: BoundedVec) -> aztec::context::calls::UtilityCall<16, 321, ()> { + let serialized_params: [Field; 321] = as aztec::protocol::traits::Serialize>::serialize(messages); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1396850735_Field); + aztec::context::calls::UtilityCall::<16, 321, ()>::new(self.target_contract, selector, "offchain_receive", serialized_params) + } + } + + #[contract_library_method] + pub fn storage_layout() -> StorageLayoutFields { + STORAGE_LAYOUT_Token.fields + } + + #[contract_library_method] + pub fn at(addr: AztecAddress) -> Token { + Token { target_contract: addr} + } + + #[contract_library_method] + pub fn interface() -> Token { + Token { target_contract: AztecAddress::zero()} + } + + pub struct sync_state_parameters { + pub scope: AztecAddress, + } + + #[abi(functions)] + pub struct sync_state_abi { + parameters: sync_state_parameters, + } + + unconstrained fn sync_state(scope: AztecAddress) { + let address: AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + } + + pub struct offchain_receive_parameters { + pub messages: BoundedVec, + } + + #[abi(functions)] + pub struct offchain_receive_abi { + parameters: offchain_receive_parameters, + } + + pub struct CallSelf { + pub address: AztecAddress, + pub context: Context, + } + + impl CallSelf { + pub fn burn_public(self, from: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3323048133_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<11, 3, ()>::new(self.address, selector, "burn_public", serialized_params).call(self.context) + } + } + + pub fn _finalize_transfer_to_private_unsafe(self, from_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from_and_completer); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1930102437_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<36, 3, ()>::new(self.address, selector, "_finalize_transfer_to_private_unsafe", serialized_params).call(self.context) + } + } + + pub fn constructor(self, admin: AztecAddress, name: str<31>, symbol: str<31>, decimals: u8) { + let mut serialized_params: [Field; 64] = [0_Field; 64]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(admin); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(name); + let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(symbol); + let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(decimals); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1578322623_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<11, 64, ()>::new(self.address, selector, "constructor", serialized_params).call(self.context) + } + } + + pub fn mint_to_public(self, to: AztecAddress, amount: u128) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1159421870_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<14, 2, ()>::new(self.address, selector, "mint_to_public", serialized_params).call(self.context) + } + } + + pub fn finalize_transfer_to_private(self, amount: u128, partial_note: PartialUintNote) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2599745508_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<28, 2, ()>::new(self.address, selector, "finalize_transfer_to_private", serialized_params).call(self.context) + } + } + + pub fn finalize_mint_to_private(self, amount: u128, partial_note: PartialUintNote) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1065137297_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<24, 2, ()>::new(self.address, selector, "finalize_mint_to_private", serialized_params).call(self.context) + } + } + + pub fn transfer_in_public(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2359186546_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<18, 4, ()>::new(self.address, selector, "transfer_in_public", serialized_params).call(self.context) + } + } + + pub fn _reduce_total_supply(self, amount: u128) { + let serialized_params: [Field; 1] = ::serialize(amount); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2253390209_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<20, 1, ()>::new(self.address, selector, "_reduce_total_supply", serialized_params).call(self.context) + } + } + + pub fn set_admin(self, new_admin: AztecAddress) { + let serialized_params: [Field; 1] = ::serialize(new_admin); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2519591682_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<9, 1, ()>::new(self.address, selector, "set_admin", serialized_params).call(self.context) + } + } + + pub fn set_minter(self, minter: AztecAddress, approve: bool) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(minter); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(approve); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1957439757_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<10, 2, ()>::new(self.address, selector, "set_minter", serialized_params).call(self.context) + } + } + + pub fn _finalize_mint_to_private_unsafe(self, minter_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(minter_and_completer); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4058507562_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<32, 3, ()>::new(self.address, selector, "_finalize_mint_to_private_unsafe", serialized_params).call(self.context) + } + } + + pub fn _increase_public_balance(self, to: AztecAddress, amount: u128) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3891283455_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<24, 2, ()>::new(self.address, selector, "_increase_public_balance", serialized_params).call(self.context) + } + } + } + + impl CallSelf<&mut PrivateContext> { + pub fn _recurse_subtract_balance(self, account: AztecAddress, amount: u128) -> u128 { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(account); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1536394406_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn transfer(self, to: AztecAddress, amount: u128) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1968158567_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn finalize_transfer_to_private_from_private(self, from: AztecAddress, partial_note: PartialUintNote, amount: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4221842038_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn prepare_private_balance_increase(self, to: AztecAddress) -> PartialUintNote { + let serialized_params: [Field; 1] = ::serialize(to); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1824243228_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn transfer_to_public_and_prepare_private_balance_increase(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> PartialUintNote { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2936463891_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn cancel_authwit(self, inner_hash: Field) { + let serialized_params: [Field; 1] = ::serialize(inner_hash); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3755840242_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn transfer_in_private(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3610465468_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn burn_private(self, from: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3263360377_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn transfer_to_public(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3880081865_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn transfer_in_private_with_offchain_delivery(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2994585803_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn mint_to_private(self, to: AztecAddress, amount: u128) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4177019161_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + + pub fn transfer_to_private(self, to: AztecAddress, amount: u128) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2306181952_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, false); + returns_hash.get_preimage() + } + } + + pub struct CallSelfStatic { + pub address: AztecAddress, + pub context: Context, + } + + impl CallSelfStatic { + pub fn balance_of_public(self, owner: AztecAddress) -> u128 { + let serialized_params: [Field; 1] = ::serialize(owner); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4286138866_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicStaticCall::<17, 1, u128>::new(self.address, selector, "balance_of_public", serialized_params).view(self.context) + } + } + + pub fn total_supply(self) -> u128 { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2379449068_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicStaticCall::<12, 0, u128>::new(self.address, selector, "total_supply", serialized_params).view(self.context) + } + } + + pub fn public_get_name(self) -> FieldCompressedString { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3367753652_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicStaticCall::<15, 0, FieldCompressedString>::new(self.address, selector, "public_get_name", serialized_params).view(self.context) + } + } + + pub fn public_get_decimals(self) -> u8 { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1613003496_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicStaticCall::<19, 0, u8>::new(self.address, selector, "public_get_decimals", serialized_params).view(self.context) + } + } + + pub fn get_admin(self) -> Field { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(722579866_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicStaticCall::<9, 0, Field>::new(self.address, selector, "get_admin", serialized_params).view(self.context) + } + } + + pub fn public_get_symbol(self) -> FieldCompressedString { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3454394185_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicStaticCall::<17, 0, FieldCompressedString>::new(self.address, selector, "public_get_symbol", serialized_params).view(self.context) + } + } + + pub fn is_minter(self, minter: AztecAddress) -> bool { + let serialized_params: [Field; 1] = ::serialize(minter); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3315237398_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicStaticCall::<9, 1, bool>::new(self.address, selector, "is_minter", serialized_params).view(self.context) + } + } + } + + impl CallSelfStatic<&mut PrivateContext> { + pub fn private_get_name(self) -> FieldCompressedString { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3516522363_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, true); + returns_hash.get_preimage() + } + + pub fn private_get_symbol(self) -> FieldCompressedString { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1295669651_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, true); + returns_hash.get_preimage() + } + + pub fn private_get_decimals(self) -> u8 { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2520508119_Field); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + aztec::oracle::execution_cache::store(serialized_params, args_hash); + let returns_hash: aztec::context::ReturnsHash = self.context.call_private_function_with_args_hash(self.address, selector, args_hash, true); + returns_hash.get_preimage() + } + } + + pub struct EnqueueSelf { + pub address: AztecAddress, + pub context: Context, + } + + impl EnqueueSelf<&mut PrivateContext> { + pub fn set_minter(self, minter: AztecAddress, approve: bool) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(minter); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(approve); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1957439757_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn burn_public(self, from: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3323048133_Field); + let calldata: [Field; 1 + 3] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn _finalize_transfer_to_private_unsafe(self, from_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from_and_completer); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1930102437_Field); + let calldata: [Field; 1 + 3] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn _finalize_mint_to_private_unsafe(self, minter_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(minter_and_completer); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4058507562_Field); + let calldata: [Field; 1 + 3] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn mint_to_public(self, to: AztecAddress, amount: u128) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1159421870_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn finalize_transfer_to_private(self, amount: u128, partial_note: PartialUintNote) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2599745508_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn constructor(self, admin: AztecAddress, name: str<31>, symbol: str<31>, decimals: u8) { + let mut serialized_params: [Field; 64] = [0_Field; 64]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(admin); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(name); + let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 31] = as aztec::protocol::traits::Serialize>::serialize(symbol); + let serialized_member_len: u32 = as aztec::protocol::traits::Serialize>::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(decimals); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1578322623_Field); + let calldata: [Field; 1 + 64] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn finalize_mint_to_private(self, amount: u128, partial_note: PartialUintNote) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1065137297_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn _increase_public_balance(self, to: AztecAddress, amount: u128) { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3891283455_Field); + let calldata: [Field; 1 + 2] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn transfer_in_public(self, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2359186546_Field); + let calldata: [Field; 1 + 4] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn _reduce_total_supply(self, amount: u128) { + let serialized_params: [Field; 1] = ::serialize(amount); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2253390209_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn set_admin(self, new_admin: AztecAddress) { + let serialized_params: [Field; 1] = ::serialize(new_admin); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2519591682_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + } + + pub struct EnqueueSelfStatic { + pub address: AztecAddress, + pub context: Context, + } + + impl EnqueueSelfStatic<&mut PrivateContext> { + pub fn public_get_name(self) { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3367753652_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, true, false); + } + + pub fn public_get_decimals(self) { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1613003496_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, true, false); + } + + pub fn get_admin(self) { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(722579866_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, true, false); + } + + pub fn balance_of_public(self, owner: AztecAddress) { + let serialized_params: [Field; 1] = ::serialize(owner); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4286138866_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, true, false); + } + + pub fn total_supply(self) { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2379449068_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, true, false); + } + + pub fn public_get_symbol(self) { + let serialized_params: [Field; 0] = []; + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3454394185_Field); + let calldata: [Field; 1 + 0] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, true, false); + } + + pub fn is_minter(self, minter: AztecAddress) { + let serialized_params: [Field; 1] = ::serialize(minter); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3315237398_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, true, false); + } + } + + pub struct CallSelfUtility { + pub address: AztecAddress, + } + + impl CallSelfUtility { + pub unconstrained fn balance_of_private(self, owner: AztecAddress) -> u128 { + let serialized_params: [Field; 1] = ::serialize(owner); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1131770492_Field); + let returns: [Field; 1] = aztec::oracle::call_utility_function::call_utility_function(self.address, selector, serialized_params); + ::deserialize(returns) + } + } + + pub struct CallInternal { + pub context: Context, + } + + impl CallInternal { + pub unconstrained fn _finalize_mint_to_private(self, completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + __aztec_nr_internals___finalize_mint_to_private(self.context, completer, amount, partial_note) + } + + pub unconstrained fn _finalize_transfer_to_private(self, from_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + __aztec_nr_internals___finalize_transfer_to_private(self.context, from_and_completer, amount, partial_note) + } + } + + impl CallInternal<&mut PrivateContext> { + pub fn subtract_balance(self, account: AztecAddress, amount: u128, max_notes: u32) -> u128 { + __aztec_nr_internals__subtract_balance(self.context, account, amount, max_notes) + } + + pub fn _prepare_private_balance_increase(self, to: AztecAddress) -> PartialUintNote { + __aztec_nr_internals___prepare_private_balance_increase(self.context, to) + } + } + + pub unconstrained fn public_dispatch(selector: Field) { + if selector == 1578322623_Field { + let input_calldata: [Field; 64] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + as aztec::protocol::traits::Serialize>::N) + as aztec::protocol::traits::Serialize>::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<64> = aztec::protocol::utils::reader::Reader::<64>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: str<31> = as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let arg2: str<31> = as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); + let arg3: u8 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__constructor(arg0, arg1, arg2, arg3); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2519591682_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + __aztec_nr_internals__set_admin(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3367753652_Field { + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__public_get_name()); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3454394185_Field { + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__public_get_symbol()); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1613003496_Field { + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__public_get_decimals()); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 722579866_Field { + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__get_admin()); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 3315237398_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__is_minter(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 2379449068_Field { + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__total_supply()); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 4286138866_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let return_value: [Field; 1] = ::serialize(__aztec_nr_internals__balance_of_public(arg0)); + aztec::oracle::avm::avm_return(return_value.as_vector()); + }; + if selector == 1957439757_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: bool = ::stream_deserialize(&mut reader); + __aztec_nr_internals__set_minter(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1159421870_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: u128 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__mint_to_public(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2359186546_Field { + let input_calldata: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + ::N) + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<4> = aztec::protocol::utils::reader::Reader::<4>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: AztecAddress = ::stream_deserialize(&mut reader); + let arg2: u128 = ::stream_deserialize(&mut reader); + let arg3: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__transfer_in_public(arg0, arg1, arg2, arg3); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3323048133_Field { + let input_calldata: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (::N + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<3> = aztec::protocol::utils::reader::Reader::<3>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: u128 = ::stream_deserialize(&mut reader); + let arg2: Field = ::stream_deserialize(&mut reader); + __aztec_nr_internals__burn_public(arg0, arg1, arg2); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2599745508_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: u128 = ::stream_deserialize(&mut reader); + let arg1: PartialUintNote = ::stream_deserialize(&mut reader); + __aztec_nr_internals__finalize_transfer_to_private(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1930102437_Field { + let input_calldata: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (::N + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<3> = aztec::protocol::utils::reader::Reader::<3>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: u128 = ::stream_deserialize(&mut reader); + let arg2: PartialUintNote = ::stream_deserialize(&mut reader); + __aztec_nr_internals___finalize_transfer_to_private_unsafe(arg0, arg1, arg2); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1065137297_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: u128 = ::stream_deserialize(&mut reader); + let arg1: PartialUintNote = ::stream_deserialize(&mut reader); + __aztec_nr_internals__finalize_mint_to_private(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 4058507562_Field { + let input_calldata: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (::N + ::N) + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<3> = aztec::protocol::utils::reader::Reader::<3>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: u128 = ::stream_deserialize(&mut reader); + let arg2: PartialUintNote = ::stream_deserialize(&mut reader); + __aztec_nr_internals___finalize_mint_to_private_unsafe(arg0, arg1, arg2); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3891283455_Field { + let input_calldata: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + let mut reader: aztec::protocol::utils::reader::Reader<2> = aztec::protocol::utils::reader::Reader::<2>::new(input_calldata); + let arg0: AztecAddress = ::stream_deserialize(&mut reader); + let arg1: u128 = ::stream_deserialize(&mut reader); + __aztec_nr_internals___increase_public_balance(arg0, arg1); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2253390209_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u128 = ::stream_deserialize(&mut reader); + __aztec_nr_internals___reduce_total_supply(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + panic(f"Unknown selector {selector}") + } + + pub struct _finalize_mint_to_private_unsafe_parameters { + pub minter_and_completer: AztecAddress, + pub amount: u128, + pub partial_note: PartialUintNote, + } + + pub struct _finalize_transfer_to_private_unsafe_parameters { + pub from_and_completer: AztecAddress, + pub amount: u128, + pub partial_note: PartialUintNote, + } + + pub struct _increase_public_balance_parameters { + pub to: AztecAddress, + pub amount: u128, + } + + pub struct _recurse_subtract_balance_parameters { + pub account: AztecAddress, + pub amount: u128, + } + + pub struct _reduce_total_supply_parameters { + pub amount: u128, + } + + pub struct balance_of_private_parameters { + pub owner: AztecAddress, + } + + pub struct balance_of_public_parameters { + pub owner: AztecAddress, + } + + pub struct burn_private_parameters { + pub from: AztecAddress, + pub amount: u128, + pub authwit_nonce: Field, + } + + pub struct burn_public_parameters { + pub from: AztecAddress, + pub amount: u128, + pub authwit_nonce: Field, + } + + pub struct cancel_authwit_parameters { + pub inner_hash: Field, + } + + pub struct constructor_parameters { + pub admin: AztecAddress, + pub name: str<31>, + pub symbol: str<31>, + pub decimals: u8, + } + + pub struct finalize_mint_to_private_parameters { + pub amount: u128, + pub partial_note: PartialUintNote, + } + + pub struct finalize_transfer_to_private_from_private_parameters { + pub from: AztecAddress, + pub partial_note: PartialUintNote, + pub amount: u128, + pub authwit_nonce: Field, + } + + pub struct finalize_transfer_to_private_parameters { + pub amount: u128, + pub partial_note: PartialUintNote, + } + + pub struct get_admin_parameters { + } + + pub struct is_minter_parameters { + pub minter: AztecAddress, + } + + pub struct mint_to_private_parameters { + pub to: AztecAddress, + pub amount: u128, + } + + pub struct mint_to_public_parameters { + pub to: AztecAddress, + pub amount: u128, + } + + pub struct prepare_private_balance_increase_parameters { + pub to: AztecAddress, + } + + pub struct private_get_decimals_parameters { + } + + pub struct private_get_name_parameters { + } + + pub struct private_get_symbol_parameters { + } + + pub struct public_get_decimals_parameters { + } + + pub struct public_get_name_parameters { + } + + pub struct public_get_symbol_parameters { + } + + pub struct set_admin_parameters { + pub new_admin: AztecAddress, + } + + pub struct set_minter_parameters { + pub minter: AztecAddress, + pub approve: bool, + } + + pub struct total_supply_parameters { + } + + pub struct transfer_in_private_parameters { + pub from: AztecAddress, + pub to: AztecAddress, + pub amount: u128, + pub authwit_nonce: Field, + } + + pub struct transfer_in_private_with_offchain_delivery_parameters { + pub from: AztecAddress, + pub to: AztecAddress, + pub amount: u128, + pub authwit_nonce: Field, + } + + pub struct transfer_in_public_parameters { + pub from: AztecAddress, + pub to: AztecAddress, + pub amount: u128, + pub authwit_nonce: Field, + } + + pub struct transfer_parameters { + pub to: AztecAddress, + pub amount: u128, + } + + pub struct transfer_to_private_parameters { + pub to: AztecAddress, + pub amount: u128, + } + + pub struct transfer_to_public_and_prepare_private_balance_increase_parameters { + pub from: AztecAddress, + pub to: AztecAddress, + pub amount: u128, + pub authwit_nonce: Field, + } + + pub struct transfer_to_public_parameters { + pub from: AztecAddress, + pub to: AztecAddress, + pub amount: u128, + pub authwit_nonce: Field, + } + + #[abi(functions)] + pub struct _finalize_mint_to_private_unsafe_abi { + parameters: _finalize_mint_to_private_unsafe_parameters, + } + + #[abi(functions)] + pub struct _finalize_transfer_to_private_unsafe_abi { + parameters: _finalize_transfer_to_private_unsafe_parameters, + } + + #[abi(functions)] + pub struct _increase_public_balance_abi { + parameters: _increase_public_balance_parameters, + } + + #[abi(functions)] + pub struct _recurse_subtract_balance_abi { + parameters: _recurse_subtract_balance_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct _reduce_total_supply_abi { + parameters: _reduce_total_supply_parameters, + } + + #[abi(functions)] + pub struct balance_of_private_abi { + parameters: balance_of_private_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct balance_of_public_abi { + parameters: balance_of_public_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct burn_private_abi { + parameters: burn_private_parameters, + } + + #[abi(functions)] + pub struct burn_public_abi { + parameters: burn_public_parameters, + } + + #[abi(functions)] + pub struct cancel_authwit_abi { + parameters: cancel_authwit_parameters, + } + + #[abi(functions)] + pub struct constructor_abi { + parameters: constructor_parameters, + } + + #[abi(functions)] + pub struct finalize_mint_to_private_abi { + parameters: finalize_mint_to_private_parameters, + } + + #[abi(functions)] + pub struct finalize_transfer_to_private_abi { + parameters: finalize_transfer_to_private_parameters, + } + + #[abi(functions)] + pub struct finalize_transfer_to_private_from_private_abi { + parameters: finalize_transfer_to_private_from_private_parameters, + } + + #[abi(functions)] + pub struct get_admin_abi { + parameters: get_admin_parameters, + return_type: Field, + } + + #[abi(functions)] + pub struct is_minter_abi { + parameters: is_minter_parameters, + return_type: bool, + } + + #[abi(functions)] + pub struct mint_to_private_abi { + parameters: mint_to_private_parameters, + } + + #[abi(functions)] + pub struct mint_to_public_abi { + parameters: mint_to_public_parameters, + } + + #[abi(functions)] + pub struct prepare_private_balance_increase_abi { + parameters: prepare_private_balance_increase_parameters, + return_type: PartialUintNote, + } + + #[abi(functions)] + pub struct private_get_decimals_abi { + parameters: private_get_decimals_parameters, + return_type: u8, + } + + #[abi(functions)] + pub struct private_get_name_abi { + parameters: private_get_name_parameters, + return_type: FieldCompressedString, + } + + #[abi(functions)] + pub struct private_get_symbol_abi { + parameters: private_get_symbol_parameters, + return_type: FieldCompressedString, + } + + #[abi(functions)] + pub struct public_get_decimals_abi { + parameters: public_get_decimals_parameters, + return_type: u8, + } + + #[abi(functions)] + pub struct public_get_name_abi { + parameters: public_get_name_parameters, + return_type: FieldCompressedString, + } + + #[abi(functions)] + pub struct public_get_symbol_abi { + parameters: public_get_symbol_parameters, + return_type: FieldCompressedString, + } + + #[abi(functions)] + pub struct set_admin_abi { + parameters: set_admin_parameters, + } + + #[abi(functions)] + pub struct set_minter_abi { + parameters: set_minter_parameters, + } + + #[abi(functions)] + pub struct total_supply_abi { + parameters: total_supply_parameters, + return_type: u128, + } + + #[abi(functions)] + pub struct transfer_abi { + parameters: transfer_parameters, + } + + #[abi(functions)] + pub struct transfer_in_private_abi { + parameters: transfer_in_private_parameters, + } + + #[abi(functions)] + pub struct transfer_in_private_with_offchain_delivery_abi { + parameters: transfer_in_private_with_offchain_delivery_parameters, + } + + #[abi(functions)] + pub struct transfer_in_public_abi { + parameters: transfer_in_public_parameters, + } + + #[abi(functions)] + pub struct transfer_to_private_abi { + parameters: transfer_to_private_parameters, + } + + #[abi(functions)] + pub struct transfer_to_public_abi { + parameters: transfer_to_public_parameters, + } + + #[abi(functions)] + pub struct transfer_to_public_and_prepare_private_balance_increase_abi { + parameters: transfer_to_public_and_prepare_private_balance_increase_parameters, + return_type: PartialUintNote, + } + + fn __aztec_nr_internals___recurse_subtract_balance(inputs: aztec::context::inputs::PrivateContextInputs, account: AztecAddress, amount: u128) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(account); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + assert(self.msg_sender() == self.address, "Function _recurse_subtract_balance can only be called by the same contract"); + let macro__returned__values: u128 = self.internal.subtract_balance(account, amount, RECURSIVE_TRANSFER_CALL_MAX_NOTES); + let serialized_params: [Field; 1] = ::serialize(macro__returned__values); + self.context.set_return_hash(serialized_params); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__burn_private(inputs: aztec::context::inputs::PrivateContextInputs, from: AztecAddress, amount: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 3] = [0_Field; 3]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + if !from.eq(self.msg_sender()) { + aztec::authwit::auth::assert_current_call_valid_authwit::<3>(self.context, from); + } else { + assert(authwit_nonce == 0_Field, "Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero"); + }; + self.storage.balances.at(from).sub(amount).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); + self.enqueue_self._reduce_total_supply(amount); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__cancel_authwit(inputs: aztec::context::inputs::PrivateContextInputs, inner_hash: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let serialized_params: [Field; 1] = ::serialize(inner_hash); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + let on_behalf_of: AztecAddress = self.msg_sender(); + let nullifier: Field = compute_authwit_nullifier(on_behalf_of, inner_hash); + self.context.push_nullifier(nullifier); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__finalize_transfer_to_private_from_private(inputs: aztec::context::inputs::PrivateContextInputs, from: AztecAddress, partial_note: PartialUintNote, amount: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(partial_note); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + if !from.eq(self.msg_sender()) { + aztec::authwit::auth::assert_current_call_valid_authwit::<4>(self.context, from); + } else { + assert(authwit_nonce == 0_Field, "Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero"); + }; + self.storage.balances.at(from).sub(amount).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); + partial_note.complete_from_private(self.context, self.msg_sender(), self.storage.balances.get_storage_slot(), amount); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__mint_to_private(inputs: aztec::context::inputs::PrivateContextInputs, to: AztecAddress, amount: u128) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + let partial_note: PartialUintNote = self.internal._prepare_private_balance_increase(to); + self.enqueue_self._finalize_mint_to_private_unsafe(self.msg_sender(), amount, partial_note); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__prepare_private_balance_increase(inputs: aztec::context::inputs::PrivateContextInputs, to: AztecAddress) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let serialized_params: [Field; 1] = ::serialize(to); + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + let macro__returned__values: PartialUintNote = self.internal._prepare_private_balance_increase(to); + let serialized_params: [Field; 1] = ::serialize(macro__returned__values); + self.context.set_return_hash(serialized_params); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__private_get_decimals(inputs: aztec::context::inputs::PrivateContextInputs) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let serialized_params: [Field; 0] = []; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + assert(self.context.inputs.call_context.is_static_call, "Function private_get_decimals can only be called statically"); + let macro__returned__values: u8 = self.storage.decimals.read(); + let serialized_params: [Field; 1] = ::serialize(macro__returned__values); + self.context.set_return_hash(serialized_params); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__private_get_name(inputs: aztec::context::inputs::PrivateContextInputs) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let serialized_params: [Field; 0] = []; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + assert(self.context.inputs.call_context.is_static_call, "Function private_get_name can only be called statically"); + let macro__returned__values: FieldCompressedString = self.storage.name.read(); + let serialized_params: [Field; 1] = ::serialize(macro__returned__values); + self.context.set_return_hash(serialized_params); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__private_get_symbol(inputs: aztec::context::inputs::PrivateContextInputs) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let serialized_params: [Field; 0] = []; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + assert(self.context.inputs.call_context.is_static_call, "Function private_get_symbol can only be called statically"); + let macro__returned__values: FieldCompressedString = self.storage.symbol.read(); + let serialized_params: [Field; 1] = ::serialize(macro__returned__values); + self.context.set_return_hash(serialized_params); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__transfer(inputs: aztec::context::inputs::PrivateContextInputs, to: AztecAddress, amount: u128) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + let from: AztecAddress = self.msg_sender(); + let change: u128 = self.internal.subtract_balance(from, amount, INITIAL_TRANSFER_CALL_MAX_NOTES); + self.storage.balances.at(from).add(change).deliver(MessageDelivery.ONCHAIN_UNCONSTRAINED); + self.storage.balances.at(to).add(amount).deliver(MessageDelivery.ONCHAIN_UNCONSTRAINED); + self.emit(Transfer { from: from, to: to, amount: amount}).deliver_to(to, MessageDelivery.ONCHAIN_UNCONSTRAINED); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__transfer_in_private(inputs: aztec::context::inputs::PrivateContextInputs, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + if !from.eq(self.msg_sender()) { + aztec::authwit::auth::assert_current_call_valid_authwit::<4>(self.context, from); + } else { + assert(authwit_nonce == 0_Field, "Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero"); + }; + self.storage.balances.at(from).sub(amount).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); + self.storage.balances.at(to).add(amount).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__transfer_in_private_with_offchain_delivery(inputs: aztec::context::inputs::PrivateContextInputs, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + if !from.eq(self.msg_sender()) { + aztec::authwit::auth::assert_current_call_valid_authwit::<4>(self.context, from); + } else { + assert(authwit_nonce == 0_Field, "Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero"); + }; + self.storage.balances.at(from).sub(amount).deliver(MessageDelivery.OFFCHAIN); + self.storage.balances.at(to).add(amount).deliver(MessageDelivery.OFFCHAIN); + self.emit(Transfer { from: from, to: to, amount: amount}).deliver_to(to, MessageDelivery.OFFCHAIN); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__transfer_to_private(inputs: aztec::context::inputs::PrivateContextInputs, to: AztecAddress, amount: u128) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 2] = [0_Field; 2]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + let from: AztecAddress = self.msg_sender(); + let partial_note: PartialUintNote = self.internal._prepare_private_balance_increase(to); + self.enqueue_self._finalize_transfer_to_private_unsafe(from, amount, partial_note); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__transfer_to_public(inputs: aztec::context::inputs::PrivateContextInputs, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + if !from.eq(self.msg_sender()) { + aztec::authwit::auth::assert_current_call_valid_authwit::<4>(self.context, from); + } else { + assert(authwit_nonce == 0_Field, "Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero"); + }; + self.storage.balances.at(from).sub(amount).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); + self.enqueue_self._increase_public_balance(to, amount); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + fn __aztec_nr_internals__transfer_to_public_and_prepare_private_balance_increase(inputs: aztec::context::inputs::PrivateContextInputs, from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let mut serialized_params: [Field; 4] = [0_Field; 4]; + let mut offset: u32 = 0_u32; + let serialized_member: [Field; 1] = ::serialize(from); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_0: u32 = i + offset; + serialized_params[i_0] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(to); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_1: u32 = i + offset; + serialized_params[i_1] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(amount); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_2: u32 = i + offset; + serialized_params[i_2] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let serialized_member: [Field; 1] = ::serialize(authwit_nonce); + let serialized_member_len: u32 = ::N; + for i in 0_u32..serialized_member_len { + { + let i_3: u32 = i + offset; + serialized_params[i_3] = serialized_member[i]; + } + }; + offset = offset + serialized_member_len; + let args_hash: Field = aztec::hash::hash_args(serialized_params); + let mut context: PrivateContext = PrivateContext::new(inputs, args_hash); + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(&mut context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: &mut context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: &mut context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: &mut context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(&mut context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + let within_revertible_phase: bool = self.context.in_revertible_phase(); + aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); + if !from.eq(self.msg_sender()) { + aztec::authwit::auth::assert_current_call_valid_authwit::<4>(self.context, from); + } else { + assert(authwit_nonce == 0_Field, "Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero"); + }; + self.storage.balances.at(from).sub(amount).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); + self.enqueue_self._increase_public_balance(to, amount); + let macro__returned__values: PartialUintNote = self.internal._prepare_private_balance_increase(from); + let serialized_params: [Field; 1] = ::serialize(macro__returned__values); + self.context.set_return_hash(serialized_params); + assert(within_revertible_phase == self.context.in_revertible_phase(), f"Phase change detected on function with phase check. If this is expected, use #[allow_phase_change]"); + self.context.finish() + } + + unconstrained fn __aztec_nr_internals___finalize_mint_to_private_unsafe(minter_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (::N + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.msg_sender() == self.address, "Function _finalize_mint_to_private_unsafe can only be called by the same contract"); + { + assert(self.storage.minters.at(minter_and_completer).read(), "caller is not minter"); + self.internal._finalize_mint_to_private(minter_and_completer, amount, partial_note); + } + } + + unconstrained fn __aztec_nr_internals___finalize_transfer_to_private_unsafe(from_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (::N + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.msg_sender() == self.address, "Function _finalize_transfer_to_private_unsafe can only be called by the same contract"); + { + self.internal._finalize_transfer_to_private(from_and_completer, amount, partial_note); + } + } + + unconstrained fn __aztec_nr_internals___increase_public_balance(to: AztecAddress, amount: u128) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.msg_sender() == self.address, "Function _increase_public_balance can only be called by the same contract"); + { + let to_balance: PublicMutable = self.storage.public_balances.at(to); + let new_balance: u128 = to_balance.read().add(amount); + to_balance.write(new_balance); + } + } + + unconstrained fn __aztec_nr_internals___reduce_total_supply(amount: u128) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + assert(self.msg_sender() == self.address, "Function _reduce_total_supply can only be called by the same contract"); + { + let new_supply: u128 = self.storage.total_supply.read().sub(amount); + self.storage.total_supply.write(new_supply); + } + } + + unconstrained fn __aztec_nr_internals__balance_of_public(owner: AztecAddress) -> pub u128 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + assert(self.context.is_static_call(), "Function balance_of_public can only be called statically"); + { + self.storage.public_balances.at(owner).read() + } + } + + unconstrained fn __aztec_nr_internals__burn_public(from: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 3] = aztec::oracle::avm::calldata_copy(1_u32, (::N + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + if !from.eq(self.msg_sender()) { + aztec::authwit::auth::assert_current_call_valid_authwit_public(self.context, from); + } else { + assert(authwit_nonce == 0_Field, "Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero"); + }; + { + let from_balance: u128 = self.storage.public_balances.at(from).read().sub(amount); + self.storage.public_balances.at(from).write(from_balance); + let new_supply: u128 = self.storage.total_supply.read().sub(amount); + self.storage.total_supply.write(new_supply); + } + } + + unconstrained fn __aztec_nr_internals__constructor(admin: AztecAddress, name: str<31>, symbol: str<31>, decimals: u8) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 64] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + as aztec::protocol::traits::Serialize>::N) + as aztec::protocol::traits::Serialize>::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_initialization_matches_address_preimage_public(self.context); + { + assert(!admin.is_zero(), "invalid admin"); + self.storage.admin.write(admin); + self.storage.minters.at(admin).write(true); + self.storage.name.initialize(FieldCompressedString::from_string(name)); + self.storage.symbol.initialize(FieldCompressedString::from_string(symbol)); + self.storage.decimals.initialize(decimals); + }; + aztec::macros::functions::initialization_utils::mark_as_initialized_from_public_initializer(self.context); + } + + unconstrained fn __aztec_nr_internals__finalize_mint_to_private(amount: u128, partial_note: PartialUintNote) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + { + let minter_and_completer: AztecAddress = self.msg_sender(); + assert(self.storage.minters.at(minter_and_completer).read(), "caller is not minter"); + self.internal._finalize_mint_to_private(minter_and_completer, amount, partial_note); + } + } + + unconstrained fn __aztec_nr_internals__finalize_transfer_to_private(amount: u128, partial_note: PartialUintNote) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + { + let from_and_completer: AztecAddress = self.msg_sender(); + self.internal._finalize_transfer_to_private(from_and_completer, amount, partial_note); + } + } + + unconstrained fn __aztec_nr_internals__get_admin() -> pub Field { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + assert(self.context.is_static_call(), "Function get_admin can only be called statically"); + { + self.storage.admin.read().to_field() + } + } + + unconstrained fn __aztec_nr_internals__is_minter(minter: AztecAddress) -> pub bool { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + assert(self.context.is_static_call(), "Function is_minter can only be called statically"); + { + self.storage.minters.at(minter).read() + } + } + + unconstrained fn __aztec_nr_internals__mint_to_public(to: AztecAddress, amount: u128) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + { + assert(self.storage.minters.at(self.msg_sender()).read(), "caller is not minter"); + let new_balance: u128 = self.storage.public_balances.at(to).read().add(amount); + let supply: u128 = self.storage.total_supply.read().add(amount); + self.storage.public_balances.at(to).write(new_balance); + self.storage.total_supply.write(supply); + } + } + + unconstrained fn __aztec_nr_internals__public_get_decimals() -> pub u8 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + assert(self.context.is_static_call(), "Function public_get_decimals can only be called statically"); + { + self.storage.decimals.read() + } + } + + unconstrained fn __aztec_nr_internals__public_get_name() -> pub FieldCompressedString { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + assert(self.context.is_static_call(), "Function public_get_name can only be called statically"); + { + self.storage.name.read() + } + } + + unconstrained fn __aztec_nr_internals__public_get_symbol() -> pub FieldCompressedString { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + assert(self.context.is_static_call(), "Function public_get_symbol can only be called statically"); + { + self.storage.symbol.read() + } + } + + unconstrained fn __aztec_nr_internals__set_admin(new_admin: AztecAddress) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + { + assert(self.storage.admin.read().eq(self.msg_sender()), "caller is not admin"); + self.storage.admin.write(new_admin); + } + } + + unconstrained fn __aztec_nr_internals__set_minter(minter: AztecAddress, approve: bool) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 2] = aztec::oracle::avm::calldata_copy(1_u32, ::N + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + { + assert(self.storage.admin.read().eq(self.msg_sender()), "caller is not admin"); + self.storage.minters.at(minter).write(approve); + } + } + + unconstrained fn __aztec_nr_internals__total_supply() -> pub u128 { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 0] = aztec::oracle::avm::calldata_copy(1_u32, 0_u32); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + assert(self.context.is_static_call(), "Function total_supply can only be called statically"); + { + self.storage.total_supply.read() + } + } + + unconstrained fn __aztec_nr_internals__transfer_in_public(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 4] = aztec::oracle::avm::calldata_copy(1_u32, ((::N + ::N) + ::N) + ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); + if !from.eq(self.msg_sender()) { + aztec::authwit::auth::assert_current_call_valid_authwit_public(self.context, from); + } else { + assert(authwit_nonce == 0_Field, "Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero"); + }; + { + let from_balance: u128 = self.storage.public_balances.at(from).read().sub(amount); + self.storage.public_balances.at(from).write(from_balance); + let to_balance: u128 = self.storage.public_balances.at(to).read().add(amount); + self.storage.public_balances.at(to).write(to_balance); + } + } + + unconstrained fn __aztec_nr_internals__balance_of_private(owner: AztecAddress) -> pub u128 { + aztec::oracle::version::assert_compatible_oracle_version(); + let mut self: aztec::contract_self::contract_self_utility::ContractSelfUtility, CallSelfUtility> = { + let context: aztec::context::UtilityContext = aztec::context::UtilityContext::new(); + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelfUtility = CallSelfUtility { address: self_address}; + aztec::contract_self::contract_self_utility::ContractSelfUtility::, CallSelfUtility>::new(context, storage, call_self) + }; + aztec::macros::functions::initialization_utils::assert_is_initialized_utility(self.context); + { + self.storage.balances.at(owner).balance_of() + } + } + + #[contract_library_method] + fn __aztec_nr_internals___prepare_private_balance_increase(context: &mut PrivateContext, to: AztecAddress) -> PartialUintNote { + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + { + let partial_note: PartialUintNote = UintNote::partial(to, self.context, to, self.msg_sender()); + partial_note + } + } + + #[contract_library_method] + fn __aztec_nr_internals__subtract_balance(context: &mut PrivateContext, account: AztecAddress, amount: u128, max_notes: u32) -> u128 { + let mut self: aztec::contract_self::contract_self_private::ContractSelfPrivate, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility> = { + let storage: Storage<&mut PrivateContext> = Storage::<&mut PrivateContext>::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf<&mut PrivateContext> = CallSelf::<&mut PrivateContext> { address: self_address, context: context}; + let enqueue_self: EnqueueSelf<&mut PrivateContext> = EnqueueSelf::<&mut PrivateContext> { address: self_address, context: context}; + let call_self_static: CallSelfStatic<&mut PrivateContext> = CallSelfStatic::<&mut PrivateContext> { address: self_address, context: context}; + let enqueue_self_static: EnqueueSelfStatic<&mut PrivateContext> = EnqueueSelfStatic::<&mut PrivateContext> { address: self_address, context: context}; + let internal: CallInternal<&mut PrivateContext> = CallInternal::<&mut PrivateContext> { context: context}; + let call_self_utility: CallSelfUtility = CallSelfUtility { address: self_address}; + let utility: aztec::contract_self::contract_self_private::PrivateUtilityCalls = aztec::contract_self::contract_self_private::PrivateUtilityCalls:: { call_self: call_self_utility}; + aztec::contract_self::contract_self_private::ContractSelfPrivate::, CallSelf<&mut PrivateContext>, EnqueueSelf<&mut PrivateContext>, CallSelfStatic<&mut PrivateContext>, EnqueueSelfStatic<&mut PrivateContext>, CallInternal<&mut PrivateContext>, CallSelfUtility>::new(context, storage, call_self, enqueue_self, call_self_static, enqueue_self_static, internal, utility) + }; + { + let subtracted: u128 = self.storage.balances.at(account).try_sub(amount, max_notes); + assert(subtracted > (0_Field as u128), "Balance too low"); + if subtracted >= amount { + subtracted - amount + } else { + let remaining: u128 = amount - subtracted; + compute_recurse_subtract_balance_call(*context, account, remaining).call(context) + } + } + } + + #[contract_library_method] + unconstrained fn __aztec_nr_internals___finalize_mint_to_private(context: aztec::context::PublicContext, completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let supply: u128 = self.storage.total_supply.read().add(amount); + self.storage.total_supply.write(supply); + partial_note.complete(self.context, completer, self.storage.balances.get_storage_slot(), amount); + } + } + + #[contract_library_method] + unconstrained fn __aztec_nr_internals___finalize_transfer_to_private(context: aztec::context::PublicContext, from_and_completer: AztecAddress, amount: u128, partial_note: PartialUintNote) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let storage: Storage = Storage::::init(context); + let self_address: AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let balance_storage: PublicMutable = self.storage.public_balances.at(from_and_completer); + let from_balance: u128 = balance_storage.read().sub(amount); + balance_storage.write(from_balance); + partial_note.complete(self.context, from_and_completer, self.storage.balances.get_storage_slot(), amount); + } + } + + pub struct StorageLayoutFields { + pub admin: aztec::state_vars::Storable, + pub minters: aztec::state_vars::Storable, + pub balances: aztec::state_vars::Storable, + pub total_supply: aztec::state_vars::Storable, + pub public_balances: aztec::state_vars::Storable, + pub symbol: aztec::state_vars::Storable, + pub name: aztec::state_vars::Storable, + pub decimals: aztec::state_vars::Storable, + } + + pub struct StorageLayout { + pub contract_name: str, + pub fields: StorageLayoutFields, + } +} + +mod test { + pub mod access_control { + use super::utils; + use crate::Token; + use aztec::protocol::traits::ToField; + + #[test] + unconstrained fn access_control() { + let (env, token_contract_address, owner, new_admin): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress) = utils::setup(false); + let token: Token::Token = Token::at(token_contract_address); + env.call_public(owner, token.set_admin(new_admin)); + assert(env.view_public(token.get_admin()) == new_admin.to_field()); + assert(!env.view_public(token.is_minter(new_admin))); + env.call_public(new_admin, token.set_minter(new_admin, true)); + assert(env.view_public(token.is_minter(new_admin))); + env.call_public(new_admin, token.set_minter(new_admin, false)); + assert(!env.view_public(token.is_minter(new_admin))); + } + + #[test(should_fail_with = "caller is not admin")] + unconstrained fn set_admin_requires_admin_caller() { + let (env, token_contract_address, _, other): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress) = utils::setup(false); + let token: Token::Token = Token::at(token_contract_address); + env.call_public(other, token.set_admin(other)); + } + + #[test(should_fail_with = "caller is not admin")] + unconstrained fn set_minter_requires_admin_caller() { + let (env, token_contract_address, _, other): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress) = utils::setup(false); + let token: Token::Token = Token::at(token_contract_address); + env.call_public(other, token.set_minter(other, true)); + } + } + + pub mod burn_private { + use super::utils; + use crate::Token; + use aztec::test::helpers::authwit::add_private_authwit_from_call; + use generic_proxy_contract::GenericProxy; + + global AUTHWIT_NONCE: Field = 0x07; + + #[test] + unconstrained fn burn_private_on_behalf_of_self() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let burn_amount: u128 = mint_amount / (10_Field as u128); + env.call_private(owner, Token::at(token_contract_address).burn_private(owner, burn_amount, 0_Field)); + utils::check_private_balance(env, token_contract_address, owner, mint_amount - burn_amount); + } + + #[test] + unconstrained fn burn_private_on_behalf_of_other() { + let (env, token_contract_address, owner, _, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let burn_amount: u128 = mint_amount / (10_Field as u128); + let burn_call: aztec::context::calls::PrivateCall<12, 3, ()> = Token::at(token_contract_address).burn_private(owner, burn_amount, AUTHWIT_NONCE); + add_private_authwit_from_call(env, owner, proxy, burn_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_3(burn_call.target_contract, burn_call.selector, burn_call.args)); + utils::check_private_balance(env, token_contract_address, owner, mint_amount - burn_amount); + } + + #[test(should_fail_with = "Balance too low")] + unconstrained fn burn_private_failure_more_than_balance() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let burn_amount: u128 = mint_amount * (10_Field as u128); + env.call_private(owner, Token::at(token_contract_address).burn_private(owner, burn_amount, 0_Field)); + } + + #[test(should_fail_with = "Assertion failed: Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero")] + unconstrained fn burn_private_failure_on_behalf_of_self_non_zero_nonce() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let burn_amount: u128 = mint_amount; + env.call_private(owner, Token::at(token_contract_address).burn_private(owner, burn_amount, 1_Field)); + } + + #[test(should_fail_with = "Balance too low")] + unconstrained fn burn_private_failure_on_behalf_of_other_more_than_balance() { + let (env, token_contract_address, owner, _, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_public_with_proxy(); + let burn_amount: u128 = mint_amount * (10_Field as u128); + let burn_call: aztec::context::calls::PrivateCall<12, 3, ()> = Token::at(token_contract_address).burn_private(owner, burn_amount, AUTHWIT_NONCE); + add_private_authwit_from_call(env, owner, proxy, burn_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_3(burn_call.target_contract, burn_call.selector, burn_call.args)); + } + + #[test(should_fail_with = "Unknown auth witness for message hash")] + unconstrained fn burn_private_failure_on_behalf_of_other_without_approval() { + let (env, token_contract_address, owner, _, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_public_with_proxy(); + let burn_amount: u128 = mint_amount / (10_Field as u128); + let burn_call: aztec::context::calls::PrivateCall<12, 3, ()> = Token::at(token_contract_address).burn_private(owner, burn_amount, AUTHWIT_NONCE); + env.call_private(owner, GenericProxy::at(proxy).forward_private_3(burn_call.target_contract, burn_call.selector, burn_call.args)); + } + + #[test(should_fail_with = "Unknown auth witness for message hash")] + unconstrained fn burn_private_failure_on_behalf_of_other_wrong_designated_caller() { + let (env, token_contract_address, owner, _, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_public_with_proxy(); + let burn_amount: u128 = mint_amount / (10_Field as u128); + let burn_call: aztec::context::calls::PrivateCall<12, 3, ()> = Token::at(token_contract_address).burn_private(owner, burn_amount, AUTHWIT_NONCE); + add_private_authwit_from_call(env, owner, owner, burn_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_3(burn_call.target_contract, burn_call.selector, burn_call.args)); + } + } + + pub mod burn_public { + use super::utils; + use crate::Token; + use aztec::oracle::random::random; + use aztec::test::helpers::authwit::add_public_authwit_from_call; + + #[test] + unconstrained fn burn_public_success() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let burn_amount: u128 = mint_amount / (10_Field as u128); + env.call_public(owner, Token::at(token_contract_address).burn_public(owner, burn_amount, 0_Field)); + utils::check_public_balance(env, token_contract_address, owner, mint_amount - burn_amount); + } + + #[test] + unconstrained fn burn_public_on_behalf_of_other() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(true); + let burn_amount: u128 = mint_amount / (10_Field as u128); + let burn_call: aztec::context::calls::PublicCall<11, 3, ()> = Token::at(token_contract_address).burn_public(owner, burn_amount, random()); + add_public_authwit_from_call(env, owner, recipient, burn_call); + env.call_public(recipient, burn_call); + utils::check_public_balance(env, token_contract_address, owner, mint_amount - burn_amount); + } + + #[test(should_fail_with = "Assertion failed: attempt to subtract with overflow")] + unconstrained fn burn_public_failure_more_than_balance() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let burn_amount: u128 = mint_amount * (10_Field as u128); + env.call_public(owner, Token::at(token_contract_address).burn_public(owner, burn_amount, 0_Field)); + } + + #[test(should_fail_with = "Assertion failed: Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero")] + unconstrained fn burn_public_failure_on_behalf_of_self_non_zero_nonce() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let burn_amount: u128 = mint_amount / (10_Field as u128); + env.call_public(owner, Token::at(token_contract_address).burn_public(owner, burn_amount, random())); + } + + #[test(should_fail_with = "unauthorized")] + unconstrained fn burn_public_failure_on_behalf_of_other_without_approval() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(true); + let burn_amount: u128 = mint_amount / (10_Field as u128); + let burn_call: aztec::context::calls::PublicCall<11, 3, ()> = Token::at(token_contract_address).burn_public(owner, burn_amount, random()); + env.call_public(recipient, burn_call); + } + + #[test(should_fail_with = "unauthorized")] + unconstrained fn burn_public_failure_on_behalf_of_other_wrong_caller() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(true); + let burn_amount: u128 = mint_amount / (10_Field as u128); + let burn_call: aztec::context::calls::PublicCall<11, 3, ()> = Token::at(token_contract_address).burn_public(owner, burn_amount, random()); + add_public_authwit_from_call(env, owner, owner, burn_call); + env.call_public(recipient, burn_call); + } + } + + pub mod mint_to_public { + use super::utils; + use crate::Token; + + #[test] + unconstrained fn mint_to_public_success() { + let (env, token_contract_address, owner, _): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress) = utils::setup(false); + let mint_amount: u128 = 10000_Field as u128; + env.call_public(owner, Token::at(token_contract_address).mint_to_public(owner, mint_amount)); + utils::check_public_balance(env, token_contract_address, owner, mint_amount); + let total_supply: u128 = env.view_public(Token::at(token_contract_address).total_supply()); + assert(total_supply == mint_amount); + } + + #[test(should_fail_with = "caller is not minter")] + unconstrained fn mint_as_non_minter() { + let (env, token_contract_address, _, recipient): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress) = utils::setup(false); + let mint_amount: u128 = 10000_Field as u128; + env.call_public(recipient, Token::at(token_contract_address).mint_to_public(recipient, mint_amount)); + } + + #[test(should_fail)] + unconstrained fn mint_overflow() { + let (env, token_contract_address, owner, recipient): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress) = utils::setup(false); + let amount_until_overflow: u128 = 1000_Field as u128; + let mint_amount: u128 = (2_Field.pow_32(128_Field) - (amount_until_overflow as Field)) as u128; + env.call_public(owner, Token::at(token_contract_address).mint_to_public(recipient, mint_amount)); + env.call_public(owner, Token::at(token_contract_address).mint_to_public(recipient, amount_until_overflow)); + } + } + + pub mod reading_constants { + use super::utils; + use crate::Token; + + #[test] + unconstrained fn check_decimals_private() { + let (env, token_contract_address, owner, _): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress) = utils::setup(false); + let result: u8 = env.view_private(owner, Token::at(token_contract_address).private_get_decimals()); + assert(result == 18_u8); + } + + #[test] + unconstrained fn check_decimals_public() { + let (env, token_contract_address, _, _): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress) = utils::setup(false); + let result: u8 = env.view_public(Token::at(token_contract_address).public_get_decimals()); + assert(result == 18_u8); + } + } + + pub mod transfer { + use super::utils; + use crate::Token; + + #[test] + unconstrained fn transfer_private() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_amount: u128 = 1000_Field as u128; + env.call_private(owner, Token::at(token_contract_address).transfer(recipient, transfer_amount)); + utils::check_private_balance(env, token_contract_address, owner, mint_amount - transfer_amount); + utils::check_private_balance(env, token_contract_address, recipient, transfer_amount); + } + + #[test] + unconstrained fn transfer_private_to_self() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_amount: u128 = 1000_Field as u128; + let _: () = env.call_private(owner, Token::at(token_contract_address).transfer(owner, transfer_amount)); + utils::check_private_balance(env, token_contract_address, owner, mint_amount); + } + + #[test] + unconstrained fn transfer_private_to_non_deployed_account() { + let (mut env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let not_deployed: aztec::protocol::address::AztecAddress = env.create_light_account(); + let transfer_amount: u128 = 1000_Field as u128; + env.call_private(owner, Token::at(token_contract_address).transfer(not_deployed, transfer_amount)); + utils::check_private_balance(env, token_contract_address, owner, mint_amount - transfer_amount); + utils::check_private_balance(env, token_contract_address, not_deployed, transfer_amount); + } + + #[test(should_fail_with = "Balance too low")] + unconstrained fn transfer_private_failure_more_than_balance() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_amount: u128 = mint_amount + (1_Field as u128); + env.call_private(owner, Token::at(token_contract_address).transfer(recipient, transfer_amount)); + } + } + + pub mod transfer_in_private { + use super::utils; + use crate::Token; + use aztec::test::helpers::authwit::add_private_authwit_from_call; + use generic_proxy_contract::GenericProxy; + + #[test] + unconstrained fn transfer_private_on_behalf_of_other() { + let (env, token_contract_address, owner, recipient, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_amount: u128 = 1000_Field as u128; + let transfer_private_from_call: aztec::context::calls::PrivateCall<19, 4, ()> = Token::at(token_contract_address).transfer_in_private(owner, recipient, transfer_amount, 1_Field); + add_private_authwit_from_call(env, owner, proxy, transfer_private_from_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_private_from_call.target_contract, transfer_private_from_call.selector, transfer_private_from_call.args)); + utils::check_private_balance(env, token_contract_address, owner, mint_amount - transfer_amount); + utils::check_private_balance(env, token_contract_address, recipient, transfer_amount); + } + + #[test(should_fail_with = "Assertion failed: Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero")] + unconstrained fn transfer_private_failure_on_behalf_of_self_non_zero_nonce() { + let (env, token_contract_address, owner, recipient, _): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_amount: u128 = 1000_Field as u128; + let transfer_private_from_call: aztec::context::calls::PrivateCall<19, 4, ()> = Token::at(token_contract_address).transfer_in_private(owner, recipient, transfer_amount, 1_Field); + add_private_authwit_from_call(env, owner, recipient, transfer_private_from_call); + env.call_private(owner, transfer_private_from_call); + } + + #[test(should_fail_with = "Balance too low")] + unconstrained fn transfer_private_failure_on_behalf_of_more_than_balance() { + let (env, token_contract_address, owner, recipient, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_amount: u128 = mint_amount + (1_Field as u128); + let transfer_private_from_call: aztec::context::calls::PrivateCall<19, 4, ()> = Token::at(token_contract_address).transfer_in_private(owner, recipient, transfer_amount, 1_Field); + add_private_authwit_from_call(env, owner, proxy, transfer_private_from_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_private_from_call.target_contract, transfer_private_from_call.selector, transfer_private_from_call.args)); + } + + #[test(should_fail_with = "Unknown auth witness for message hash")] + unconstrained fn transfer_private_failure_on_behalf_of_other_without_approval() { + let (env, token_contract_address, owner, recipient, _, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_amount: u128 = 1000_Field as u128; + let transfer_private_from_call: aztec::context::calls::PrivateCall<19, 4, ()> = Token::at(token_contract_address).transfer_in_private(owner, recipient, transfer_amount, 1_Field); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_private_from_call.target_contract, transfer_private_from_call.selector, transfer_private_from_call.args)); + } + + #[test(should_fail_with = "Unknown auth witness for message hash")] + unconstrained fn transfer_private_failure_on_behalf_of_other_wrong_caller() { + let (env, token_contract_address, owner, recipient, _, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_amount: u128 = 1000_Field as u128; + let transfer_private_from_call: aztec::context::calls::PrivateCall<19, 4, ()> = Token::at(token_contract_address).transfer_in_private(owner, recipient, transfer_amount, 1_Field); + add_private_authwit_from_call(env, owner, owner, transfer_private_from_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_private_from_call.target_contract, transfer_private_from_call.selector, transfer_private_from_call.args)); + } + } + + pub mod transfer_in_private_with_offchain_delivery { + use super::utils; + use crate::Token; + use aztec::test::helpers::authwit::add_private_authwit_from_call; + use generic_proxy_contract::GenericProxy; + + #[test] + unconstrained fn transfer_in_private_with_offchain_delivery_updates_both_balances() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_amount: u128 = 1000_Field as u128; + let transfer_call: aztec::context::calls::PrivateCall<42, 4, ()> = Token::at(token_contract_address).transfer_in_private_with_offchain_delivery(owner, recipient, transfer_amount, 0_Field); + env.call_private(owner, transfer_call); + let messages: BoundedVec = env.offchain_messages(); + let mut batch: BoundedVec = BoundedVec::::new(); + for i in 0_u32..messages.len() { + batch.push(messages.get(i)); + }; + env.execute_utility(Token::at(token_contract_address).offchain_receive(batch)); + utils::check_private_balance(env, token_contract_address, owner, mint_amount - transfer_amount); + utils::check_private_balance(env, token_contract_address, recipient, transfer_amount); + } + + #[test(should_fail_with = "Assertion failed: Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero")] + unconstrained fn transfer_in_private_with_offchain_delivery_failure_on_behalf_of_self_non_zero_nonce() { + let (env, token_contract_address, owner, recipient, _): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_amount: u128 = 1000_Field as u128; + let transfer_call: aztec::context::calls::PrivateCall<42, 4, ()> = Token::at(token_contract_address).transfer_in_private_with_offchain_delivery(owner, recipient, transfer_amount, 1_Field); + add_private_authwit_from_call(env, owner, recipient, transfer_call); + env.call_private(owner, transfer_call); + } + + #[test(should_fail_with = "Balance too low")] + unconstrained fn transfer_in_private_with_offchain_delivery_failure_on_behalf_of_more_than_balance() { + let (env, token_contract_address, owner, recipient, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_amount: u128 = mint_amount + (1_Field as u128); + let transfer_call: aztec::context::calls::PrivateCall<42, 4, ()> = Token::at(token_contract_address).transfer_in_private_with_offchain_delivery(owner, recipient, transfer_amount, 1_Field); + add_private_authwit_from_call(env, owner, proxy, transfer_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_call.target_contract, transfer_call.selector, transfer_call.args)); + } + + #[test(should_fail_with = "Unknown auth witness for message hash")] + unconstrained fn transfer_in_private_with_offchain_delivery_failure_on_behalf_of_other_without_approval() { + let (env, token_contract_address, owner, recipient, _, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_amount: u128 = 1000_Field as u128; + let transfer_call: aztec::context::calls::PrivateCall<42, 4, ()> = Token::at(token_contract_address).transfer_in_private_with_offchain_delivery(owner, recipient, transfer_amount, 1_Field); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_call.target_contract, transfer_call.selector, transfer_call.args)); + } + + #[test(should_fail_with = "Unknown auth witness for message hash")] + unconstrained fn transfer_in_private_with_offchain_delivery_failure_on_behalf_of_other_wrong_caller() { + let (env, token_contract_address, owner, recipient, _, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_amount: u128 = 1000_Field as u128; + let transfer_call: aztec::context::calls::PrivateCall<42, 4, ()> = Token::at(token_contract_address).transfer_in_private_with_offchain_delivery(owner, recipient, transfer_amount, 1_Field); + add_private_authwit_from_call(env, owner, owner, transfer_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_call.target_contract, transfer_call.selector, transfer_call.args)); + } + } + + pub mod transfer_in_public { + use super::utils; + use crate::Token; + use aztec::test::helpers::authwit::add_public_authwit_from_call; + + #[test] + unconstrained fn public_transfer() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let transfer_amount: u128 = mint_amount / (10_Field as u128); + env.call_public(owner, Token::at(token_contract_address).transfer_in_public(owner, recipient, transfer_amount, 0_Field)); + utils::check_public_balance(env, token_contract_address, owner, mint_amount - transfer_amount); + utils::check_public_balance(env, token_contract_address, recipient, transfer_amount); + } + + #[test] + unconstrained fn public_transfer_to_self() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let transfer_amount: u128 = mint_amount / (10_Field as u128); + env.call_public(owner, Token::at(token_contract_address).transfer_in_public(owner, owner, transfer_amount, 0_Field)); + utils::check_public_balance(env, token_contract_address, owner, mint_amount); + } + + #[test] + unconstrained fn public_transfer_on_behalf_of_other() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(true); + let transfer_amount: u128 = mint_amount / (10_Field as u128); + let public_transfer_in_private_call: aztec::context::calls::PublicCall<18, 4, ()> = Token::at(token_contract_address).transfer_in_public(owner, recipient, transfer_amount, 1_Field); + add_public_authwit_from_call(env, owner, recipient, public_transfer_in_private_call); + env.call_public(recipient, public_transfer_in_private_call); + utils::check_public_balance(env, token_contract_address, owner, mint_amount - transfer_amount); + utils::check_public_balance(env, token_contract_address, recipient, transfer_amount); + } + + #[test(should_fail_with = "Assertion failed: attempt to subtract with overflow")] + unconstrained fn public_transfer_failure_more_than_balance() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let transfer_amount: u128 = mint_amount + (1_Field as u128); + let public_transfer_call: aztec::context::calls::PublicCall<18, 4, ()> = Token::at(token_contract_address).transfer_in_public(owner, recipient, transfer_amount, 0_Field); + env.call_public(owner, public_transfer_call); + } + + #[test(should_fail_with = "Assertion failed: Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero")] + unconstrained fn public_transfer_failure_on_behalf_of_self_non_zero_nonce() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let transfer_amount: u128 = mint_amount / (10_Field as u128); + let public_transfer_call: aztec::context::calls::PublicCall<18, 4, ()> = Token::at(token_contract_address).transfer_in_public(owner, recipient, transfer_amount, 1_Field); + add_public_authwit_from_call(env, owner, recipient, public_transfer_call); + env.call_public(owner, public_transfer_call); + } + + #[test(should_fail_with = "unauthorized")] + unconstrained fn public_transfer_failure_on_behalf_of_other_without_approval() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(true); + let transfer_amount: u128 = mint_amount / (10_Field as u128); + let public_transfer_in_private_call: aztec::context::calls::PublicCall<18, 4, ()> = Token::at(token_contract_address).transfer_in_public(owner, recipient, transfer_amount, 1_Field); + env.call_public(recipient, public_transfer_in_private_call); + } + + #[test(should_fail_with = "Assertion failed: attempt to subtract with overflow")] + unconstrained fn public_transfer_failure_on_behalf_of_other_more_than_balance() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(true); + let transfer_amount: u128 = mint_amount + (1_Field as u128); + let public_transfer_in_private_call: aztec::context::calls::PublicCall<18, 4, ()> = Token::at(token_contract_address).transfer_in_public(owner, recipient, transfer_amount, 1_Field); + add_public_authwit_from_call(env, owner, recipient, public_transfer_in_private_call); + env.call_public(recipient, public_transfer_in_private_call); + } + + #[test(should_fail_with = "unauthorized")] + unconstrained fn public_transfer_failure_on_behalf_of_other_wrong_caller() { + let (env, token_contract_address, owner, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(true); + let transfer_amount: u128 = mint_amount / (10_Field as u128); + let public_transfer_in_private_call: aztec::context::calls::PublicCall<18, 4, ()> = Token::at(token_contract_address).transfer_in_public(owner, recipient, transfer_amount, 1_Field); + add_public_authwit_from_call(env, owner, owner, public_transfer_in_private_call); + env.call_public(recipient, public_transfer_in_private_call); + } + } + + pub mod transfer_to_private { + use super::utils; + use crate::Token; + use aztec::oracle::random::random; + use aztec::protocol::traits::Deserialize; + use uint_note::PartialUintNote; + + /// Internal orchestration means that the calls to `prepare_private_balance_increase` + /// and `finalize_transfer_to_private` are done by the TOKEN contract itself. + /// In this test's case this is done by the `Token::transfer_to_private(...)` function called + /// in `utils::setup_mint_and_transfer_to_private`. + #[test] + unconstrained fn transfer_to_private_internal_orchestration() { + let (env, token_contract_address, user, _, amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + utils::check_private_balance(env, token_contract_address, user, amount); + } + + /// External orchestration means that the calls to prepare and finalize are not done by the Token contract. This flow + /// will typically be used by a DEX. + #[test] + unconstrained fn transfer_to_private_external_orchestration() { + let (env, token_contract_address, owner, recipient, amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let partial_uint_note: PartialUintNote = env.call_private(owner, Token::at(token_contract_address).prepare_private_balance_increase(recipient)); + env.call_public(owner, Token::at(token_contract_address).finalize_transfer_to_private(amount, partial_uint_note)); + utils::check_private_balance(env, token_contract_address, recipient, amount); + } + + /// External orchestration means that the calls to prepare and finalize are not done by the Token contract. This flow + /// will typically be used by a DEX. + #[test] + unconstrained fn transfer_to_private_from_private_external_orchestration() { + let (env, token_contract_address, owner, recipient, amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let partial_uint_note: PartialUintNote = env.call_private(owner, Token::at(token_contract_address).prepare_private_balance_increase(recipient)); + env.call_private(owner, Token::at(token_contract_address).finalize_transfer_to_private_from_private(owner, partial_uint_note, amount, 0_Field)); + utils::check_private_balance(env, token_contract_address, recipient, amount); + utils::check_private_balance(env, token_contract_address, owner, 0_u128); + } + + #[test(should_fail_with = "Invalid partial note or completer")] + unconstrained fn transfer_to_private_transfer_not_prepared() { + let (env, token_contract_address, owner, _, amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let commitment: Field = random(); + let partial_uint_note: PartialUintNote = PartialUintNote::deserialize([commitment]); + env.call_public(owner, Token::at(token_contract_address).finalize_transfer_to_private(amount, partial_uint_note)); + } + + #[test(should_fail_with = "Assertion failed: attempt to subtract with overflow")] + unconstrained fn transfer_to_private_failure_not_an_owner() { + let (env, token_contract_address, owner, not_owner, amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let partial_uint_note: PartialUintNote = env.call_private(owner, Token::at(token_contract_address).prepare_private_balance_increase(not_owner)); + env.call_public(not_owner, Token::at(token_contract_address).finalize_transfer_to_private(amount, partial_uint_note)); + } + + #[test(should_fail_with = "Invalid partial note or completer")] + unconstrained fn incorrect_completer_cannot_complete_partial_note() { + let (mut env, token_contract_address, owner, recipient, amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_public(false); + let completer: aztec::protocol::address::AztecAddress = env.create_light_account(); + let partial_uint_note: PartialUintNote = env.call_private(completer, Token::at(token_contract_address).prepare_private_balance_increase(recipient)); + env.call_public(owner, Token::at(token_contract_address).finalize_transfer_to_private(amount, partial_uint_note)); + } + } + + pub mod transfer_to_public { + use super::utils; + use crate::Token; + use aztec::oracle::random::random; + use aztec::test::helpers::authwit::add_private_authwit_from_call; + use generic_proxy_contract::GenericProxy; + + #[test] + unconstrained fn transfer_to_public_on_behalf_of_self() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_to_public_amount: u128 = mint_amount / (10_Field as u128); + env.call_private(owner, Token::at(token_contract_address).transfer_to_public(owner, owner, transfer_to_public_amount, 0_Field)); + utils::check_private_balance(env, token_contract_address, owner, mint_amount - transfer_to_public_amount); + utils::check_public_balance(env, token_contract_address, owner, transfer_to_public_amount); + } + + #[test] + unconstrained fn transfer_to_public_on_behalf_of_other() { + let (env, token_contract_address, owner, recipient, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_to_public_amount: u128 = mint_amount / (10_Field as u128); + let transfer_to_public_call: aztec::context::calls::PrivateCall<18, 4, ()> = Token::at(token_contract_address).transfer_to_public(owner, recipient, transfer_to_public_amount, 0_Field); + add_private_authwit_from_call(env, owner, proxy, transfer_to_public_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_to_public_call.target_contract, transfer_to_public_call.selector, transfer_to_public_call.args)); + utils::check_private_balance(env, token_contract_address, owner, mint_amount - transfer_to_public_amount); + utils::check_public_balance(env, token_contract_address, recipient, transfer_to_public_amount); + } + + #[test(should_fail_with = "Balance too low")] + unconstrained fn transfer_to_public_failure_more_than_balance() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_to_public_amount: u128 = mint_amount + (1_Field as u128); + env.call_private(owner, Token::at(token_contract_address).transfer_to_public(owner, owner, transfer_to_public_amount, 0_Field)); + } + + #[test(should_fail_with = "Assertion failed: Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero")] + unconstrained fn transfer_to_public_failure_on_behalf_of_self_non_zero_nonce() { + let (env, token_contract_address, owner, _, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_to_public_amount: u128 = mint_amount + (1_Field as u128); + env.call_private(owner, Token::at(token_contract_address).transfer_to_public(owner, owner, transfer_to_public_amount, random())); + } + + #[test(should_fail_with = "Balance too low")] + unconstrained fn transfer_to_public_failure_on_behalf_of_other_more_than_balance() { + let (env, token_contract_address, owner, recipient, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_to_public_amount: u128 = mint_amount + (1_Field as u128); + let transfer_to_public_call: aztec::context::calls::PrivateCall<18, 4, ()> = Token::at(token_contract_address).transfer_to_public(owner, recipient, transfer_to_public_amount, 0_Field); + add_private_authwit_from_call(env, owner, proxy, transfer_to_public_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_to_public_call.target_contract, transfer_to_public_call.selector, transfer_to_public_call.args)); + } + + #[test(should_fail_with = "Unknown auth witness for message hash")] + unconstrained fn transfer_to_public_failure_on_behalf_of_other_invalid_designated_caller() { + let (env, token_contract_address, owner, recipient, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_to_public_amount: u128 = mint_amount + (1_Field as u128); + let transfer_to_public_call: aztec::context::calls::PrivateCall<18, 4, ()> = Token::at(token_contract_address).transfer_to_public(owner, recipient, transfer_to_public_amount, 0_Field); + add_private_authwit_from_call(env, owner, owner, transfer_to_public_call); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_to_public_call.target_contract, transfer_to_public_call.selector, transfer_to_public_call.args)); + } + + #[test(should_fail_with = "Unknown auth witness for message hash")] + unconstrained fn transfer_to_public_failure_on_behalf_of_other_no_approval() { + let (env, token_contract_address, owner, recipient, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_to_public_amount: u128 = mint_amount + (1_Field as u128); + let transfer_to_public_call: aztec::context::calls::PrivateCall<18, 4, ()> = Token::at(token_contract_address).transfer_to_public(owner, recipient, transfer_to_public_amount, 0_Field); + env.call_private(owner, GenericProxy::at(proxy).forward_private_4(transfer_to_public_call.target_contract, transfer_to_public_call.selector, transfer_to_public_call.args)); + } + } + + pub mod transfer_to_public_and_prepare_private_balance_increase { + use super::utils; + use crate::Token; + use aztec::oracle::random::random; + use aztec::protocol::traits::Deserialize; + use aztec::test::helpers::authwit::add_private_authwit_from_call; + use generic_proxy_contract::GenericProxy; + use uint_note::PartialUintNote; + + #[test] + unconstrained fn transfer_to_public_and_prepare_private_balance_increase_and_finalize_transfer_to_private() { + let (env, token_contract_address, liquidity_provider, _, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let deposit_amount: u128 = mint_amount / (10_Field as u128); + let transfer_call: aztec::context::calls::PrivateCall<55, 4, PartialUintNote> = Token::at(token_contract_address).transfer_to_public_and_prepare_private_balance_increase(liquidity_provider, proxy, deposit_amount, 1_Field); + add_private_authwit_from_call(env, liquidity_provider, proxy, transfer_call); + let partial_note_field: Field = env.call_private(liquidity_provider, GenericProxy::at(proxy).forward_private_4_and_return(transfer_call.target_contract, transfer_call.selector, transfer_call.args)); + let partial_note: PartialUintNote = ::deserialize([partial_note_field]); + utils::check_private_balance(env, token_contract_address, liquidity_provider, mint_amount - deposit_amount); + utils::check_public_balance(env, token_contract_address, proxy, deposit_amount); + let change_amount: u128 = deposit_amount / (2_Field as u128); + env.call_public(proxy, Token::at(token_contract_address).finalize_transfer_to_private(change_amount, partial_note)); + utils::check_private_balance(env, token_contract_address, liquidity_provider, (mint_amount - deposit_amount) + change_amount); + utils::check_public_balance(env, token_contract_address, proxy, deposit_amount - change_amount); + } + + #[test(should_fail_with = "Balance too low")] + unconstrained fn transfer_to_public_and_prepare_private_balance_increase_failure_more_than_balance() { + let (env, token_contract_address, sender, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_amount: u128 = mint_amount + (1_Field as u128); + let _: PartialUintNote = env.call_private(sender, Token::at(token_contract_address).transfer_to_public_and_prepare_private_balance_increase(sender, recipient, transfer_amount, 0_Field)); + } + + #[test(should_fail_with = "Assertion failed: Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero")] + unconstrained fn transfer_to_public_and_prepare_private_balance_increase_failure_on_behalf_of_self_non_zero_nonce() { + let (env, token_contract_address, sender, recipient, mint_amount): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128) = utils::setup_and_mint_to_private(false); + let transfer_amount: u128 = mint_amount / (10_Field as u128); + let _: PartialUintNote = env.call_private(sender, Token::at(token_contract_address).transfer_to_public_and_prepare_private_balance_increase(sender, recipient, transfer_amount, random())); + } + + #[test(should_fail_with = "Unknown auth witness for message hash")] + unconstrained fn transfer_to_public_and_prepare_private_balance_increase_failure_on_behalf_of_other_no_approval() { + let (env, token_contract_address, sender, recipient, mint_amount, proxy): (aztec::test::helpers::test_environment::TestEnvironment, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, aztec::protocol::address::AztecAddress, u128, aztec::protocol::address::AztecAddress) = utils::setup_and_mint_to_private_with_proxy(); + let transfer_amount: u128 = mint_amount / (10_Field as u128); + let transfer_call: aztec::context::calls::PrivateCall<55, 4, PartialUintNote> = Token::at(token_contract_address).transfer_to_public_and_prepare_private_balance_increase(sender, recipient, transfer_amount, 1_Field); + env.call_private(sender, GenericProxy::at(proxy).forward_private_4(transfer_call.target_contract, transfer_call.selector, transfer_call.args)); + } + } + + pub mod utils { + use crate::Token; + use aztec::protocol::address::AztecAddress; + use aztec::test::helpers::test_environment::TestEnvironment; + + pub unconstrained fn setup(with_account_contracts: bool) -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress) { + let mut env: TestEnvironment = TestEnvironment::new(); + let (owner, recipient): (AztecAddress, AztecAddress) = if with_account_contracts { + let owner: AztecAddress = env.create_contract_account(); + let recipient: AztecAddress = env.create_contract_account(); + (owner, recipient) + } else { + let owner: AztecAddress = env.create_light_account(); + let recipient: AztecAddress = env.create_light_account(); + (owner, recipient) + }; + let initializer_call: aztec::context::calls::PublicCall<11, 64, ()> = Token::interface().constructor(owner, "TestToken0000000000000000000000", "TT00000000000000000000000000000", 18_u8); + let token_contract_address: AztecAddress = env.deploy("Token").with_public_initializer(owner, initializer_call); + (env, token_contract_address, owner, recipient) + } + + pub unconstrained fn setup_and_mint_to_public(with_account_contracts: bool) -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, u128) { + let (env, token_contract_address, owner, recipient): (TestEnvironment, AztecAddress, AztecAddress, AztecAddress) = setup(with_account_contracts); + let mint_amount: u128 = 10000_Field as u128; + env.call_public(owner, Token::at(token_contract_address).mint_to_public(owner, mint_amount)); + (env, token_contract_address, owner, recipient, mint_amount) + } + + pub unconstrained fn setup_and_mint_amount_to_private(with_account_contracts: bool, mint_amount: u128) -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, u128) { + let (env, token_contract_address, owner, recipient): (TestEnvironment, AztecAddress, AztecAddress, AztecAddress) = setup(with_account_contracts); + env.call_private(owner, Token::at(token_contract_address).mint_to_private(owner, mint_amount)); + (env, token_contract_address, owner, recipient, mint_amount) + } + + pub unconstrained fn setup_and_mint_to_private(with_account_contracts: bool) -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, u128) { + let mint_amount: u128 = 10000_Field as u128; + setup_and_mint_amount_to_private(with_account_contracts, mint_amount) + } + + pub unconstrained fn check_public_balance(env: TestEnvironment, token_contract_address: AztecAddress, address: AztecAddress, address_amount: u128) { + assert(env.view_public(Token::at(token_contract_address).balance_of_public(address)) == address_amount); + } + + pub unconstrained fn check_private_balance(env: TestEnvironment, token_contract_address: AztecAddress, address: AztecAddress, address_amount: u128) { + assert(env.execute_utility(Token::at(token_contract_address).balance_of_private(address)) == address_amount); + } + + pub unconstrained fn setup_and_mint_to_private_with_proxy() -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, u128, AztecAddress) { + let (mut env, token_contract_address, owner, recipient, mint_amount): (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, u128) = setup_and_mint_to_private(true); + let proxy: AztecAddress = env.deploy("@generic_proxy_contract/GenericProxy").without_initializer(); + (env, token_contract_address, owner, recipient, mint_amount, proxy) + } + + pub unconstrained fn setup_and_mint_to_public_with_proxy() -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, u128, AztecAddress) { + let (mut env, token_contract_address, owner, recipient, mint_amount): (TestEnvironment, AztecAddress, AztecAddress, AztecAddress, u128) = setup_and_mint_to_public(true); + let proxy: AztecAddress = env.deploy("@generic_proxy_contract/GenericProxy").without_initializer(); + (env, token_contract_address, owner, recipient, mint_amount, proxy) + } + } +} + +// Warning: the generated code has syntax errors diff --git a/noir-projects/noir-contracts-comp-failures/README.md b/noir-projects/noir-contracts-comp-failures/README.md deleted file mode 100644 index d158c4376e3e..000000000000 --- a/noir-projects/noir-contracts-comp-failures/README.md +++ /dev/null @@ -1,37 +0,0 @@ -## Noir Contracts Compilation Failures - -Aztec-nr contracts that are expected to fail to compile. Each case asserts that compilation fails *and* that the full set of `error:` diagnostics nargo emits matches a committed snapshot, so an unrelated regression that breaks compilation for a different reason does not silently pass. - -### Layout - -Each contract lives in `contracts//` with: - -- `Nargo.toml` — `type = "contract"`, depends on `aztec = { path = "../../../aztec-nr/aztec" }`. -- `src/main.nr` — the intentionally invalid contract. -- `expected_error` — one line per nargo `error:` headline (stripped of the `error: ` prefix), in emission order. An empty file means the contract is expected to compile successfully; see its `src/main.nr` doc comment for context. - -### Running - -```sh -./bootstrap.sh test # all cases -./bootstrap.sh test reserved_public_dispatch # one case -./bootstrap.sh test 'panic_on_*' # glob subset -``` - -For each contract the runner: - -1. Runs `nargo compile --silence-warnings` and asserts it fails. -2. Extracts every `error: ` line from stderr in order and strips the `error: ` prefix. -3. Requires the extracted list to equal, line for line, the non-blank lines of `expected_error`. Any difference — text, count, or order — fails the test. - -### Updating expected errors - -When a compiler or macro error message changes intentionally, regenerate snapshots locally: - -```sh -ACCEPT_SNAPSHOTS=1 ./bootstrap.sh test -``` - -The runner extracts each `error: ` headline, strips the prefix, and writes one per line — no manual trimming needed. If nargo emits no `error: ` diagnostics (e.g. an internal compiler panic), the full stderr is written and a `⚠` warning is printed; those cases need a manual trim before committing. - -CI refuses to run with `ACCEPT_SNAPSHOTS` set (`CI=1 ACCEPT_SNAPSHOTS=1` exits non-zero), so any drift between committed snapshots and actual stderr must be resolved intentionally by a developer. diff --git a/noir-projects/noir-contracts-comp-failures/contracts/.gitignore b/noir-projects/noir-contracts-comp-failures/contracts/.gitignore deleted file mode 100644 index b60de5b5f2c9..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -**/target diff --git a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_non_external_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_non_external_fn/expected_error deleted file mode 100644 index 81efd937b978..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_non_external_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[allow_phase_change] attribute can only be applied to #[external("private")] functions - foo is not diff --git a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_utility_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_utility_fn/expected_error deleted file mode 100644 index 8938c1a408f3..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/allow_phase_change_on_utility_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[allow_phase_change] attribute cannot be applied to #[external("utility")] functions - foo diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_before_external/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_before_external/expected_error deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_from_wrong_type/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_from_wrong_type/expected_error deleted file mode 100644 index 1bbce0be00f8..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_from_wrong_type/expected_error +++ /dev/null @@ -1 +0,0 @@ -Argument from in function foo must be of type AztecAddress, but is of type Field diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_from_param/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_from_param/expected_error deleted file mode 100644 index 8b1cfa5ad9d6..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_from_param/expected_error +++ /dev/null @@ -1 +0,0 @@ -Function foo does not have a from parameter. Please specify which one to use in #[authorize_once("...", "authwit_nonce")] diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_nonce_param/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_nonce_param/expected_error deleted file mode 100644 index ed3aaf603d01..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_missing_nonce_param/expected_error +++ /dev/null @@ -1 +0,0 @@ -Function foo does not have a authwit_nonce. Please specify which one to use in #[authorize_once("from", "...")] diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_nonce_wrong_type/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_nonce_wrong_type/expected_error deleted file mode 100644 index bd57ebb6529a..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_nonce_wrong_type/expected_error +++ /dev/null @@ -1 +0,0 @@ -Argument authwit_nonce in function foo must be of type Field, but is of type u64 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_non_external_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_non_external_fn/expected_error deleted file mode 100644 index f3f70104ef54..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_non_external_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[authorize_once] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_utility_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_utility_fn/expected_error deleted file mode 100644 index dbe74ea297fa..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorize_once_on_utility_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[authorize_once] attribute cannot be applied to #[external("utility")] functions - foo diff --git a/noir-projects/noir-contracts-comp-failures/contracts/aztec_macro_too_many_args/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/aztec_macro_too_many_args/expected_error deleted file mode 100644 index ef5de9454fe1..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/aztec_macro_too_many_args/expected_error +++ /dev/null @@ -1 +0,0 @@ -#[aztec] expects 0 or 1 arguments, got 2 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/bob_token/Nargo.toml b/noir-projects/noir-contracts-comp-failures/contracts/bob_token/Nargo.toml deleted file mode 100644 index c43230433fb1..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/bob_token/Nargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "bob_token" -type = "contract" -authors = [""] - -[dependencies] -aztec = { path = "../../../aztec-nr/aztec" } -balance_set = { path = "../../../aztec-nr/balance-set" } diff --git a/noir-projects/noir-contracts-comp-failures/contracts/bob_token/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/bob_token/expected_error deleted file mode 100644 index 29117d5b03e1..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/bob_token/expected_error +++ /dev/null @@ -1,38 +0,0 @@ -The #[internal] attribute cannot be applied to external functions - transfer_public is marked as both #[external] and #[internal("public")] -A function marked as #[external("private")] or #[internal("private")] must not have public Noir visibility - transfer_private's visibility is 'pub' -The #[view] attribute can only be applied to #[external("private")] or #[external("public")] functions - _assert_is_owner is neither -#[external("private")] or #[internal("private")] functions must not be unconstrained - mint_private is -Function _assert_is_owner must be marked as either #[external(...)], #[internal(...)], or #[test] -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -missing pub keyword on return type of function private_balance_of -cannot find `self` in this scope -missing pub keyword on return type of function public_balance_of -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope -cannot find `self` in this scope diff --git a/noir-projects/noir-contracts-comp-failures/contracts/duplicate_storage/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/duplicate_storage/expected_error deleted file mode 100644 index c1331b6dca3f..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/duplicate_storage/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[storage] macro can only be applied to a struct with name 'Storage', got 'Storage2' instead. diff --git a/noir-projects/noir-contracts-comp-failures/contracts/event_selector_collision/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/event_selector_collision/expected_error deleted file mode 100644 index 5d2027e29796..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/event_selector_collision/expected_error +++ /dev/null @@ -1 +0,0 @@ -Event selector collision detected between events 'EventCollision8370082250' and 'EventCollision' diff --git a/noir-projects/noir-contracts-comp-failures/contracts/external_and_internal_together/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/external_and_internal_together/expected_error deleted file mode 100644 index bf93cad5e5d7..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/external_and_internal_together/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[internal] attribute cannot be applied to external functions - foo is marked as both #[external] and #[internal("private")] diff --git a/noir-projects/noir-contracts-comp-failures/contracts/incorrect_storage_struct_name/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/incorrect_storage_struct_name/expected_error deleted file mode 100644 index c1331b6dca3f..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/incorrect_storage_struct_name/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[storage] macro can only be applied to a struct with name 'Storage', got 'Storage2' instead. diff --git a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_non_external_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_non_external_fn/expected_error deleted file mode 100644 index 5c684056da32..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_non_external_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[initializer] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither diff --git a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_utility_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_utility_fn/expected_error deleted file mode 100644 index 73500d3e2c07..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/initializer_on_utility_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[initializer] attribute cannot be applied to #[external("utility")] functions - foo diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/expected_error deleted file mode 100644 index 52ea26ac60ee..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/invalid_event/expected_error +++ /dev/null @@ -1 +0,0 @@ -event's serialized length exceeds the maximum allowed for private events diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_external_function_type/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/invalid_external_function_type/expected_error deleted file mode 100644 index e53202f2683b..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/invalid_external_function_type/expected_error +++ /dev/null @@ -1 +0,0 @@ -Function 'invalid_external_function_type' is marked as #[external("invalid")], but 'invalid' is not a valid external function type. External functions must be one of 'private', 'public' or 'utility' diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_internal_function_type/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/invalid_internal_function_type/expected_error deleted file mode 100644 index 598737fea58a..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/invalid_internal_function_type/expected_error +++ /dev/null @@ -1 +0,0 @@ -Function 'foo' is marked as #[internal("utility")], but 'utility' is not a valid internal function type. Internal functions must be one of 'private', 'public' diff --git a/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/expected_error deleted file mode 100644 index 02c046ffd7ab..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/invalid_note/expected_error +++ /dev/null @@ -1 +0,0 @@ -InvalidNote has a packed length of 9 fields, which exceeds the maximum allowed length of 8 fields. See https://docs.aztec.network/errors/4 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/marked_private_unconstrained/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/marked_private_unconstrained/expected_error deleted file mode 100644 index 2688275a93b9..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/marked_private_unconstrained/expected_error +++ /dev/null @@ -1 +0,0 @@ -#[external("private")] or #[internal("private")] functions must not be unconstrained - unconstrained_private_function is diff --git a/noir-projects/noir-contracts-comp-failures/contracts/marked_public_unconstrained/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/marked_public_unconstrained/expected_error deleted file mode 100644 index 8758aa579ffc..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/marked_public_unconstrained/expected_error +++ /dev/null @@ -1 +0,0 @@ -#[external("public")] or #[internal("public")] functions must not be unconstrained - unconstrained_public_function is diff --git a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_non_external_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_non_external_fn/expected_error deleted file mode 100644 index 69b930611586..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_non_external_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[noinitcheck] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither diff --git a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_utility_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_utility_fn/expected_error deleted file mode 100644 index 1e1dfaca9e12..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_on_utility_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[noinitcheck] attribute cannot be applied to #[external("utility")] functions - foo diff --git a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_without_initializer/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_without_initializer/expected_error deleted file mode 100644 index 17c3dff427ad..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/noinitcheck_without_initializer/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[noinitcheck] attribute is unnecessary for contracts with no #[initializer] functions diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/expected_error deleted file mode 100644 index 0752e0c1a17f..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/non_deserializable/expected_error +++ /dev/null @@ -1,6 +0,0 @@ -Contract function 'bad_private_return' returns a value of type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. -Parameter '_p' of contract function 'bad_private_param' has type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. -Contract function 'bad_public_return' returns a value of type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. -Parameter '_p' of contract function 'bad_public_param' has type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. -Contract function 'bad_utility_return' returns a value of type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. -Parameter '_p' of contract function 'bad_utility_param' has type NotDeserializable, which does not implement the Deserialize trait. Add #[derive(Deserialize)] to NotDeserializable's declaration. diff --git a/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/expected_error deleted file mode 100644 index 33a63c051f3a..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/non_serializable/expected_error +++ /dev/null @@ -1,6 +0,0 @@ -Contract function 'bad_private_return' returns a value of type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. -Parameter '_p' of contract function 'bad_private_param' has type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. -Contract function 'bad_public_return' returns a value of type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. -Parameter '_p' of contract function 'bad_public_param' has type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. -Contract function 'bad_utility_return' returns a value of type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. -Parameter '_p' of contract function 'bad_utility_param' has type NotSerializable, which does not implement the Serialize trait. Add #[derive(Serialize)] to NotSerializable's declaration. diff --git a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_non_external_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_non_external_fn/expected_error deleted file mode 100644 index e2cf366b083d..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_non_external_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[only_self] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither diff --git a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_utility_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_utility_fn/expected_error deleted file mode 100644 index 67b493e28c6a..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/only_self_on_utility_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[only_self] attribute cannot be applied to #[external("utility")] functions - foo diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_external_fn_call/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_external_fn_call/expected_error deleted file mode 100644 index 03dcdf55e48b..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_external_fn_call/expected_error +++ /dev/null @@ -1 +0,0 @@ -Direct invocation of private functions is not supported. You attempted to call arbitrary_external_function. See https://docs.aztec.network/errors/6 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_internal_fn_call/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_internal_fn_call/expected_error deleted file mode 100644 index 70eb1d78dfed..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_private_internal_fn_call/expected_error +++ /dev/null @@ -1 +0,0 @@ -Direct invocation of private internal functions is not supported. You attempted to call arbitrary_private_function. See https://docs.aztec.network/errors/6 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_external_fn_call/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_external_fn_call/expected_error deleted file mode 100644 index b698579729a9..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_external_fn_call/expected_error +++ /dev/null @@ -1 +0,0 @@ -Direct invocation of public functions is not supported. You attempted to call arbitrary_external_function. See https://docs.aztec.network/errors/6 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_internal_fn_call/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_internal_fn_call/expected_error deleted file mode 100644 index b50d8f6b8a7e..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_public_internal_fn_call/expected_error +++ /dev/null @@ -1 +0,0 @@ -Direct invocation of public internal functions is not supported. You attempted to call arbitrary_public_function. See https://docs.aztec.network/errors/6 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_utility_external_fn_call/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_utility_external_fn_call/expected_error deleted file mode 100644 index d83a13317cd4..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_direct_utility_external_fn_call/expected_error +++ /dev/null @@ -1 +0,0 @@ -Direct invocation of utility functions is not supported. You attempted to call arbitrary_external_function. See https://docs.aztec.network/errors/6 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_call/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_call/expected_error deleted file mode 100644 index 691f42b15075..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_call/expected_error +++ /dev/null @@ -1,2 +0,0 @@ -Could not resolve 'ZERO' in path -Your private call needs to be passed into the `self.call(...)` method to be executed (e.g. `self.call(MyContract::at(address).my_private_function(...args))` diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_static_call/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_static_call/expected_error deleted file mode 100644 index 1ef6eef9437f..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_private_static_call/expected_error +++ /dev/null @@ -1,2 +0,0 @@ -Could not resolve 'ZERO' in path -Your private static call needs to be passed into the `self.view(...)` method to be executed (e.g. `self.view(MyContract::at(address).my_private_static_function(...args))` diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_call/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_call/expected_error deleted file mode 100644 index aba4880076cb..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_call/expected_error +++ /dev/null @@ -1,2 +0,0 @@ -Could not resolve 'ZERO' in path -Your public call needs to be passed into the `self.call(...)`, `self.enqueue(...)` or `self.enqueue_incognito(...)` method to be executed (e.g. `self.call(MyContract::at(address).my_public_function(...args))` diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_static_call/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_static_call/expected_error deleted file mode 100644 index 663ed39ae75b..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_incorrectly_performed_public_static_call/expected_error +++ /dev/null @@ -1,2 +0,0 @@ -Could not resolve 'ZERO' in path -Your public static call needs to be passed into the `self.view(...)`, `self.enqueue_view(...)` or `self.enqueue_view_incognito(...)` method to be executed (e.g. `self.view(MyContract::at(address).my_public_static_function(...args))` diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_non_state_var_in_storage/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_non_state_var_in_storage/expected_error deleted file mode 100644 index a557e8eba5d2..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_non_state_var_in_storage/expected_error +++ /dev/null @@ -1,3 +0,0 @@ -Type NonStateVar does not implement StateVariable and hence cannot be placed in Storage struct. -Could not resolve 'init' in path -Type annotation needed diff --git a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_owned_state_var_in_storage/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/panic_on_owned_state_var_in_storage/expected_error deleted file mode 100644 index 912e28180292..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/panic_on_owned_state_var_in_storage/expected_error +++ /dev/null @@ -1,3 +0,0 @@ -Type PrivateImmutable implements OwnedStateVariable and hence cannot be placed in Storage struct without being wrapped in Owned. Wrap the type in Owned<..., Context>. -Could not resolve 'init' in path -Type annotation needed diff --git a/noir-projects/noir-contracts-comp-failures/contracts/pub_private_external_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/pub_private_external_fn/expected_error deleted file mode 100644 index 669dc8c04480..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/pub_private_external_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -A function marked as #[external("private")] or #[internal("private")] must not have public Noir visibility - foo's visibility is 'pub' diff --git a/noir-projects/noir-contracts-comp-failures/contracts/pub_public_external_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/pub_public_external_fn/expected_error deleted file mode 100644 index 044cc7b24636..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/pub_public_external_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -A function marked as #[external("public")] or #[internal("public")] must not have public Noir visibility - foo's visibility is 'pub' diff --git a/noir-projects/noir-contracts-comp-failures/contracts/pub_utility_external_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/pub_utility_external_fn/expected_error deleted file mode 100644 index e619f508ff8e..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/pub_utility_external_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -A function marked as #[external("utility")] must not have public Noir visibility - foo's visibility is 'pub' diff --git a/noir-projects/noir-contracts-comp-failures/contracts/public_allow_phase_change/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/public_allow_phase_change/expected_error deleted file mode 100644 index abb57930739e..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/public_allow_phase_change/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[allow_phase_change] attribute cannot be applied to #[external("public")] functions - foo diff --git a/noir-projects/noir-contracts-comp-failures/contracts/public_function_selector_collision/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/public_function_selector_collision/expected_error deleted file mode 100644 index 3ac5de4c49d9..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/public_function_selector_collision/expected_error +++ /dev/null @@ -1 +0,0 @@ -Public function selector collision detected between functions 'fn_selector_collision_1442740381' and 'fn_selector_collision' diff --git a/noir-projects/noir-contracts-comp-failures/contracts/reserved_emit_public_init_nullifier/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/reserved_emit_public_init_nullifier/expected_error deleted file mode 100644 index e7bef0a515de..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/reserved_emit_public_init_nullifier/expected_error +++ /dev/null @@ -1 +0,0 @@ -Function name '__emit_public_init_nullifier' is reserved for internal use diff --git a/noir-projects/noir-contracts-comp-failures/contracts/reserved_public_dispatch/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/reserved_public_dispatch/expected_error deleted file mode 100644 index 6652431061c4..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/reserved_public_dispatch/expected_error +++ /dev/null @@ -1 +0,0 @@ -Function name 'public_dispatch' is reserved for internal use diff --git a/noir-projects/noir-contracts-comp-failures/contracts/unmacroified_function_in_contract/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/unmacroified_function_in_contract/expected_error deleted file mode 100644 index 5923b9ac25d3..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/unmacroified_function_in_contract/expected_error +++ /dev/null @@ -1 +0,0 @@ -Function foo must be marked as either #[external(...)], #[internal(...)], or #[test] diff --git a/noir-projects/noir-contracts-comp-failures/contracts/user_defined_offchain_receive/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/user_defined_offchain_receive/expected_error deleted file mode 100644 index 3aa9a27613c7..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/user_defined_offchain_receive/expected_error +++ /dev/null @@ -1 +0,0 @@ -User-defined 'offchain_receive' is not allowed. The function is auto-injected by the #[aztec] macro. See https://docs.aztec.network/errors/7 diff --git a/noir-projects/noir-contracts-comp-failures/contracts/utility_not_unconstrained/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/utility_not_unconstrained/expected_error deleted file mode 100644 index aeeba4db64c8..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/utility_not_unconstrained/expected_error +++ /dev/null @@ -1 +0,0 @@ -#[external("utility")] must be unconstrained - constrained_utility_function isn't diff --git a/noir-projects/noir-contracts-comp-failures/contracts/view_on_non_external_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/view_on_non_external_fn/expected_error deleted file mode 100644 index 237014f4076a..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/view_on_non_external_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[view] attribute can only be applied to #[external("private")] or #[external("public")] functions - foo is neither diff --git a/noir-projects/noir-contracts-comp-failures/contracts/view_on_utility_fn/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/view_on_utility_fn/expected_error deleted file mode 100644 index b51bee13a6a6..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/view_on_utility_fn/expected_error +++ /dev/null @@ -1 +0,0 @@ -The #[view] attribute cannot be applied to #[external("utility")] functions - foo From e61be60379e7bd485973a16dc438c7bbb69ce45a Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 17:25:44 +0000 Subject: [PATCH 25/30] fix: resolve cherry-pick conflicts Removes the two stray files (bootstrap.sh and authorization_selector_collision/expected_error) that #23061 deleted as part of dropping the noir-contracts-comp-failures crate. Both had been modified on v4-next-staging, which created the rename/delete conflicts; the entire old crate is gone in #23061's direction. --- .../noir-contracts-comp-failures/bootstrap.sh | 141 ------------------ .../expected_error | 6 - 2 files changed, 147 deletions(-) delete mode 100755 noir-projects/noir-contracts-comp-failures/bootstrap.sh delete mode 100644 noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/expected_error diff --git a/noir-projects/noir-contracts-comp-failures/bootstrap.sh b/noir-projects/noir-contracts-comp-failures/bootstrap.sh deleted file mode 100755 index f03a3fa1e541..000000000000 --- a/noir-projects/noir-contracts-comp-failures/bootstrap.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env bash -source $(git rev-parse --show-toplevel)/ci3/source_bootstrap - -# nargo command path relative to the individual contract directory -export NARGO=${NARGO:-../../../../noir/noir-repo/target/release/nargo} - -# Check that `nargo compile` stderr matches expected_error exactly. -# -# Every nargo compile error begins with a line `error: `. The runner -# extracts that ordered list of headlines (stripped of the `error: ` prefix) and -# requires it to equal, line for line, the non-blank lines in expected_error. -# Any change to the emitted errors — different text, different count, different -# order — fails the test and must be resolved by regenerating the snapshot. -# -# When ACCEPT_SNAPSHOTS=1 the runner skips assertion and writes every extracted -# headline (one per line) into expected_error. CI refuses this flag so any drift -# must be resolved by a developer locally. If nargo emits no `error: ` lines -# (e.g. an internal compiler panic), the full stderr is written instead and a -# warning is printed — such cases need a manual trim before committing. -check_compilation_error() { - local contract_dir=$1 - local expected_error_file="$contract_dir/expected_error" - - local actual_output - local compile_rc=0 - actual_output=$(cd "$contract_dir" && $NARGO compile --silence-warnings 2>&1) || compile_rc=$? - - local actual_headlines - actual_headlines=$(echo "$actual_output" | awk '/^error: /{sub(/^error: /, ""); print}') - - if [ -n "${ACCEPT_SNAPSHOTS:-}" ]; then - if [ "$compile_rc" -eq 0 ]; then - : > "$expected_error_file" - echo "↻ $contract_dir: wrote empty expected_error (compiled successfully)" - elif [ -n "$actual_headlines" ]; then - echo "$actual_headlines" > "$expected_error_file" - local count - count=$(printf '%s\n' "$actual_headlines" | wc -l | tr -d ' ') - echo "↻ $contract_dir: wrote $count headline(s) to expected_error" - else - echo "$actual_output" > "$expected_error_file" - echo "⚠ $contract_dir: no 'error: ' headlines found in stderr; wrote full output — trim manually" - fi - return 0 - fi - - if [ ! -f "$expected_error_file" ]; then - echo "✗ $contract_dir: No expected_error file. Run with ACCEPT_SNAPSHOTS=1 to generate one." - exit 1 - fi - - local -a expected_lines=() actual_lines=() - while IFS= read -r line; do - [ -z "$line" ] && continue - expected_lines+=("$line") - done < "$expected_error_file" - while IFS= read -r line; do - actual_lines+=("$line") - done <<< "$actual_headlines" - # `<<<` always appends a newline; if no headlines were found this leaves a - # single empty element that would miscount 0 as 1. - if [ "${#actual_lines[@]}" -eq 1 ] && [ -z "${actual_lines[0]}" ]; then - actual_lines=() - fi - - if [ "${#expected_lines[@]}" -ne "${#actual_lines[@]}" ]; then - echo "✗ $contract_dir: error count mismatch — expected ${#expected_lines[@]}, got ${#actual_lines[@]}" - echo "Expected lines:" - if [ "${#expected_lines[@]}" -eq 0 ]; then echo " (none)"; else printf ' %s\n' "${expected_lines[@]}"; fi - echo "Actual error headlines:" - if [ "${#actual_lines[@]}" -eq 0 ]; then echo " (none)"; else printf ' %s\n' "${actual_lines[@]}"; fi - echo "Full stderr:" - echo "$actual_output" - exit 1 - fi - - local i - for i in "${!expected_lines[@]}"; do - if [ "${actual_lines[$i]}" != "${expected_lines[$i]}" ]; then - echo "✗ $contract_dir: error $((i + 1)) does not match" - echo " Expected: ${expected_lines[$i]}" - echo " Actual: ${actual_lines[$i]}" - echo "Full stderr:" - echo "$actual_output" - exit 1 - fi - done - - if [ "${#expected_lines[@]}" -eq 0 ]; then - echo "⚠ $contract_dir: compiled successfully (see src/main.nr doc comment)" - else - echo "✓ $contract_dir: Compilation failed as expected with correct error(s)" - fi -} - -# Tests that compilation of contracts in noir-contracts-comp-failures fails with the expected error message. -# -# Optional arg: a shell glob to filter by contract directory name. Examples: -# ./bootstrap.sh test # all cases -# ./bootstrap.sh test reserved_public_dispatch -# ./bootstrap.sh test 'panic_on_*' -test() { - if [ -n "${ACCEPT_SNAPSHOTS:-}" ] && [ "${CI:-0}" = "1" ]; then - echo "ACCEPT_SNAPSHOTS is not permitted in CI. Snapshots must be regenerated locally and committed." >&2 - exit 1 - fi - - local pattern=${1:-} - local matched=0 - - for contract_dir in contracts/*/; do - [ -d "$contract_dir" ] || continue - if [ -n "$pattern" ]; then - local name=${contract_dir%/} - name=${name#contracts/} - # `case` pattern matching supports shell globs; leave $pattern unquoted. - case "$name" in - $pattern) ;; - *) continue ;; - esac - fi - check_compilation_error "$contract_dir" - matched=$((matched + 1)) - done - - if [ -n "$pattern" ] && [ "$matched" -eq 0 ]; then - echo "✗ no contracts matched pattern '$pattern'" >&2 - exit 1 - fi -} - -function test_cmds { - hash=$(hash_str $(../../noir/bootstrap.sh hash) $(cache_content_hash ^noir-projects/noir-contracts-comp-failures)) - echo "$hash ./noir-projects/noir-contracts-comp-failures/bootstrap.sh test" -} - -case "$cmd" in - *) - default_cmd_handler "$@" - ;; -esac diff --git a/noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/expected_error b/noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/expected_error deleted file mode 100644 index 924fc14595ad..000000000000 --- a/noir-projects/noir-contracts-comp-failures/contracts/authorization_selector_collision/expected_error +++ /dev/null @@ -1,6 +0,0 @@ -Trait crate::authwit::authorization_interface::AuthorizationInterface not found -Could not resolve 'authwit' in path -check_trait_impl_where_clause_matches_trait_where_clause: missing trait ID -check_parent_traits_are_implemented: missing trait ID -check_trait_impl_method_matches_declaration: missing trait impl -Selector collision detected between authorizations 'EventCollision8370082250' and 'EventCollision' From 7fb436102cd2fc12f512f2b73863e0c66bcd0246 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 17:55:23 +0000 Subject: [PATCH 26/30] test: regenerate contract-snapshots for v4-next Re-runs the cargo-insta snapshot tests against the v4-next compiler and the v4-next aztec-nr / contract code, accepting the diffs: - compile_failure/authorization_selector_collision: one extra 'check_parent_traits_are_implemented: missing trait ID' diagnostic on v4-next's authorization.nr. - expand/avm_gadgets_test_contract: keccak_hash_300 doesn't exist on v4-next's avm_gadgets_test_contract. - expand/avm_test_contract: ordering / minor signature differences on v4-next's avm_test_contract. --- .../snapshots__stderr.snap | 14 ++- .../snapshots__expanded.snap | 88 +++--------------- .../snapshots__expanded.snap | 93 ++++++++++--------- 3 files changed, 73 insertions(+), 122 deletions(-) diff --git a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorization_selector_collision/snapshots__stderr.snap b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorization_selector_collision/snapshots__stderr.snap index de4879598429..bba93701b5e9 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorization_selector_collision/snapshots__stderr.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/compile_failure/authorization_selector_collision/snapshots__stderr.snap @@ -38,6 +38,18 @@ error: check_trait_impl_where_clause_matches_trait_where_clause: missing trait I │ ---------------- While running this function attribute │ +error: check_parent_traits_are_implemented: missing trait ID + ┌─ /noir-projects/aztec-nr/aztec/src/macros/authorization.nr:23:16 + │ +23 │ let name = s.name(); + │ -------- + │ + ┌─ src/main.nr:24:5 + │ +24 │ #[authorization] + │ ---------------- While running this function attribute + │ + error: check_trait_impl_method_matches_declaration: missing trait impl ┌─ /noir-projects/aztec-nr/aztec/src/macros/authorization.nr:42:16 │ @@ -64,4 +76,4 @@ error: Selector collision detected between authorizations 'EventCollision8370082 3: register_authorization at /noir-projects/aztec-nr/aztec/src/macros/authorization.nr:15:9 -Aborting due to 5 previous errors +Aborting due to 6 previous errors diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap index 2f36a53d539e..f8ce2bcdc47b 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_gadgets_test_contract/snapshots__expanded.snap @@ -2,6 +2,7 @@ source: tests/snapshots.rs expression: stdout --- + use aztec::macros::aztec; use aztec::macros::aztec; @@ -12,10 +13,6 @@ contract AvmGadgetsTest { #[contract_library_method] fn keccak_hash(data: [u8; 10]) -> [u8; 32]; - #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call keccak_hash_300. See https://docs.aztec.network/errors/6")] - #[contract_library_method] - fn keccak_hash_300(data: [u8; 300]) -> [u8; 32]; - #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call keccak_hash_1400. See https://docs.aztec.network/errors/6")] #[contract_library_method] fn keccak_hash_1400(data: [u8; 1400]) -> [u8; 32]; @@ -159,12 +156,6 @@ contract AvmGadgetsTest { Self { target_contract: aztec::protocol::address::AztecAddress::zero()} } - pub fn sha256_hash_1536(self, data: [u8; 1536]) -> aztec::context::calls::PublicCall<16, 1536, [u8; 32]> { - let serialized_params: [Field; 1536] = <[u8; 1536] as aztec::protocol::traits::Serialize>::serialize(data); - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(373006257_Field); - aztec::context::calls::PublicCall::<16, 1536, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_1536", serialized_params) - } - pub fn pedersen_hash_with_index(self, data: [Field; 10]) -> aztec::context::calls::PublicCall<24, 10, Field> { let serialized_params: [Field; 10] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3265405934_Field); @@ -297,10 +288,10 @@ contract AvmGadgetsTest { aztec::context::calls::PublicCall::<16, 1400, [u8; 32]>::new(self.target_contract, selector, "keccak_hash_1400", serialized_params) } - pub fn keccak_hash_300(self, data: [u8; 300]) -> aztec::context::calls::PublicCall<15, 300, [u8; 32]> { - let serialized_params: [Field; 300] = <[u8; 300] as aztec::protocol::traits::Serialize>::serialize(data); - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3065624740_Field); - aztec::context::calls::PublicCall::<15, 300, [u8; 32]>::new(self.target_contract, selector, "keccak_hash_300", serialized_params) + pub fn sha256_hash_1536(self, data: [u8; 1536]) -> aztec::context::calls::PublicCall<16, 1536, [u8; 32]> { + let serialized_params: [Field; 1536] = <[u8; 1536] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(373006257_Field); + aztec::context::calls::PublicCall::<16, 1536, [u8; 32]>::new(self.target_contract, selector, "sha256_hash_1536", serialized_params) } pub fn offchain_receive(self, messages: BoundedVec) -> aztec::context::calls::UtilityCall<16, 321, ()> { @@ -349,15 +340,6 @@ contract AvmGadgetsTest { } impl CallSelf { - pub fn sha256_hash_1536(self, data: [u8; 1536]) -> [u8; 32] { - let serialized_params: [Field; 1536 * 1] = <[u8; 1536] as aztec::protocol::traits::Serialize>::serialize(data); - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(373006257_Field); - // Safety: comment added by `nargo expand` - unsafe { - aztec::context::calls::PublicCall::<16, 1536 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_1536", serialized_params).call(self.context) - } - } - pub fn pedersen_hash_with_index(self, data: [Field; 10]) -> Field { let serialized_params: [Field; 10 * 1] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3265405934_Field); @@ -556,12 +538,12 @@ contract AvmGadgetsTest { } } - pub fn keccak_hash_300(self, data: [u8; 300]) -> [u8; 32] { - let serialized_params: [Field; 300 * 1] = <[u8; 300] as aztec::protocol::traits::Serialize>::serialize(data); - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3065624740_Field); + pub fn sha256_hash_1536(self, data: [u8; 1536]) -> [u8; 32] { + let serialized_params: [Field; 1536 * 1] = <[u8; 1536] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(373006257_Field); // Safety: comment added by `nargo expand` unsafe { - aztec::context::calls::PublicCall::<15, 300 * 1, [u8; 32]>::new(self.address, selector, "keccak_hash_300", serialized_params).call(self.context) + aztec::context::calls::PublicCall::<16, 1536 * 1, [u8; 32]>::new(self.address, selector, "sha256_hash_1536", serialized_params).call(self.context) } } } @@ -577,15 +559,6 @@ contract AvmGadgetsTest { } impl EnqueueSelf<&mut aztec::context::PrivateContext> { - pub fn sha256_hash_1536(self, data: [u8; 1536]) { - let serialized_params: [Field; 1536 * 1] = <[u8; 1536] as aztec::protocol::traits::Serialize>::serialize(data); - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(373006257_Field); - let calldata: [Field; 1 + (1536 * 1)] = [::to_field(selector)].concat(serialized_params); - let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); - aztec::oracle::execution_cache::store(calldata, calldata_hash); - self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); - } - pub fn pedersen_hash_with_index(self, data: [Field; 10]) { let serialized_params: [Field; 10 * 1] = <[Field; 10] as aztec::protocol::traits::Serialize>::serialize(data); let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3265405934_Field); @@ -784,10 +757,10 @@ contract AvmGadgetsTest { self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); } - pub fn keccak_hash_300(self, data: [u8; 300]) { - let serialized_params: [Field; 300 * 1] = <[u8; 300] as aztec::protocol::traits::Serialize>::serialize(data); - let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3065624740_Field); - let calldata: [Field; 1 + (300 * 1)] = [::to_field(selector)].concat(serialized_params); + pub fn sha256_hash_1536(self, data: [u8; 1536]) { + let serialized_params: [Field; 1536 * 1] = <[u8; 1536] as aztec::protocol::traits::Serialize>::serialize(data); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(373006257_Field); + let calldata: [Field; 1 + (1536 * 1)] = [::to_field(selector)].concat(serialized_params); let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); aztec::oracle::execution_cache::store(calldata, calldata_hash); self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); @@ -815,13 +788,6 @@ contract AvmGadgetsTest { let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__keccak_hash(arg0)); aztec::oracle::avm::avm_return(return_value.as_vector()); }; - if selector == 3065624740_Field { - let input_calldata: [Field; 300 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 300] as aztec::protocol::traits::Serialize>::N); - let mut reader: aztec::protocol::utils::reader::Reader<300 * 1> = aztec::protocol::utils::reader::Reader::<300 * 1>::new(input_calldata); - let arg0: [u8; 300] = <[u8; 300] as aztec::protocol::traits::Deserialize>::stream_deserialize(&mut reader); - let return_value: [Field; 32 * 1] = <[u8; 32] as aztec::protocol::traits::Serialize>::serialize(__aztec_nr_internals__keccak_hash_300(arg0)); - aztec::oracle::avm::avm_return(return_value.as_vector()); - }; if selector == 372001522_Field { let input_calldata: [Field; 1400 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 1400] as aztec::protocol::traits::Serialize>::N); let mut reader: aztec::protocol::utils::reader::Reader<1400 * 1> = aztec::protocol::utils::reader::Reader::<1400 * 1>::new(input_calldata); @@ -987,10 +953,6 @@ contract AvmGadgetsTest { pub data: [u8; 1400], } - pub struct keccak_hash_300_parameters { - pub data: [u8; 300], - } - pub struct keccak_hash_parameters { pub data: [u8; 10], } @@ -1087,12 +1049,6 @@ contract AvmGadgetsTest { return_type: [u8; 32], } - #[abi(functions)] - pub struct keccak_hash_300_abi { - parameters: keccak_hash_300_parameters, - return_type: [u8; 32], - } - #[abi(functions)] pub struct keccak_hash_abi { parameters: keccak_hash_parameters, @@ -1273,24 +1229,6 @@ contract AvmGadgetsTest { } } - unconstrained fn __aztec_nr_internals__keccak_hash_300(data: [u8; 300]) -> pub [u8; 32] { - let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { - let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { - let serialized_args: [Field; 300 * 1] = aztec::oracle::avm::calldata_copy(1_u32, <[u8; 300] as aztec::protocol::traits::Serialize>::N); - aztec::hash::hash_args(serialized_args) - }); - let storage: () = (); - let self_address: aztec::protocol::address::AztecAddress = context.this_address(); - let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; - let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; - let internal: CallInternal = CallInternal:: { context: context}; - aztec::contract_self::contract_self_public::ContractSelfPublic::<(), CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) - }; - { - keccak256::keccak256(data, data.len()) - } - } - unconstrained fn __aztec_nr_internals__pedersen_hash(data: [Field; 10]) -> pub Field { let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic<(), CallSelf, CallSelfStatic, CallInternal> = { let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap index 7b88b9531a0c..e01a624001a7 100644 --- a/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/avm_test_contract/snapshots__expanded.snap @@ -2,6 +2,7 @@ source: tests/snapshots.rs expression: stdout --- + use aztec::macros::aztec; use aztec::macros::aztec; @@ -1491,10 +1492,10 @@ pub contract AvmTest { aztec::context::calls::PublicCall::<41, 2, ()>::new(self.target_contract, selector, "create_different_nullifier_in_nested_call", serialized_params) } - pub fn call_fee_juice(self) -> aztec::context::calls::PublicCall<14, 0, ()> { - let serialized_params: [Field; 0] = []; - let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); - aztec::context::calls::PublicCall::<14, 0, ()>::new(self.target_contract, selector, "call_fee_juice", serialized_params) + pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> aztec::context::calls::PublicCall<26, 300, Field> { + let serialized_params: [Field; 300] = arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); + aztec::context::calls::PublicCall::<26, 300, Field>::new(self.target_contract, selector, "nested_call_large_calldata", serialized_params) } pub fn get_transaction_fee(self) -> aztec::context::calls::PublicCall<19, 0, Field> { @@ -1521,6 +1522,12 @@ pub contract AvmTest { aztec::context::calls::PublicStaticCall::<18, 0, u8>::new(self.target_contract, selector, "set_opcode_u8_view", serialized_params) } + pub fn call_fee_juice(self) -> aztec::context::calls::PublicCall<14, 0, ()> { + let serialized_params: [Field; 0] = []; + let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); + aztec::context::calls::PublicCall::<14, 0, ()>::new(self.target_contract, selector, "call_fee_juice", serialized_params) + } + pub fn assert_nullifier_exists(self, nullifier: Field) -> aztec::context::calls::PublicCall<23, 1, ()> { let serialized_params: [Field; 1] = nullifier.serialize(); let selector: FunctionSelector = FunctionSelector::from_field(2810255355_Field); @@ -1539,12 +1546,6 @@ pub contract AvmTest { aztec::context::calls::PublicCall::<13, 0, ()>::new(self.target_contract, selector, "debug_logging", serialized_params) } - pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> aztec::context::calls::PublicCall<26, 300, Field> { - let serialized_params: [Field; 300] = arr.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); - aztec::context::calls::PublicCall::<26, 300, Field>::new(self.target_contract, selector, "nested_call_large_calldata", serialized_params) - } - pub fn external_call_to_divide_by_zero_recovers(self) -> aztec::context::calls::PublicCall<40, 0, ()> { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(2245930342_Field); @@ -2497,15 +2498,6 @@ pub contract AvmTest { } } - pub fn new_nullifier(self, nullifier: Field) { - let serialized_params: [Field; 1] = nullifier.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); - // Safety: comment added by `nargo expand` - unsafe { - aztec::context::calls::PublicCall::<13, 1, ()>::new(self.address, selector, "new_nullifier", serialized_params).call(self.context) - } - } - pub fn divide_by_zero(self, denominator: u8) -> u8 { let serialized_params: [Field; 1] = denominator.serialize(); let selector: FunctionSelector = FunctionSelector::from_field(815932481_Field); @@ -2524,6 +2516,15 @@ pub contract AvmTest { } } + pub fn new_nullifier(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<13, 1, ()>::new(self.address, selector, "new_nullifier", serialized_params).call(self.context) + } + } + pub fn raw_l2_to_l1_msg(self, recipient: EthAddress, content: Field) { let mut serialized_params: [Field; 2] = [0_Field; 2]; let mut offset: u32 = 0_u32; @@ -2782,6 +2783,15 @@ pub contract AvmTest { } } + pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> Field { + let serialized_params: [Field; 300 * 1] = arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<26, 300 * 1, Field>::new(self.address, selector, "nested_call_large_calldata", serialized_params).call(self.context) + } + } + pub fn call_fee_juice(self) { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); @@ -2845,15 +2855,6 @@ pub contract AvmTest { } } - pub fn nested_call_large_calldata(self, arr: [Field; 300]) -> Field { - let serialized_params: [Field; 300 * 1] = arr.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); - // Safety: comment added by `nargo expand` - unsafe { - aztec::context::calls::PublicCall::<26, 300 * 1, Field>::new(self.address, selector, "nested_call_large_calldata", serialized_params).call(self.context) - } - } - pub fn external_call_to_divide_by_zero_recovers(self) { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(2245930342_Field); @@ -3870,15 +3871,6 @@ pub contract AvmTest { self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); } - pub fn new_nullifier(self, nullifier: Field) { - let serialized_params: [Field; 1] = nullifier.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); - let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); - let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); - aztec::oracle::execution_cache::store(calldata, calldata_hash); - self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); - } - pub fn divide_by_zero(self, denominator: u8) { let serialized_params: [Field; 1] = denominator.serialize(); let selector: FunctionSelector = FunctionSelector::from_field(815932481_Field); @@ -3897,6 +3889,15 @@ pub contract AvmTest { self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); } + pub fn new_nullifier(self, nullifier: Field) { + let serialized_params: [Field; 1] = nullifier.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(3648851082_Field); + let calldata: [Field; 1 + 1] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + pub fn raw_l2_to_l1_msg(self, recipient: EthAddress, content: Field) { let mut serialized_params: [Field; 2] = [0_Field; 2]; let mut offset: u32 = 0_u32; @@ -4155,6 +4156,15 @@ pub contract AvmTest { self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); } + pub fn nested_call_large_calldata(self, arr: [Field; 300]) { + let serialized_params: [Field; 300 * 1] = arr.serialize(); + let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); + let calldata: [Field; 1 + (300 * 1)] = [selector.to_field()].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + pub fn call_fee_juice(self) { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(2734888597_Field); @@ -4218,15 +4228,6 @@ pub contract AvmTest { self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); } - pub fn nested_call_large_calldata(self, arr: [Field; 300]) { - let serialized_params: [Field; 300 * 1] = arr.serialize(); - let selector: FunctionSelector = FunctionSelector::from_field(14812432_Field); - let calldata: [Field; 1 + (300 * 1)] = [selector.to_field()].concat(serialized_params); - let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); - aztec::oracle::execution_cache::store(calldata, calldata_hash); - self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); - } - pub fn external_call_to_divide_by_zero_recovers(self) { let serialized_params: [Field; 0] = []; let selector: FunctionSelector = FunctionSelector::from_field(2245930342_Field); From 64dcfcb9b6c1e1d892f6e7eb5657a2c245aa5900 Mon Sep 17 00:00:00 2001 From: Nicolas Chamo Date: Fri, 8 May 2026 16:05:35 -0300 Subject: [PATCH 27/30] feat(txe): allow authorizing cross-contract utility calls in nr tests (#23064) --- .../src/test/helpers/test_environment.nr | 134 +++++++++++++++--- .../aztec/src/test/helpers/txe_oracles.nr | 20 ++- .../test/nested_utility_contract/src/main.nr | 2 + .../test/nested_utility_contract/src/test.nr | 72 ++++++++++ yarn-project/pxe/src/hooks/execution_hooks.ts | 11 ++ yarn-project/pxe/src/hooks/index.ts | 1 + yarn-project/txe/src/oracle/interfaces.ts | 2 + .../oracle/txe_oracle_top_level_context.ts | 32 ++++- yarn-project/txe/src/rpc_translator.ts | 10 ++ 9 files changed, 256 insertions(+), 28 deletions(-) create mode 100644 noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/test.nr diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr index e4277f23ee7d..536001d926ff 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr @@ -132,21 +132,22 @@ struct UtilityContextOptions { /// ```noir /// env.call_private_opts(from, CallPrivateOptions::new().with_additional_scopes([other]), call); /// ``` -pub struct CallPrivateOptions { +pub struct CallPrivateOptions { additional_scopes: [AztecAddress; N], + authorized_utility_call_targets: [AztecAddress; T], } -impl CallPrivateOptions<0> { +impl CallPrivateOptions<0, 0> { /// Creates default `CallPrivateOptions`. /// /// The default values are the same as if using [`TestEnvironment::call_private`] instead of /// [`TestEnvironment::call_private_opts`]. pub fn new() -> Self { - CallPrivateOptions { additional_scopes: [] } + CallPrivateOptions { additional_scopes: [], authorized_utility_call_targets: [] } } } -impl CallPrivateOptions { +impl CallPrivateOptions { /// Grants access to secrets of additional accounts. /// /// By default only the secrets that belong to the `from` account can be accessed: this function lets contracts @@ -155,10 +156,27 @@ impl CallPrivateOptions { /// Example usage includes accounts withdrawing from an escrow, which may require accessing the escrow's own notes /// and secrets. pub fn with_additional_scopes( - _self: Self, + self, additional_scopes: [AztecAddress; N_2], - ) -> CallPrivateOptions { - CallPrivateOptions { additional_scopes } + ) -> CallPrivateOptions { + CallPrivateOptions { + additional_scopes, + authorized_utility_call_targets: self.authorized_utility_call_targets, + } + } + + /// Authorizes cross-contract utility calls to the given target contracts during this call. + /// + /// By default, cross-contract utility calls are denied. This method lets the test author specify which target + /// contracts are allowed to be called via utility functions during execution. + pub fn with_authorized_utility_call_targets( + self, + targets: [AztecAddress; T_2], + ) -> CallPrivateOptions { + CallPrivateOptions { + additional_scopes: self.additional_scopes, + authorized_utility_call_targets: targets, + } } } @@ -169,21 +187,22 @@ impl CallPrivateOptions { /// ```noir /// env.view_private_opts(from, ViewPrivateOptions::new().with_additional_scopes([other]), call); /// ``` -pub struct ViewPrivateOptions { +pub struct ViewPrivateOptions { additional_scopes: [AztecAddress; S], + authorized_utility_call_targets: [AztecAddress; T], } -impl ViewPrivateOptions<0> { +impl ViewPrivateOptions<0, 0> { /// Creates default `ViewPrivateOptions`. /// /// The default values are the same as if using [`TestEnvironment::view_private`] instead of /// [`TestEnvironment::view_private_opts`]. pub fn new() -> Self { - ViewPrivateOptions { additional_scopes: [] } + ViewPrivateOptions { additional_scopes: [], authorized_utility_call_targets: [] } } } -impl ViewPrivateOptions { +impl ViewPrivateOptions { /// Grants access to secrets of additional accounts. /// /// By default only the secrets that belong to the `from` account can be accessed: this function lets contracts @@ -192,10 +211,27 @@ impl ViewPrivateOptions { /// Example usage includes accounts querying an escrow's balance, which may require accessing the escrow's own /// notes. pub fn with_additional_scopes( - _self: Self, + self, additional_scopes: [AztecAddress; S2], - ) -> ViewPrivateOptions { - ViewPrivateOptions { additional_scopes } + ) -> ViewPrivateOptions { + ViewPrivateOptions { + additional_scopes, + authorized_utility_call_targets: self.authorized_utility_call_targets, + } + } + + /// Authorizes cross-contract utility calls to the given target contracts during this call. + /// + /// By default, cross-contract utility calls are denied. This method lets the test author specify which target + /// contracts are allowed to be called via utility functions during execution. + pub fn with_authorized_utility_call_targets( + self, + targets: [AztecAddress; T_2], + ) -> ViewPrivateOptions { + ViewPrivateOptions { + additional_scopes: self.additional_scopes, + authorized_utility_call_targets: targets, + } } } @@ -207,6 +243,40 @@ struct EventDiscoveryOptions { contract_address: Option, } +/// Configuration for [`TestEnvironment::execute_utility_opts`]. +/// +/// Constructed by calling [`ExecuteUtilityOptions::new`] and then chaining methods: +/// +/// ```noir +/// env.execute_utility_opts( +/// ExecuteUtilityOptions::new().with_authorized_utility_call_targets([target]), +/// SomeContract::at(addr).some_utility_function(), +/// ); +/// ``` +pub struct ExecuteUtilityOptions { + authorized_utility_call_targets: [AztecAddress; T], +} + +impl ExecuteUtilityOptions<0> { + /// Creates default `ExecuteUtilityOptions`. + pub fn new() -> Self { + ExecuteUtilityOptions { authorized_utility_call_targets: [] } + } +} + +impl ExecuteUtilityOptions { + /// Authorizes cross-contract utility calls to the given target contracts during this call. + /// + /// By default, cross-contract utility calls are denied. This method lets the test author specify which target + /// contracts are allowed to be called via utility functions during execution. + pub fn with_authorized_utility_call_targets( + _self: Self, + targets: [AztecAddress; T_2], + ) -> ExecuteUtilityOptions { + ExecuteUtilityOptions { authorized_utility_call_targets: targets } + } +} + /// Configuration values for [`TestEnvironment::deploy_opts`]. Meant to be used by calling `new` and then chaining /// methods setting each value, e.g.: /// ```noir @@ -629,10 +699,10 @@ impl TestEnvironment { } /// Variant of `call_private` which allows specifying multiple configuration values via `CallPrivateOptions`. - pub unconstrained fn call_private_opts( + pub unconstrained fn call_private_opts( _self: Self, from: AztecAddress, - opts: CallPrivateOptions, + opts: CallPrivateOptions, call: PrivateCall, ) -> T where @@ -646,6 +716,7 @@ impl TestEnvironment { hash_args(call.args), /*is_static=*/ false, opts.additional_scopes, + opts.authorized_utility_call_targets, ); T::deserialize(serialized_return_values) @@ -670,10 +741,10 @@ impl TestEnvironment { } /// Variant of `view_private` which allows specifying multiple configuration values via `ViewPrivateOptions`. - pub unconstrained fn view_private_opts( + pub unconstrained fn view_private_opts( _self: Self, from: AztecAddress, - opts: ViewPrivateOptions, + opts: ViewPrivateOptions, call: PrivateStaticCall, ) -> T where @@ -687,6 +758,7 @@ impl TestEnvironment { hash_args(call.args), /*is_static=*/ true, opts.additional_scopes, + opts.authorized_utility_call_targets, ); T::deserialize(serialized_return_values) @@ -701,12 +773,32 @@ impl TestEnvironment { /// let contract_addr = env.deploy("SampleContract").without_initializer(); /// let return_value = env.execute_utility(SampleContract::at(contract_addr).sample_utility_function()); /// ``` - pub unconstrained fn execute_utility(_self: Self, call: UtilityCall) -> T + pub unconstrained fn execute_utility( + self: Self, + call: UtilityCall, + ) -> T where T: Deserialize, { - let serialized_return_values = - txe_oracles::execute_utility_function(call.target_contract, call.selector, call.args); + self.execute_utility_opts(ExecuteUtilityOptions::new(), call) + } + + /// Variant of `execute_utility` which allows specifying configuration values via `ExecuteUtilityOptions`, such as + /// authorizing cross-contract utility calls. + pub unconstrained fn execute_utility_opts( + _self: Self, + opts: ExecuteUtilityOptions, + call: UtilityCall, + ) -> T + where + T: Deserialize, + { + let serialized_return_values = txe_oracles::execute_utility_function( + call.target_contract, + call.selector, + call.args, + opts.authorized_utility_call_targets, + ); T::deserialize(serialized_return_values) } diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr index 8ab6ecb42db4..ed82665af037 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr @@ -36,7 +36,7 @@ pub unconstrained fn deploy( ContractInstance::deserialize(instance_fields) } -pub unconstrained fn private_call_new_flow( +pub unconstrained fn private_call_new_flow( from: Option, contract_address: AztecAddress, function_selector: FunctionSelector, @@ -44,6 +44,7 @@ pub unconstrained fn private_call_new_flow( args_hash: Field, is_static_call: bool, additional_scopes: [AztecAddress; S], + authorized_utility_call_targets: [AztecAddress; T], ) -> [Field; N] { private_call_new_flow_oracle( from, @@ -53,6 +54,7 @@ pub unconstrained fn private_call_new_flow( args_hash, is_static_call, additional_scopes, + authorized_utility_call_targets, ) } @@ -68,12 +70,18 @@ pub unconstrained fn public_call_new_flow( public_call_new_flow_oracle(from, contract_address, calldata, is_static_call) } -pub unconstrained fn execute_utility_function( +pub unconstrained fn execute_utility_function( contract_address: AztecAddress, function_selector: FunctionSelector, args: [Field; M], + authorized_utility_call_targets: [AztecAddress; T], ) -> [Field; N] { - execute_utility_function_oracle(contract_address, function_selector, args) + execute_utility_function_oracle( + contract_address, + function_selector, + args, + authorized_utility_call_targets, + ) } #[oracle(aztec_txe_getNextBlockNumber)] @@ -209,7 +217,7 @@ pub unconstrained fn add_account(secret: Field) -> TestAccount {} pub unconstrained fn add_authwit(address: AztecAddress, message_hash: Field) {} #[oracle(aztec_txe_privateCallNewFlow)] -unconstrained fn private_call_new_flow_oracle( +unconstrained fn private_call_new_flow_oracle( _from: Option, _contract_address: AztecAddress, _function_selector: FunctionSelector, @@ -217,6 +225,7 @@ unconstrained fn private_call_new_flow_oracle [Field; N] {} #[oracle(aztec_txe_publicCallNewFlow)] @@ -228,10 +237,11 @@ unconstrained fn public_call_new_flow_oracle( ) -> [Field; N] {} #[oracle(aztec_txe_executeUtilityFunction)] -unconstrained fn execute_utility_function_oracle( +unconstrained fn execute_utility_function_oracle( contract_address: AztecAddress, function_selector: FunctionSelector, args: [Field; M], + authorized_utility_call_targets: [AztecAddress; T], ) -> [Field; N] {} #[oracle(aztec_txe_setTopLevelTXEContext)] diff --git a/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/main.nr index c5a5810d10de..01b6a503a800 100644 --- a/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/main.nr @@ -3,6 +3,8 @@ use aztec::macros::aztec; +mod test; + #[aztec] pub contract NestedUtility { use aztec::macros::functions::external; diff --git a/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/test.nr b/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/test.nr new file mode 100644 index 000000000000..51fe8fc5c221 --- /dev/null +++ b/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/test.nr @@ -0,0 +1,72 @@ +use crate::NestedUtility; +use aztec::{ + protocol::address::AztecAddress, + test::helpers::test_environment::{CallPrivateOptions, ExecuteUtilityOptions, TestEnvironment}, +}; + +unconstrained fn setup() -> (TestEnvironment, AztecAddress, AztecAddress, AztecAddress) { + let mut env = TestEnvironment::new(); + let account = env.create_light_account(); + let addr_a = env.deploy("NestedUtility").without_initializer(); + let addr_b = env.deploy("NestedUtility").without_initializer(); + (env, account, addr_a, addr_b) +} + +#[test] +unconstrained fn same_contract_utility_call_from_utility_succeeds() { + let (env, _, addr_a, _) = setup(); + + let result: Field = env.execute_utility(NestedUtility::at(addr_a).pow_utility(2, 10)); + assert_eq(result, 1024); +} + +#[test] +unconstrained fn same_contract_utility_call_from_private_succeeds() { + let (env, account, addr_a, _) = setup(); + + let result: Field = + env.call_private(account, NestedUtility::at(addr_a).pow_private(2, 10)); + assert_eq(result, 1024); +} + +#[test(should_fail_with = "Cross-contract utility call denied")] +unconstrained fn cross_contract_utility_call_from_utility_denied_by_default() { + let (env, _, addr_a, addr_b) = setup(); + + let _: Field = env.execute_utility( + NestedUtility::at(addr_a).delegate_pow_utility(addr_b, 2, 3), + ); +} + +#[test(should_fail_with = "Cross-contract utility call denied")] +unconstrained fn cross_contract_utility_call_from_private_denied_by_default() { + let (env, account, addr_a, addr_b) = setup(); + + let _: Field = env.call_private( + account, + NestedUtility::at(addr_a).delegate_pow_private(addr_b, 2, 3), + ); +} + +#[test] +unconstrained fn cross_contract_utility_call_from_utility_succeeds_with_authorization() { + let (env, _, addr_a, addr_b) = setup(); + + let result: Field = env.execute_utility_opts( + ExecuteUtilityOptions::new().with_authorized_utility_call_targets([addr_b]), + NestedUtility::at(addr_a).delegate_pow_utility(addr_b, 2, 3), + ); + assert_eq(result, 8); +} + +#[test] +unconstrained fn cross_contract_utility_call_from_private_succeeds_with_authorization() { + let (env, account, addr_a, addr_b) = setup(); + + let result: Field = env.call_private_opts( + account, + CallPrivateOptions::new().with_authorized_utility_call_targets([addr_b]), + NestedUtility::at(addr_a).delegate_pow_private(addr_b, 2, 3), + ); + assert_eq(result, 8); +} diff --git a/yarn-project/pxe/src/hooks/execution_hooks.ts b/yarn-project/pxe/src/hooks/execution_hooks.ts index e8ad86e762f2..7e4a3423f762 100644 --- a/yarn-project/pxe/src/hooks/execution_hooks.ts +++ b/yarn-project/pxe/src/hooks/execution_hooks.ts @@ -35,3 +35,14 @@ export interface ExecutionHooks { /** Called when a contract attempts a cross-contract utility call. */ authorizeUtilityCall: AuthorizeUtilityCall; } + +/** + * Builds an {@link ExecutionHooks} from individually-constructed hook callbacks. Returns `undefined` + * when every field is absent, so callers can unconditionally pass the result as `hooks`. + */ +export function composeHooks(partial: Partial): ExecutionHooks | undefined { + if (Object.values(partial).every(v => v === undefined)) { + return undefined; + } + return partial as ExecutionHooks; +} diff --git a/yarn-project/pxe/src/hooks/index.ts b/yarn-project/pxe/src/hooks/index.ts index 77be368eb7b8..b9ceb80c404e 100644 --- a/yarn-project/pxe/src/hooks/index.ts +++ b/yarn-project/pxe/src/hooks/index.ts @@ -4,3 +4,4 @@ export type { UtilityCallAuthorizationResponse, } from './authorize_utility_call.js'; export type { ExecutionHooks } from './execution_hooks.js'; +export { composeHooks } from './execution_hooks.js'; diff --git a/yarn-project/txe/src/oracle/interfaces.ts b/yarn-project/txe/src/oracle/interfaces.ts index 773e69d5a9df..7aaf8e94c95a 100644 --- a/yarn-project/txe/src/oracle/interfaces.ts +++ b/yarn-project/txe/src/oracle/interfaces.ts @@ -71,12 +71,14 @@ export interface ITxeExecutionOracle { isStaticCall: boolean, additionalScopes: AztecAddress[], jobId: string, + authorizedUtilityCallTargets: AztecAddress[], ): Promise<{ returnValues: Fr[]; offchainEffects: Fr[][] }>; executeUtilityFunction( targetContractAddress: AztecAddress, functionSelector: FunctionSelector, args: Fr[], jobId: string, + authorizedUtilityCallTargets: AztecAddress[], ): Promise; publicCallNewFlow( from: AztecAddress | undefined, diff --git a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts index b9d9e7b33890..68aa13c61e91 100644 --- a/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts +++ b/yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts @@ -15,12 +15,14 @@ import { CapsuleService, CapsuleStore, type ContractStore, + type ExecutionHooks, NoteStore, ORACLE_VERSION_MAJOR, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore, + composeHooks, enrichPublicSimulationError, } from '@aztec/pxe/server'; import { @@ -326,6 +328,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl isStaticCall: boolean = false, additionalScopes: AztecAddress[] = [], jobId: string, + authorizedUtilityCallTargets: AztecAddress[], ) { this.logger.verbose( `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`, @@ -410,6 +413,9 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl simulator, messageContextService: this.stateMachine.messageContextService, l2TipsStore: this.stateMachine.node, + hooks: composeHooks({ + authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('private', authorizedUtilityCallTargets), + }), }); // Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks. @@ -712,6 +718,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl functionSelector: FunctionSelector, args: Fr[], jobId: string, + authorizedUtilityCallTargets: AztecAddress[], ) { const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector); if (!artifact) { @@ -742,10 +749,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl returnTypes: [], }); - return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId); + return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId, authorizedUtilityCallTargets); } - private async executeUtilityCall(call: FunctionCall, scopes: AztecAddress[], jobId: string): Promise { + private async executeUtilityCall( + call: FunctionCall, + scopes: AztecAddress[], + jobId: string, + authorizedUtilityCallTargets: AztecAddress[] = [], + ): Promise { const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector); if (entryPointArtifact.functionType !== FunctionType.UTILITY) { throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`); @@ -779,6 +791,9 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl jobId, scopes, simulator, + hooks: composeHooks({ + authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets), + }), }); const acirExecutionResult = await simulator .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()) @@ -811,4 +826,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl const header = await this.stateMachine.node.getBlockHeader('latest'); return header ? header.globalVariables.blockNumber : BlockNumber.ZERO; } + + private buildAuthorizeUtilityCallHook( + callerContext: 'private' | 'utility', + authorizedTargets: AztecAddress[], + ): ExecutionHooks['authorizeUtilityCall'] | undefined { + if (authorizedTargets.length === 0) { + return undefined; + } + return req => + Promise.resolve({ + authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)), + }); + } } diff --git a/yarn-project/txe/src/rpc_translator.ts b/yarn-project/txe/src/rpc_translator.ts index 3498177cd2ab..581f1cd5ffa7 100644 --- a/yarn-project/txe/src/rpc_translator.ts +++ b/yarn-project/txe/src/rpc_translator.ts @@ -1352,6 +1352,7 @@ export class RPCTranslator { foreignArgsHash: ForeignCallSingle, foreignIsStaticCall: ForeignCallSingle, foreignAdditionalScopes: ForeignCallArray, + foreignAuthorizedUtilityCallTargets: ForeignCallArray, ) { const from = fromSingle(foreignFromIsSome).toBool() ? addressFromSingle(foreignFromValue) : undefined; const targetContractAddress = addressFromSingle(foreignTargetContractAddress); @@ -1360,6 +1361,9 @@ export class RPCTranslator { const argsHash = fromSingle(foreignArgsHash); const isStaticCall = fromSingle(foreignIsStaticCall).toBool(); const additionalScopes = fromArray(foreignAdditionalScopes).map(field => AztecAddress.fromField(field)); + const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field => + AztecAddress.fromField(field), + ); const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => { const { returnValues, offchainEffects } = await this.handlerAsTxe().privateCallNewFlow( @@ -1371,6 +1375,7 @@ export class RPCTranslator { isStaticCall, additionalScopes, this.stateHandler.getCurrentJob(), + authorizedUtilityCallTargets, ); // Private execution collects offchain effects inside PXE's PrivateExecutionOracle rather than @@ -1402,10 +1407,14 @@ export class RPCTranslator { foreignTargetContractAddress: ForeignCallSingle, foreignFunctionSelector: ForeignCallSingle, foreignArgs: ForeignCallArray, + foreignAuthorizedUtilityCallTargets: ForeignCallArray, ) { const targetContractAddress = addressFromSingle(foreignTargetContractAddress); const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector)); const args = fromArray(foreignArgs); + const authorizedUtilityCallTargets = fromArray(foreignAuthorizedUtilityCallTargets).map(field => + AztecAddress.fromField(field), + ); const returnValues = await this.stateHandler.withTopLevelCallTracking(async () => { const returnValues = await this.handlerAsTxe().executeUtilityFunction( @@ -1413,6 +1422,7 @@ export class RPCTranslator { functionSelector, args, this.stateHandler.getCurrentJob(), + authorizedUtilityCallTargets, ); // TODO(F-335): Avoid doing the following call here. From c391d687d3828a22bfd9e0da9db9b829afc1482b Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Fri, 8 May 2026 17:26:22 -0400 Subject: [PATCH 28/30] chore: bench public fns with emit repro (#23105) Adds a bench for the contract shape from https://github.com/AztecProtocol/aztec-nr/issues/35 (15 public fns each emitting an event). No existing bench target covers this flow. I want to see the benefits from follow-up improvements. --- noir-projects/contract-snapshots/build.rs | 4 + .../snapshots__expanded.snap | 1179 +++++++++++++++++ noir-projects/noir-contracts/Nargo.toml | 1 + .../Nargo.toml | 8 + .../src/main.nr | 118 ++ .../apps_tests/bench.test.ts | 27 + 6 files changed, 1337 insertions(+) create mode 100644 noir-projects/contract-snapshots/tests/snapshots/expand/public_fns_with_emit_repro_contract/snapshots__expanded.snap create mode 100644 noir-projects/noir-contracts/contracts/test/public_fns_with_emit_repro_contract/Nargo.toml create mode 100644 noir-projects/noir-contracts/contracts/test/public_fns_with_emit_repro_contract/src/main.nr diff --git a/noir-projects/contract-snapshots/build.rs b/noir-projects/contract-snapshots/build.rs index 22949c8a6e68..9987edfb8348 100644 --- a/noir-projects/contract-snapshots/build.rs +++ b/noir-projects/contract-snapshots/build.rs @@ -30,6 +30,10 @@ const EXPAND_CASES: &[(&str, &str)] = &[ "avm_gadgets_test_contract", "../noir-contracts/contracts/test/avm_gadgets_test_contract", ), + ( + "public_fns_with_emit_repro_contract", + "../noir-contracts/contracts/test/public_fns_with_emit_repro_contract", + ), ]; fn main() { diff --git a/noir-projects/contract-snapshots/tests/snapshots/expand/public_fns_with_emit_repro_contract/snapshots__expanded.snap b/noir-projects/contract-snapshots/tests/snapshots/expand/public_fns_with_emit_repro_contract/snapshots__expanded.snap new file mode 100644 index 000000000000..81841dad48de --- /dev/null +++ b/noir-projects/contract-snapshots/tests/snapshots/expand/public_fns_with_emit_repro_contract/snapshots__expanded.snap @@ -0,0 +1,1179 @@ +--- +source: tests/snapshots.rs +expression: stdout +--- + +use aztec::macros::aztec; +use aztec::macros::aztec; + +/// Bytecode-shape repro from https://github.com/AztecProtocol/aztec-nr/issues/35. +/// +/// 15 `#[external("public")]` functions, each doing one storage read, one storage write, +/// and one `self.emit(Updated { .. })`. Pinned here so that: +/// - `nargo expand` is snapshotted in `noir-projects/contract-snapshots`, making any +/// change to the macro boilerplate visible across all 15 call sites in a single review. +/// - `bytecodeSizeBytes/PublicFnsWithEmitRepro` lands on the bench dashboard, so any +/// improvement (or regression) in the per-public-fn emit shape is tracked over time. +pub contract PublicFnsWithEmitRepro { + use aztec::macros::events::event; + use aztec::macros::functions::external; + use aztec::macros::storage::storage; + use aztec::state_vars::PublicMutable; + + #[abi(events)] + struct Updated { + new_value: u64, + } + + impl aztec::event::event_interface::EventInterface for Updated { + fn get_event_type_id() -> aztec::event::EventSelector { + ::from_field(3505425495_Field) + } + } + + impl aztec::protocol::traits::Serialize for Updated { + let N: u32 = 1; + + fn serialize(self) -> [Field; 1] { + let mut writer: aztec::protocol::utils::writer::Writer<1> = aztec::protocol::utils::writer::Writer::<1>::new(); + ::stream_serialize(self, &mut writer); + writer.finish() + } + + #[inline_always] + fn stream_serialize(self, writer: &mut aztec::protocol::utils::writer::Writer) { + ::stream_serialize(self.new_value, writer); + } + } + + struct Storage { + value: PublicMutable, + } + + impl Storage { + fn init(context: Context) -> Self { + Self { value: as aztec::state_vars::StateVariable<1, Context>>::new(context, 1_Field)} + } + } + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_01. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_01(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_02. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_02(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_03. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_03(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_04. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_04(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_05. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_05(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_06. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_06(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_07. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_07(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_08. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_08(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_09. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_09(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_10. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_10(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_11. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_11(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_12. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_12(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_13. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_13(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_14. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_14(v: u64); + + #[deprecated(deny, "Direct invocation of public functions is not supported. You attempted to call fn_15. See https://docs.aztec.network/errors/6")] + #[contract_library_method] + fn fn_15(v: u64); + + #[abi(storage)] + pub global STORAGE_LAYOUT_PublicFnsWithEmitRepro: StorageLayout<22> = StorageLayout::<22> { + contract_name: "PublicFnsWithEmitRepro", + fields: StorageLayoutFields { + value: aztec::state_vars::Storable { + slot: 0x01, + }, + }, + }; + + /// Unpacks an array into a note corresponding to `note_type_id` and then computes its note hash (non-siloed) and inner nullifier (non-siloed) assuming the note has been inserted into the note hash tree with `note_nonce`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + #[allow(dead_code)] + unconstrained fn _compute_note_hash_and_nullifier(packed_note: BoundedVec, owner: aztec::protocol::address::AztecAddress, storage_slot: Field, note_type_id: Field, contract_address: aztec::protocol::address::AztecAddress, randomness: Field, note_nonce: Field) -> Option { + _compute_note_hash(packed_note, owner, storage_slot, note_type_id, contract_address, randomness).map(|note_hash: Field| -> aztec::messages::discovery::NoteHashAndNullifier { + let siloed_note_hash: Field = aztec::protocol::hash::compute_siloed_note_hash(contract_address, note_hash); + let unique_note_hash: Field = aztec::protocol::hash::compute_unique_note_hash(note_nonce, siloed_note_hash); + let inner_nullifier: Option = _compute_note_nullifier(unique_note_hash, packed_note, owner, storage_slot, note_type_id, contract_address, randomness); + aztec::messages::discovery::NoteHashAndNullifier { note_hash: note_hash, inner_nullifier: inner_nullifier} + }) + } + + /// This contract does not use private notes, so this function should never be called as it will unconditionally fail. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_hash(_packed_note: BoundedVec, _owner: aztec::protocol::address::AztecAddress, _storage_slot: Field, _note_type_id: Field, _contract_address: aztec::protocol::address::AztecAddress, _randomness: Field) -> Option { + panic(f"This contract does not use private notes") + } + + /// This contract does not use private notes, so this function should never be called as it will unconditionally fail. + /// + /// This function is automatically injected by the `#[aztec]` macro. + #[contract_library_method] + unconstrained fn _compute_note_nullifier(_unique_note_hash: Field, _packed_note: BoundedVec, _owner: aztec::protocol::address::AztecAddress, _storage_slot: Field, _note_type_id: Field, _contract_address: aztec::protocol::address::AztecAddress, _randomness: Field) -> Option { + panic(f"This contract does not use private notes") + } + + /// Receives offchain messages into this contract's offchain inbox for subsequent processing. + /// + /// Each message is routed to the inbox scoped to its `recipient` field. + /// + /// For more details, see `aztec::messages::processing::offchain::receive`. + /// + /// This function is automatically injected by the `#[aztec]` macro. + unconstrained fn offchain_receive(messages: BoundedVec) { + let address: aztec::protocol::address::AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::processing::offchain::receive(address, messages); + } + + pub struct PublicFnsWithEmitRepro { + pub target_contract: aztec::protocol::address::AztecAddress, + } + + impl PublicFnsWithEmitRepro { + pub fn storage_layout() -> StorageLayoutFields { + STORAGE_LAYOUT_PublicFnsWithEmitRepro.fields + } + + pub fn at(addr: aztec::protocol::address::AztecAddress) -> Self { + Self { target_contract: addr} + } + + pub fn interface() -> Self { + Self { target_contract: aztec::protocol::address::AztecAddress::zero()} + } + + pub fn fn_05(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1024449064_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_05", serialized_params) + } + + pub fn fn_07(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3759335427_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_07", serialized_params) + } + + pub fn fn_14(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1096580269_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_14", serialized_params) + } + + pub fn fn_06(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4182861060_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_06", serialized_params) + } + + pub fn fn_02(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3685080997_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_02", serialized_params) + } + + pub fn fn_01(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1472103964_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_01", serialized_params) + } + + pub fn fn_04(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1049101134_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_04", serialized_params) + } + + pub fn fn_08(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4192827894_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_08", serialized_params) + } + + pub fn fn_11(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3056031378_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_11", serialized_params) + } + + pub fn fn_13(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2026372669_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_13", serialized_params) + } + + pub fn fn_03(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2154571552_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_03", serialized_params) + } + + pub fn fn_10(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2644440885_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_10", serialized_params) + } + + pub fn fn_12(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2749762129_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_12", serialized_params) + } + + pub fn fn_15(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(986670843_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_15", serialized_params) + } + + pub fn fn_09(self, v: u64) -> aztec::context::calls::PublicCall<5, 1, ()> { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1901877638_Field); + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.target_contract, selector, "fn_09", serialized_params) + } + + pub fn offchain_receive(self, messages: BoundedVec) -> aztec::context::calls::UtilityCall<16, 321, ()> { + let serialized_params: [Field; 321] = as aztec::protocol::traits::Serialize>::serialize(messages); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1396850735_Field); + aztec::context::calls::UtilityCall::<16, 321, ()>::new(self.target_contract, selector, "offchain_receive", serialized_params) + } + } + + #[contract_library_method] + pub fn storage_layout() -> StorageLayoutFields { + STORAGE_LAYOUT_PublicFnsWithEmitRepro.fields + } + + #[contract_library_method] + pub fn at(addr: aztec::protocol::address::AztecAddress) -> PublicFnsWithEmitRepro { + PublicFnsWithEmitRepro { target_contract: addr} + } + + #[contract_library_method] + pub fn interface() -> PublicFnsWithEmitRepro { + PublicFnsWithEmitRepro { target_contract: aztec::protocol::address::AztecAddress::zero()} + } + + pub struct sync_state_parameters { + pub scope: aztec::protocol::address::AztecAddress, + } + + #[abi(functions)] + pub struct sync_state_abi { + parameters: sync_state_parameters, + } + + unconstrained fn sync_state(scope: aztec::protocol::address::AztecAddress) { + let address: aztec::protocol::address::AztecAddress = aztec::context::UtilityContext::new().this_address(); + aztec::messages::discovery::do_sync_state(address, _compute_note_hash, _compute_note_nullifier, Option::>::none(), Option:: aztec::ephemeral::EphemeralArray>::some(aztec::messages::processing::offchain::sync_inbox), scope); + } + + pub struct offchain_receive_parameters { + pub messages: BoundedVec, + } + + #[abi(functions)] + pub struct offchain_receive_abi { + parameters: offchain_receive_parameters, + } + + pub struct CallSelf { + pub address: aztec::protocol::address::AztecAddress, + pub context: Context, + } + + impl CallSelf { + pub fn fn_05(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1024449064_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_05", serialized_params).call(self.context) + } + } + + pub fn fn_07(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3759335427_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_07", serialized_params).call(self.context) + } + } + + pub fn fn_14(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1096580269_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_14", serialized_params).call(self.context) + } + } + + pub fn fn_06(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4182861060_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_06", serialized_params).call(self.context) + } + } + + pub fn fn_02(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3685080997_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_02", serialized_params).call(self.context) + } + } + + pub fn fn_01(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1472103964_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_01", serialized_params).call(self.context) + } + } + + pub fn fn_04(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1049101134_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_04", serialized_params).call(self.context) + } + } + + pub fn fn_08(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4192827894_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_08", serialized_params).call(self.context) + } + } + + pub fn fn_11(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3056031378_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_11", serialized_params).call(self.context) + } + } + + pub fn fn_13(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2026372669_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_13", serialized_params).call(self.context) + } + } + + pub fn fn_03(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2154571552_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_03", serialized_params).call(self.context) + } + } + + pub fn fn_10(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2644440885_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_10", serialized_params).call(self.context) + } + } + + pub fn fn_12(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2749762129_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_12", serialized_params).call(self.context) + } + } + + pub fn fn_15(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(986670843_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_15", serialized_params).call(self.context) + } + } + + pub fn fn_09(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1901877638_Field); + // Safety: comment added by `nargo expand` + unsafe { + aztec::context::calls::PublicCall::<5, 1, ()>::new(self.address, selector, "fn_09", serialized_params).call(self.context) + } + } + } + + pub struct CallSelfStatic { + pub address: aztec::protocol::address::AztecAddress, + pub context: Context, + } + + pub struct EnqueueSelf { + pub address: aztec::protocol::address::AztecAddress, + pub context: Context, + } + + impl EnqueueSelf<&mut aztec::context::PrivateContext> { + pub fn fn_05(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1024449064_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_07(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3759335427_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_14(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1096580269_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_06(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4182861060_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_02(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3685080997_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_01(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1472103964_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_04(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1049101134_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_08(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(4192827894_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_11(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(3056031378_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_13(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2026372669_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_03(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2154571552_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_10(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2644440885_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_12(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(2749762129_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_15(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(986670843_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + + pub fn fn_09(self, v: u64) { + let serialized_params: [Field; 1] = ::serialize(v); + let selector: aztec::protocol::abis::function_selector::FunctionSelector = ::from_field(1901877638_Field); + let calldata: [Field; 1 + 1] = [::to_field(selector)].concat(serialized_params); + let calldata_hash: Field = aztec::hash::hash_calldata_array(calldata); + aztec::oracle::execution_cache::store(calldata, calldata_hash); + self.context.call_public_function_with_calldata_hash(self.address, calldata_hash, false, false); + } + } + + pub struct EnqueueSelfStatic { + pub address: aztec::protocol::address::AztecAddress, + pub context: Context, + } + + pub struct CallSelfUtility { + pub address: aztec::protocol::address::AztecAddress, + } + + pub struct CallInternal { + pub context: Context, + } + + pub unconstrained fn public_dispatch(selector: Field) { + if selector == 1472103964_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_01(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3685080997_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_02(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2154571552_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_03(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1049101134_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_04(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1024449064_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_05(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 4182861060_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_06(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3759335427_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_07(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 4192827894_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_08(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1901877638_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_09(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2644440885_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_10(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 3056031378_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_11(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2749762129_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_12(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 2026372669_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_13(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 1096580269_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_14(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + if selector == 986670843_Field { + let input_calldata: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + let mut reader: aztec::protocol::utils::reader::Reader<1> = aztec::protocol::utils::reader::Reader::<1>::new(input_calldata); + let arg0: u64 = ::stream_deserialize(&mut reader); + __aztec_nr_internals__fn_15(arg0); + aztec::oracle::avm::avm_return([].as_slice()); + }; + panic(f"Unknown selector {selector}") + } + + pub struct fn_01_parameters { + pub v: u64, + } + + pub struct fn_02_parameters { + pub v: u64, + } + + pub struct fn_03_parameters { + pub v: u64, + } + + pub struct fn_04_parameters { + pub v: u64, + } + + pub struct fn_05_parameters { + pub v: u64, + } + + pub struct fn_06_parameters { + pub v: u64, + } + + pub struct fn_07_parameters { + pub v: u64, + } + + pub struct fn_08_parameters { + pub v: u64, + } + + pub struct fn_09_parameters { + pub v: u64, + } + + pub struct fn_10_parameters { + pub v: u64, + } + + pub struct fn_11_parameters { + pub v: u64, + } + + pub struct fn_12_parameters { + pub v: u64, + } + + pub struct fn_13_parameters { + pub v: u64, + } + + pub struct fn_14_parameters { + pub v: u64, + } + + pub struct fn_15_parameters { + pub v: u64, + } + + #[abi(functions)] + pub struct fn_01_abi { + parameters: fn_01_parameters, + } + + #[abi(functions)] + pub struct fn_02_abi { + parameters: fn_02_parameters, + } + + #[abi(functions)] + pub struct fn_03_abi { + parameters: fn_03_parameters, + } + + #[abi(functions)] + pub struct fn_04_abi { + parameters: fn_04_parameters, + } + + #[abi(functions)] + pub struct fn_05_abi { + parameters: fn_05_parameters, + } + + #[abi(functions)] + pub struct fn_06_abi { + parameters: fn_06_parameters, + } + + #[abi(functions)] + pub struct fn_07_abi { + parameters: fn_07_parameters, + } + + #[abi(functions)] + pub struct fn_08_abi { + parameters: fn_08_parameters, + } + + #[abi(functions)] + pub struct fn_09_abi { + parameters: fn_09_parameters, + } + + #[abi(functions)] + pub struct fn_10_abi { + parameters: fn_10_parameters, + } + + #[abi(functions)] + pub struct fn_11_abi { + parameters: fn_11_parameters, + } + + #[abi(functions)] + pub struct fn_12_abi { + parameters: fn_12_parameters, + } + + #[abi(functions)] + pub struct fn_13_abi { + parameters: fn_13_parameters, + } + + #[abi(functions)] + pub struct fn_14_abi { + parameters: fn_14_parameters, + } + + #[abi(functions)] + pub struct fn_15_abi { + parameters: fn_15_parameters, + } + + unconstrained fn __aztec_nr_internals__fn_01(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 1_u64); + self.emit(Updated { new_value: (old + v) + 1_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_02(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 2_u64); + self.emit(Updated { new_value: (old + v) + 2_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_03(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 3_u64); + self.emit(Updated { new_value: (old + v) + 3_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_04(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 4_u64); + self.emit(Updated { new_value: (old + v) + 4_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_05(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 5_u64); + self.emit(Updated { new_value: (old + v) + 5_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_06(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 6_u64); + self.emit(Updated { new_value: (old + v) + 6_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_07(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 7_u64); + self.emit(Updated { new_value: (old + v) + 7_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_08(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 8_u64); + self.emit(Updated { new_value: (old + v) + 8_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_09(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 9_u64); + self.emit(Updated { new_value: (old + v) + 9_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_10(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 10_u64); + self.emit(Updated { new_value: (old + v) + 10_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_11(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 11_u64); + self.emit(Updated { new_value: (old + v) + 11_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_12(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 12_u64); + self.emit(Updated { new_value: (old + v) + 12_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_13(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 13_u64); + self.emit(Updated { new_value: (old + v) + 13_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_14(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 14_u64); + self.emit(Updated { new_value: (old + v) + 14_u64}); + } + } + + unconstrained fn __aztec_nr_internals__fn_15(v: u64) { + let mut self: aztec::contract_self::contract_self_public::ContractSelfPublic, CallSelf, CallSelfStatic, CallInternal> = { + let context: aztec::context::PublicContext = aztec::context::PublicContext::new(|| -> Field { + let serialized_args: [Field; 1] = aztec::oracle::avm::calldata_copy(1_u32, ::N); + aztec::hash::hash_args(serialized_args) + }); + let storage: Storage = Storage::::init(context); + let self_address: aztec::protocol::address::AztecAddress = context.this_address(); + let call_self: CallSelf = CallSelf:: { address: self_address, context: context}; + let call_self_static: CallSelfStatic = CallSelfStatic:: { address: self_address, context: context}; + let internal: CallInternal = CallInternal:: { context: context}; + aztec::contract_self::contract_self_public::ContractSelfPublic::, CallSelf, CallSelfStatic, CallInternal>::new(context, storage, call_self, call_self_static, internal) + }; + { + let old: u64 = self.storage.value.read(); + self.storage.value.write((old + v) + 15_u64); + self.emit(Updated { new_value: (old + v) + 15_u64}); + } + } + + pub struct StorageLayoutFields { + pub value: aztec::state_vars::Storable, + } + + pub struct StorageLayout { + pub contract_name: str, + pub fields: StorageLayoutFields, + } +} + +// Warning: the generated code has syntax errors diff --git a/noir-projects/noir-contracts/Nargo.toml b/noir-projects/noir-contracts/Nargo.toml index 218e7469ef6c..2e44a5d00b70 100644 --- a/noir-projects/noir-contracts/Nargo.toml +++ b/noir-projects/noir-contracts/Nargo.toml @@ -66,6 +66,7 @@ members = [ "contracts/test/parent_contract", "contracts/test/pending_note_hashes_contract", "contracts/test/private_init_test_contract", + "contracts/test/public_fns_with_emit_repro_contract", "contracts/test/public_immutable_contract", "contracts/test/returning_tuple_contract", "contracts/test/scope_test_contract", diff --git a/noir-projects/noir-contracts/contracts/test/public_fns_with_emit_repro_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/test/public_fns_with_emit_repro_contract/Nargo.toml new file mode 100644 index 000000000000..fdcd2ae8132b --- /dev/null +++ b/noir-projects/noir-contracts/contracts/test/public_fns_with_emit_repro_contract/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "public_fns_with_emit_repro_contract" +authors = [""] +compiler_version = ">=0.25.0" +type = "contract" + +[dependencies] +aztec = { path = "../../../../aztec-nr/aztec" } diff --git a/noir-projects/noir-contracts/contracts/test/public_fns_with_emit_repro_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/public_fns_with_emit_repro_contract/src/main.nr new file mode 100644 index 000000000000..6849d4b8aafa --- /dev/null +++ b/noir-projects/noir-contracts/contracts/test/public_fns_with_emit_repro_contract/src/main.nr @@ -0,0 +1,118 @@ +use aztec::macros::aztec; + +/// Bytecode-shape repro from https://github.com/AztecProtocol/aztec-nr/issues/35. +/// +/// 15 `#[external("public")]` functions, each doing one storage read, one storage write, +/// and one `self.emit(Updated { .. })`. Pinned here so that: +/// - `nargo expand` is snapshotted in `noir-projects/contract-snapshots`, making any +/// change to the macro boilerplate visible across all 15 call sites in a single review. +/// - `bytecodeSizeBytes/PublicFnsWithEmitRepro` lands on the bench dashboard, so any +/// improvement (or regression) in the per-public-fn emit shape is tracked over time. +#[aztec] +pub contract PublicFnsWithEmitRepro { + use aztec::macros::events::event; + use aztec::macros::functions::external; + use aztec::macros::storage::storage; + use aztec::state_vars::PublicMutable; + + #[event] + struct Updated { + new_value: u64, + } + + #[storage] + struct Storage { + value: PublicMutable, + } + + #[external("public")] + fn fn_01(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 1); + self.emit(Updated { new_value: old + v + 1 }); + } + #[external("public")] + fn fn_02(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 2); + self.emit(Updated { new_value: old + v + 2 }); + } + #[external("public")] + fn fn_03(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 3); + self.emit(Updated { new_value: old + v + 3 }); + } + #[external("public")] + fn fn_04(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 4); + self.emit(Updated { new_value: old + v + 4 }); + } + #[external("public")] + fn fn_05(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 5); + self.emit(Updated { new_value: old + v + 5 }); + } + #[external("public")] + fn fn_06(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 6); + self.emit(Updated { new_value: old + v + 6 }); + } + #[external("public")] + fn fn_07(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 7); + self.emit(Updated { new_value: old + v + 7 }); + } + #[external("public")] + fn fn_08(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 8); + self.emit(Updated { new_value: old + v + 8 }); + } + #[external("public")] + fn fn_09(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 9); + self.emit(Updated { new_value: old + v + 9 }); + } + #[external("public")] + fn fn_10(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 10); + self.emit(Updated { new_value: old + v + 10 }); + } + #[external("public")] + fn fn_11(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 11); + self.emit(Updated { new_value: old + v + 11 }); + } + #[external("public")] + fn fn_12(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 12); + self.emit(Updated { new_value: old + v + 12 }); + } + #[external("public")] + fn fn_13(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 13); + self.emit(Updated { new_value: old + v + 13 }); + } + #[external("public")] + fn fn_14(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 14); + self.emit(Updated { new_value: old + v + 14 }); + } + #[external("public")] + fn fn_15(v: u64) { + let old = self.storage.value.read(); + self.storage.value.write(old + v + 15); + self.emit(Updated { new_value: old + v + 15 }); + } +} diff --git a/yarn-project/simulator/src/public/public_tx_simulator/apps_tests/bench.test.ts b/yarn-project/simulator/src/public/public_tx_simulator/apps_tests/bench.test.ts index 50ffe0f8cebe..dd3fd8d1ddce 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator/apps_tests/bench.test.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator/apps_tests/bench.test.ts @@ -5,6 +5,7 @@ import { AMMContractArtifact } from '@aztec/noir-contracts.js/AMM'; import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token'; import { AvmGadgetsTestContractArtifact } from '@aztec/noir-test-contracts.js/AvmGadgetsTest'; import { AvmTestContractArtifact } from '@aztec/noir-test-contracts.js/AvmTest'; +import { PublicFnsWithEmitReproContractArtifact } from '@aztec/noir-test-contracts.js/PublicFnsWithEmitRepro'; import { StorageProofTestContractArtifact } from '@aztec/noir-test-contracts.js/StorageProofTest'; import { PublicSimulatorConfig } from '@aztec/stdlib/avm'; import { AztecAddress } from '@aztec/stdlib/aztec-address'; @@ -136,6 +137,32 @@ describe('Public TX simulator apps tests: benchmarks', () => { expect(result.revertCode.isOK()).toBe(true); }); + it('PublicFnsWithEmitRepro contract test', async () => { + // See comments on the contract source for motivation as to including this contract in our benchmarks. + tester.setMetricsPrefix(`${metricsPrefixPrefix}PublicFnsWithEmitRepro contract tests`); + const deployer = AztecAddress.fromNumber(42); + + const reproContract = await tester.registerAndDeployContract( + /*constructorArgs=*/ [], + deployer, + /*contractArtifact=*/ PublicFnsWithEmitReproContractArtifact, + ); + + const result = await tester.executeTxWithLabel( + /*txLabel=*/ 'PublicFnsWithEmitRepro/fn_01', + /*sender=*/ deployer, + /*setupCalls=*/ [], + /*appCalls=*/ [ + { + address: reproContract.address, + fnName: 'fn_01', + args: [/*v=*/ 1n], + }, + ], + ); + expect(result.revertCode.isOK()).toBe(true); + }); + it('Storage proof test', async () => { tester.setMetricsPrefix(`${metricsPrefixPrefix}StorageProof contract tests`); const deployer = AztecAddress.fromNumber(42); From aeed6b60d92d4ff3a3137e78b28a928902aba7b0 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 21:41:11 +0000 Subject: [PATCH 29/30] fix: nargo fmt for backported nested_utility tests --- .../test/nested_utility_contract/src/test.nr | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/test.nr b/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/test.nr index 51fe8fc5c221..a68f26539e2e 100644 --- a/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/test.nr +++ b/noir-projects/noir-contracts/contracts/test/nested_utility_contract/src/test.nr @@ -24,8 +24,7 @@ unconstrained fn same_contract_utility_call_from_utility_succeeds() { unconstrained fn same_contract_utility_call_from_private_succeeds() { let (env, account, addr_a, _) = setup(); - let result: Field = - env.call_private(account, NestedUtility::at(addr_a).pow_private(2, 10)); + let result: Field = env.call_private(account, NestedUtility::at(addr_a).pow_private(2, 10)); assert_eq(result, 1024); } @@ -33,19 +32,14 @@ unconstrained fn same_contract_utility_call_from_private_succeeds() { unconstrained fn cross_contract_utility_call_from_utility_denied_by_default() { let (env, _, addr_a, addr_b) = setup(); - let _: Field = env.execute_utility( - NestedUtility::at(addr_a).delegate_pow_utility(addr_b, 2, 3), - ); + let _: Field = env.execute_utility(NestedUtility::at(addr_a).delegate_pow_utility(addr_b, 2, 3)); } #[test(should_fail_with = "Cross-contract utility call denied")] unconstrained fn cross_contract_utility_call_from_private_denied_by_default() { let (env, account, addr_a, addr_b) = setup(); - let _: Field = env.call_private( - account, - NestedUtility::at(addr_a).delegate_pow_private(addr_b, 2, 3), - ); + let _: Field = env.call_private(account, NestedUtility::at(addr_a).delegate_pow_private(addr_b, 2, 3)); } #[test] From 5a1a2a175e04ae9dc3cde54c786a791c7a72964c Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 8 May 2026 21:51:57 +0000 Subject: [PATCH 30/30] update PR #23117 --- .../src/test/helpers/test_environment.nr | 25 ++++--------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr index 536001d926ff..e7f35472a3d1 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr @@ -159,10 +159,7 @@ impl CallPrivateOptions { self, additional_scopes: [AztecAddress; N_2], ) -> CallPrivateOptions { - CallPrivateOptions { - additional_scopes, - authorized_utility_call_targets: self.authorized_utility_call_targets, - } + CallPrivateOptions { additional_scopes, authorized_utility_call_targets: self.authorized_utility_call_targets } } /// Authorizes cross-contract utility calls to the given target contracts during this call. @@ -173,10 +170,7 @@ impl CallPrivateOptions { self, targets: [AztecAddress; T_2], ) -> CallPrivateOptions { - CallPrivateOptions { - additional_scopes: self.additional_scopes, - authorized_utility_call_targets: targets, - } + CallPrivateOptions { additional_scopes: self.additional_scopes, authorized_utility_call_targets: targets } } } @@ -214,10 +208,7 @@ impl ViewPrivateOptions { self, additional_scopes: [AztecAddress; S2], ) -> ViewPrivateOptions { - ViewPrivateOptions { - additional_scopes, - authorized_utility_call_targets: self.authorized_utility_call_targets, - } + ViewPrivateOptions { additional_scopes, authorized_utility_call_targets: self.authorized_utility_call_targets } } /// Authorizes cross-contract utility calls to the given target contracts during this call. @@ -228,10 +219,7 @@ impl ViewPrivateOptions { self, targets: [AztecAddress; T_2], ) -> ViewPrivateOptions { - ViewPrivateOptions { - additional_scopes: self.additional_scopes, - authorized_utility_call_targets: targets, - } + ViewPrivateOptions { additional_scopes: self.additional_scopes, authorized_utility_call_targets: targets } } } @@ -773,10 +761,7 @@ impl TestEnvironment { /// let contract_addr = env.deploy("SampleContract").without_initializer(); /// let return_value = env.execute_utility(SampleContract::at(contract_addr).sample_utility_function()); /// ``` - pub unconstrained fn execute_utility( - self: Self, - call: UtilityCall, - ) -> T + pub unconstrained fn execute_utility(self: Self, call: UtilityCall) -> T where T: Deserialize, {